Implementing database search - c#

I use mysql as database where I store my data.
I have a windows form with textboxes radiobuttons, comboboxes and more; where people give personal information about themselves like (first name, last name, sex, date birthday, phone, father name and more like this). (40 fields total)
I want to do a search button. With this button I want to fill some fields and after I push the search button a new window be opened containing all people with same personal information. I achieved to do a search button for one field (for example searching only by name).
But I have a problem when I select to search with more than one fields. For example I select to search all people who have name:Chris, Nickname:Dung, sex:Male, Birth_Country:UK and other but when I push search it gives back a window with irrelevant with the search data. Can someone help me with that?
The code I made for the search button after changes is:
public MySqlDataAdapter da;
public DataSet ds;
public string sTable = "data";
private void anazitisi_button_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
try
{
conn = openconnectio.GetConn();
string radiob = null;
if (radioButton1.Checked == true)
{
radiob = radioButton1.Text;
}
else if(radioButton2.Checked == true)
{
radiob = radioButton2.Text;
}
StringBuilder Query = new StringBuilder("SELECT * FROM data d INNER JOIN country c ON d.id_data = c.id_country WHERE 1=1 ");
if (!String.IsNullOrEmpty(textBox1.Text))
Query.Append(" AND name like '" + textBox1.Text + "'");
if (!String.IsNullOrEmpty(textBox2.Text))
Query.Append(" AND lastname like '" + textBox2.Text + "'");
if (!String.IsNullOrEmpty(radiob))
Query.Append(" AND sex like '" + radiob + "'");
if (!String.IsNullOrEmpty(maskedTextBox1.Text))
Query.Append(" AND birthdate like '" + maskedTextBox1.Text + "'");
if (!String.IsNullOrEmpty(maskedTextBox2.Text))
Query.Append(" AND phone_number like '" + maskedTextBox2.Text + "'");
MySqlDataAdapter da = new MySqlDataAdapter(Query.ToString(), conn);
ds = new DataSet();
da.Fill(ds, sTable);
conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
DataGridView dg1 = new DataGridView();
form2.Controls.Add(dg1);
dg1.Dock = DockStyle.Fill;
dg1.Refresh();
dg1.DataSource = ds;
dg1.DataMember = sTable;
form2.Show();
if (conn != null)
{
conn.Close();
}
}
}
My results after search is fine when i comment that code:
(birthdate code) and i dont used as search of course.
//if (!String.IsNullOrEmpty(maskedTextBox1.Text))
// Query.Append(" AND birthdate like '" + maskedTextBox1.Text + "'");
But when i use the (birthdate code) i get us result only a blank row.
I think because the birthdate maskedTextbox have a mask: 00/00/0000
Any suggestion?
Thanks.

I think you should consider three things
1- You may replace OR with And in your query
I mean instead of using
da = new MySqlDataAdapter(
"SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE name like '" + textBox1.Text +
"'OR lastname like '" + textBox2.Text +
"'OR sex like '" + radiob +
"'OR birthdate like '" + maskedTextBox1.Text +
"'OR phone
_number like '" + maskedTextBox2.Text + "' ;", conn);
You may use
da = new MySqlDataAdapter(
"SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE name like '" + textBox1.Text +
"'AND lastname like '" + textBox2.Text +
"'AND sex like '" + radiob +
"'AND birthdate like '" + maskedTextBox1.Text +
"'AND phone_number like '" + maskedTextBox2.Text + "' ;", conn);
2- You have to build your query string based on your text boxes and else seeing if they have any value, something like this:
StringBuilder Query = "SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE 1=1 ";
if(!String.IsNullOrEmpty(textBox1.Text))
Query.Append(" AND name like '" + textBox1.Text);
....
3- Sql Injection vulnerabilities

oh my God !!! Some programming !!!
where clause must created by and/or ,... other clauses ,
so ,
two solutions exist :
On server Side by Store Procedure by below definition :
you must care by position of AND/OR in below :
CREATE PROCEDURE [dbo].[dbo_Bank_SELByFields]
(
#ID nvarchar(50) = NULL ,
#BankName nvarchar(50) = NULL ,
#BankCode nvarchar(50) = NULL ,
#Address nvarchar(50) = NULL ,
#BranchCode nvarchar(50) = NULL
)
AS
SELECT * FROM dbo.Bank WHERE
(
(#ID IS NULL OR ID = #ID) AND
(#BankName IS NULL OR BankName =#BankName) AND
(#BankCode IS NULL OR BankCode =#BankCode) AND
(#Address IS NULL OR Address =#Address) AND
(#BranchCode IS NULL OR BranchCode =#BranchCode)
) ORDER BY BankCode
//---you know call the Sp . OK?
and other solution in your business layer code :
if you use ORM such as Entity Framework , very easy By IQueryable object, you can use below :
var selectByEnyCondition=(from c in ctx.customer ...);
//---- you must add by below way :
if(!(String.IsNullOrEmpty(txtName.Text)))
{
selectByEnyCondition.Where(.....);
}
if(!String.IsNullOrEmpty(sex))
{
selectByEnyCondition= opportunites.Where(.....);
}
//------
/* **** beacuse you use by ADO.NET technique you should use StringBuilder -->*/
StringBuilder query;
query.add("SELECT * FROM BankTbl WHERE ");
if(!(String.IsNullOrEmpty(txtName.Text))){
query.Add("Name Like {0}",txtName.Text);
//-----now continue for build your criteria
king reguard
bye.....

Related

Where is the error in my syntax? Getting values from SQL Server database

I am trying to read an integer from a SQL Server database by text in comboboxes.
I get a "Syntax error" "near" my Table name "Seeweg". The debugger does not highlight the line, where the error happens.
The column with the value I like to get is named seadistance. The other columns, by which to sort are start and ziel.
They get sorted by the values written in the comboboxes.
To reproduce this procedure I inserted the code into a class and called the instance by a button named btnSea.
I already searched for similar problems, but I could not find any syntax errors concerning the string implementation. The column names are correct.
//The Button
private void btnSea_Click(object sender, EventArgs e)
{
Entnehmen CO2 = new Entnehmen();
int Dist = CO2.Werte("Seeweg", "start", "ziel", "seadistance", comboSeaOrig.Text, comboSeaDest.Text);
MessageBox.Show(Dist.ToString());
}
//The class
class Entnehmen
{
public int Werte(string Tabelle, string Reihe1, string Reihe2, string Wertereihe, string WertReihe1, string WertReihe2)
{
int Wert = 0;
string myConnection = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;Connect Timeout=30";
using (SqlConnection myConn = new SqlConnection(myConnection))
{
myConn.Open();
SqlCommand SelectCommand = new SqlCommand("SELECT '" + Wertereihe + "' FROM '" + Tabelle + "' WHERE '" + Reihe1 + "' = '" + WertReihe1 + "' AND '" + Reihe2 + "' = '" + WertReihe2 + "' ; ", myConn);
Wert = (int)SelectCommand.ExecuteScalar();
}
return Wert;
}
}
}
I expect the value to be given back. Before that happens, I get the error:
Incorrect syntex near 'Seeweg'
Where is the syntax mistake? Any help is appreciated =)
You are generating something like:
SELECT 'seadistance' FROM 'Seeweg' WHERE 'start' = 'aa' AND 'ziel' = 'bbb'
This is not a valid T-SQL statement. Correct your quotes in columns and tables variables.
This is a suggestion of how you can write your T-SQL statemant based on your code:
SqlCommand SelectCommand = new SqlCommand("SELECT " + Wertereihe + " FROM " + Tabelle + " WHERE " + Reihe1 + " = '" + WertReihe1 + "' AND " + Reihe2 + " = '" + WertReihe2 + "' ; ", myConn);

How to disregard empty textbox or combobox in SQL SELECT?

I have a C# form that have a 6 filters (5 combobox, and 1 textbox) that the user can use to perform a search. The problem is that the user can leave some as blank or to use it all. To have a filtered search I used AND when doing a SELECT query, but the problem is it will return a blank or empty search when some of the filters is/are blank. If I will make each condition a query, I will have around 700 and so query. So I have search the closet, I think, scenario in this link
Ignore empty textboxes while searching in database
using (SqlConnection conn = new SqlConnection(#"Data Source=(local);
Initial Catalog=inventory;
Integrated Security=True"))
{
conn.Open();
string query = "SELECT * FROM [dbo].[product] WHERE IsDeleted = '0'";
using (SqlCommand scmd = new SqlCommand())
{
if (!string.IsNullOrEmpty(cmbItem.Text))
{
query += " AND Item Like #Item";
scmd.Parameters.Add("#Item", SqlDbType.VarChar).Value = "%" + item + "%";
}
}
if (!string.IsNullOrEmpty(cmbBrand.Text))
{
query += " AND Brand Like #Brand";
scmd.Parameters.Add("#Brand", SqlDbType.VarChar).Value = "%" + brand + "%";
}
//...additional query
}
scmd.CommandText = query;
scmd.Connection = conn;
using (SqlDataAdapter sda = new SqlDataAdapter(scmd))
{
dataGridView1.Refresh();
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
conn.Close();
}
And when performing the search, it is having an error like this;
'Invalid column name 'IsNull'.'
My original query goes something like this. But this will select nothing if one of the where condition is blank/empty.
SELECT * FROM [dbo].[product] WHERE Item = '" + item + "'
AND Brand = '" + brand + "'
AND Description = '" +desc + "'
AND Manufacturer = '" + manu + "'
AND Car = '" + car + "'
AND Year = '" + year + "'
If I use OR instead of AND. It will select something like this.
OR Statement
OR Statement
Below are the images for an ideal search.
Image for ideal selection
Image for ideal selection
Solved, by changing IsDeleted='0' to 1=1
string query = #"SELECT * FROM[dbo].[product] WHERE 1=1";
you can use store procedure and set parameter to default value
sample:
create proc sptest
#Fname nvarchar(50),
#Lname nvarchar(50),
#NCode nvarchar(12),
#UserType int
as
SELECT DISTINCT PersonID,
FName,
LName,
NationalID,
UserType
FROM Persons
WHERE
(FName LIKE('%' + #Fname + '%') OR (#Fname = ''))
AND (LName LIKE('%' + #Lname + '%') OR (#Lname = ''))
AND ((NCode = #NCode) OR (#NCode = ''))
AND ((UserType = #UserType) OR (#UserType = 0))
when textbox is empty or dropdownlists not is selected, get all record
Your original if/and conditions should work, but what you might be running into is a false resolution of the table COLUMN vs the PARAMETER. Since you have the example of
Item like #Item
if there is no actual parameter Item, SQL is implying to use its own value. For these types of queries, I try to prefix the parameter name to match. Change to
Item like #parmItem
and obviously change your parameter name string to match the "#parmItem" reference. This way there is no ambiguity in what value the SQL engine is looking for.

How to UPDATE multiple times off one connection OleDb

I am trying to update an Access database with information I have passed to a [WebMethod] from multiple txtbox's on a website.
[WebMethod]
public string changePersonalInfo(string email, string name, string id, string address, string contactDetails, string password, string question, string answer, string loggedInEmail)
I am passing all information to it weather it has a value or not.
if (email != "") //Wont execute if there is no value
{
cmd.CommandText = #"UPDATE BuyerInfo SET [emailAddress] = '" + email + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
if (name != "")
{
cmd.CommandText = #"UPDATE BuyerInfo SET [name] = '" + name + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
if (id != "")
{
cmd.CommandText = #"UPDATE BuyerInfo SET [id] = '" + id + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
//etc. It goes on for a few more.
cmd.ExecuteNonQuery();
conn.Close();
The problem is when I run the website it only updates the data from the last txtbox on the website (so in other words the last variable that has a value). How do I fix this, or if there is maybe a better way to do it.
P.S Keep in mind I am new to Web Services.
Thanx

List views and Grid views with the ItemCommand and RowCommand

Okay, so I am learning grid views and list views... Currently what I have is a working grid view.
The following code is as follows:
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName.CompareTo("Delete") == 0)
{
int newIndex = Convert.ToInt32(e.CommandArgument);
string studentEmail = GridView1.Rows[newIndex].Cells[1].Text;
AccessDataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [CourseID] = '" + studentEmail + "'";
AccessDataSource1.Delete();
AccessDataSource1.DataBind();
}
}
This works perfect for me. So I made a few other buttons for it and decided to move onto the list view and learn it. I cannot figure out why my delete button will not work. I currently can only make an update button. So, this is the code that I have so far
string StudentIDLabel = ((Label)(e.Item.FindControl("StudentIDLabel"))).Text.Trim();
string CourseIDLabel = ((Label)(e.Item.FindControl("CourseIDLabel"))).Text.Trim();
string GradeLabel = ((Label)(e.Item.FindControl("GradeLabel"))).Text.Trim();
AccessDataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + StudentIDLabel + "' AND [CourseID] = '" + CourseIDLabel + "' AND [Grade] ='" + GradeLabel + "'";
AccessDataSource1.Delete();
AccessDataSource1.DataBind();
I thought it might by how my SQL statement was and I have changed it around a lot. But As it is now I get a parameter error. I am assuming it might be something isn't passing through correctly..
So I changed my SQL delete statement to
AccessDataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + StudentIDLabel + "'" + CourseIDLabel + "'" + GradeLabel + "'";
This gives me the error :
Syntax error (missing operator) in query expression '[StudentID] = 'aaalshehri#mail.usi.edu'CS 402'A''."
StudentID is the first column, follower by CourseID and then Grade.
I am just really struggling with this and maybe a little guidance from someone not as green as I am would be appreciated very much.
Thanks!
Maybe StudentIDLabel, CourseIDLabel, GradeLabel are NULL.
string StudentIDLabel = ((Label)(e.Item.FindControl("StudentIDLabel"))).Text.Trim();
string CourseIDLabel = ((Label)(e.Item.FindControl("CourseIDLabel"))).Text.Trim();
string GradeLabel = ((Label)(e.Item.FindControl("GradeLabel"))).Text.Trim();
You need to show us the whole method/event where you are doing this, so that we may see:
string StudentIDLabel = ((Label)(e.Item.FindControl("StudentIDLabel"))).Text.Trim();
string CourseIDLabel = ((Label)(e.Item.FindControl("CourseIDLabel"))).Text.Trim();
string GradeLabel = ((Label)(e.Item.FindControl("GradeLabel"))).Text.Trim();
AccessDataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + StudentIDLabel + "' AND [CourseID] = '" + CourseIDLabel + "' AND [Grade] ='" + GradeLabel + "'";
AccessDataSource1.Delete();
AccessDataSource1.DataBind();
--EDIT--
You need to have the index of the button. So in the aspx code add this in the CommandArgument of the button to get the index:
CommandArgument='<%# Container.DataItemIndex %>'
In code-behind we can now get the labels using this:
Label StudentIDLabel = ListView1.Item[e.CommandArgument].FindControl("StudentIDLabel");
Label CourseIDLabel = ListView1.Item[e.CommandArgument].FindControl("CourseIDLabel");
Label GradeLabel = ListView1.Item[e.CommandArgument].FindControl("GradeLabel");
AccessDataSource1.DeleteCommand = string.Format("DELETE FROM [CoursesTaken] WHERE [StudentID] = '{0}' AND [CourseID] = '{1}' AND [Grade] = '{2}'", StudentIDLabel.Text, CourseIDLabel.Text, GradeLabel.Text)
AccessDataSource1.Delete();
AccessDataSource1.DataBind();
If Student Id is unique the you should be able to do
string sql= string.Format("DELETE FROM [CoursesTaken] WHERE [StudentID] ={0}",
StudentIDLabel);
AccessDataSource1.DeleteCommand = sql;
note integer dont need quotes.

"Cannot insert explicit value for identity column in table 'tbl Fingerprint' when IDENTITY_INSERT is set to OFF

[WebMethod]
public bool AddStudent(Student student)
{ bool UploadSuccess = false;
cn.Open();
int StudentID = 0;
using (SqlCommand com = new SqlCommand("INSERT into tblStudent (StudentNumber, Name, Surname, DOB, Gender, EmailAddress, Address1, Address2, City, Postcode, Username, Password, Course) values ('" + student.StudentNumber + "' ,'" + student.Name + "' ,'" + student.Surname + "' ,'" + student.DOB + "', '" + student.Gender + "' ,'" + student.EmailAddress + "' ,'" + student.Address1 + "' ,'" + student.Address2 + "' ,'" + student.City + "' ,'" + student.Postcode + "' ,'" + student.Username + "' ,'" + student.Password + "' ,'" + student.Course + "')", cn))
{
int i = com.ExecuteNonQuery();
StudentID = (int)com.ExecuteScalar();
cn.Close();
if (i != 0)
UploadSuccess = true;
return UploadSuccess;
}
I'm trying to insert data into fingerprint table which has four columns - ID (primary key) - StudentID (foreign key) linked to student table - description - Template
But the following error keeps coming up. I can't turn off the IDENTITY for ID as I want it to increment automatically. I also have a student table to store information. What I want to achieve is that after entering student details, I want to copy the studentID that was generated before onto the fingerprint table - StudentID column. the code I have for this is shown below.
private void btnSave_Click(object sender, EventArgs e)
{
fgrTemplate template = new fgrTemplate();
template.StudentID = std.StudentID;
template.Description = fngDes.Text;
template.Template = m_StoredTemplate;
if (upload.InsertTemplate(template))
{
MessageBox.Show("Student Successfully Added!");
}
else
{
MessageBox.Show("Student Not Successfully Added!");
}
using (SqlCommand com = new SqlCommand("INSERT INTO tblFingerprint (StudentID, Description, Template) values ('" + template.StudentID + "' ,'" + template.Description + "' ,#Template)", cn))
this is what I have on my web service. However it gives me the error
Your first error:
You are trying to insert StudentID which seems like a IDENTITY type field (Auto-increment), you don't have to pass that in your INSERT statement, SQL server will generate one for your.
Your second problem is: Your query is not properly parameterized, you are using a combination of string concatenation and parameters. Your query and statement should be like:
using (SqlCommand com = new SqlCommand(#"INSERT INTO tblFingerprint (Description, Template)
values (#Description, #Template)", cn))
{
com.Parameters.AddWithValue("#Description", template.Descriptio);
com.Parameters.AddWithValue("#Template", template.Value); //what ever value is
//....rest of your code
}
If you already have an StudentID and you want to update the existing record then use UPDATE statement.
If you want to manually insert the StudentID (overriding auto increment ID) then you have to use SET IDENTITY_INSERT
Remove or comment this line
//template.StudentID = std.StudentID;
Also remove StudentID from INSERT
"INSERT INTO tblFingerprint (Description,....
Your code can be attacked using an SQL INJECTION
In this case, try to use sql command parameters

Categories