Wildcards in T-SQL LIKE vs. ASP.net parameters - c#

In my SQL statement I use wildcards. But when I try to select something, it never select something. While when I execute the query in Microsoft SQL Server Management Studio, it works fine.
What am I doing wrong?
Click handler
protected void btnTitelAuteur_Click(object sender, EventArgs e)
{
cvalTitelAuteur.Enabled = true;
cvalTitelAuteur.Validate();
if (Page.IsValid)
{
objdsSelectedBooks.SelectMethod = "getBooksByTitleAuthor";
objdsSelectedBooks.SelectParameters.Clear();
objdsSelectedBooks.SelectParameters.Add(new Parameter("title", DbType.String));
objdsSelectedBooks.SelectParameters.Add(new Parameter("author", DbType.String));
objdsSelectedBooks.Select();
gvSelectedBooks.DataBind();
pnlZoeken.Visible = false;
pnlKiezen.Visible = true;
}
}
In my Data Access Layer
public static DataTable getBooksByTitleAuthor(string title, string author)
{
string sql = "SELECT 'AUTHOR' = tblAuthors.FIRSTNAME + ' ' + tblAuthors.LASTNAME, tblBooks.*, tblGenres.GENRE "
+ "FROM tblAuthors INNER JOIN tblBooks ON tblAuthors.AUTHOR_ID = tblBooks.AUTHOR_ID INNER JOIN tblGenres ON tblBooks.GENRE_ID = tblGenres.GENRE_ID "
+"WHERE (tblBooks.TITLE LIKE '%#title%');";
SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString());
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = title;
DataSet ds = new DataSet();
da.Fill(ds, "Books");
return ds.Tables["Books"];
}

Try this:
string sql = "SELECT 'AUTHOR' = tblAuthors.FIRSTNAME + ' ' + tblAuthors.LASTNAME, tblBooks.*, tblGenres.GENRE "
+ "FROM tblAuthors INNER JOIN tblBooks ON tblAuthors.AUTHOR_ID = tblBooks.AUTHOR_ID INNER JOIN tblGenres ON tblBooks.GENRE_ID = tblGenres.GENRE_ID "
+"WHERE (tblBooks.TITLE LIKE #title);";
SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString());
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = "%" + title + "%";

You can't include your query parameter inside a string literal. Do it like this instead:
WHERE (tblBooks.TITLE LIKE '%' + #title + '%');
Also, whenever you have a leading wildcard you should look into a full text index instead. Your query as written is doomed to be much slower than it could be, because you can't use index when you have a leading wild card.

The answer from John Allers is correct. As an aside, you should wrap the SqlDataAdapter in a using block:
using (SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString()))
{
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = title;
DataSet ds = new DataSet();
da.Fill(ds, "Books");
return ds.Tables["Books"];
}

Related

Number of query values and destinations fields are not the same

This is the function for automatically stored value to TotalAmt_tx.Text..
void TotalAmount()
{
.
.
.
.
TotalAmt_tx.Text = Total.ToString("00.00");
.
.
.
catch { }
}
Save button code :here the image of my forms
private void Save_bt_Click(object sender, EventArgs e)
{
//Purchase Table
{
string insertPur = "Insert into Purchase (Invoice,VendorName,PurchaseDate,TotalAmt) values ("+Invoice_tx.Text+"," +
"'"+VendorName_cb.Text+"','"+PurchaseDate_dt.Value.Date.ToString()+"',"+TotalAmt_tx.Text+" )";
OleDbDataAdapter da = new OleDbDataAdapter(insertPur, conn);
DataSet ds = new DataSet();
da.Fill(ds);
}
//Purchase Item Table
for (int i = 0; i < metroGrid1.Rows.Count; i++)
{
string insertPur = "Insert into PurchaseItem (Invoice, PId, Product, Qty, Rate, Amount) values (" + Invoice_tx.Text + "," +
""+metroGrid1.Rows[i].Cells["PId"].Value.ToString()+ ",'" + metroGrid1.Rows[i].Cells["Product"].Value.ToString() + "'," +
"" + metroGrid1.Rows[i].Cells["Qty"].Value.ToString() + "," + metroGrid1.Rows[i].Cells["Rate"].Value.ToString() + "," +
"" + metroGrid1.Rows[i].Cells["Amount"].Value.ToString() + ")";
OleDbDataAdapter da = new OleDbDataAdapter(insertPur, conn);
DataSet ds = new DataSet();
da.Fill(ds);
}
MessageBox.Show("Data Saved!!");
The problems show up because this
TotalAmt_tx.Text = Total.ToString("00.00")
What should I do, to solve it??
I've try follow some tutorial about formatting string but nothings works.
Please help
I suggest you try to use OleDbParameter Class, because if one of the values you combine to your query string has the , character it will mess-up you query (for example a number in the following format 1,000).
Hope it helps!
You should always stick to parameterized queries to avoid SQL Injection. It also helps in avoiding mistakes like missing a "'"
using (OleDbConnection connection =new OleDbConnection(connectionString))
{
var query = "Insert into Purchase (Invoice,VendorName,PurchaseDate,TotalAmt) values (#invoice,#vendor,#purchasedate,#amt)";
OleDbDataAdapter adapter = new OleDbDataAdapter(queryString, connection);
adapter.SelectCommand.Parameters.Add("#invoic", OleDbType.Integer).Value = Convert.ToInt32(Invoice_tx.Text);
adapter.SelectCommand.Parameters.Add("#vendor", OleDbType.VarChar,100).Value = VendorName_cb.Text;
adapter.SelectCommand.Parameters.Add("#invoic", OleDbType.Date).Value = PurchaseDate_dt.Value.Date; // I do not know what PurchaseDate_dt.Value.Date type is, so I leave it to you to convert to approapriate type
adapter.SelectCommand.Parameters.Add("#CategoryName", OleDbType.Integer).Value = Convert.ToInt32(TotalAmt_tx.Text);
connection.Open();
DataSet ds = new DataSet();
adapter.Fill(ds);
}

Retrieving a Row from a table causes invalid column name error

I am trying to delete a record in my database table. I am trying to delete it on the basis of a selected name in the dropdown list. When I debug my code there is not any record available in dataset and an exception "invalid column name" occurs, whereas if I run the same query in SQL Server, everything seems to be fine.
This is my code:
protected void SubCategory_Delete_Click(object sender, EventArgs e)
{
try
{
var conn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\template_castle.mdf;Integrated Security=True");
var adpt = new SqlDataAdapter("Select * from tc_prod_subcategory where subcategory_name = ' ' "+ DropDownList2.SelectedItem.Value, conn);
var ds = new DataSet();
adpt.Fill(ds, "tc_prod_subcategory");
foreach (DataRow dr in ds.Tables["tc_prod_subcategory"].Rows)
{
dr.Delete();
}
SqlCommandBuilder build = new SqlCommandBuilder(adpt);
adpt.Update(ds, "tc_prod_subcategory");
Updatesubcategorygrid();
updatedelete_dropdown();
Lblsub_catdelete.Text = "Deleted Successfully";
}
catch(Exception ex)
{
Lblsub_catdelete.Text = ex.Message;
}
}
And this is the same query when I run it in SQL Server 2014; everything runs fine:
Select *
from tc_prod_subcategory
Where subcategory_name= 'Favicon'
The error is caused by the incorrect position of the apostophes in the where clause. It should be like:
"Select * from tc_prod_subcategory where subcategory_name = '" + DropDownList2.SelectedItem.Value + "'"
but that code is vulnerable to a SQL injection,so you should use parameters instead of concatenating strings.
var conn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\template_castle.mdf;Integrated Security=True");
var adpt = new SqlDataAdapter("Select * from tc_prod_subcategory where subcategory_name = #subcategory_name", conn);
var ds = new DataSet();
adpt.SelectCommand.Parameters.AddWithValue("#subcategory_name", DropDownList2.SelectedItem.Value);
If you use c# version >= 6.0
you can use interpolation to concat strings in very handy and less error-prone way.
var adpt = new SqlDataAdapter($"Select * from tc_prod_subcategory where subcategory_name = '{DropDownList2.SelectedItem.Value}'", conn);

System.Data.SqlClient.SqlException: Incorrect syntax near ')'

I am getting an error in my SQL command with which I am trying to retrieve values from a SQL Server database. It is showing a error in browser as mentioned in title. If I remove the brackets it shows error in AND operator
string jdate = (string)Session["jdate"];
string clas = (string)Session["class"];
string scode = (string)Session["scode"];
string dcode = (string)Session["dcode"];
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["dummyConnectionString"].ToString());
// error shows up on this line
string slct = "SELECT Route.Route_Source, Route.Route_Destination, Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time, Schedule.Route_rate_Ad , Seats." + jdate +
"Schedule.Sch_id FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id INNER JOIN Route ON Schedule.Route_id = Route.Route_id INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id WHERE (Route.Route_Source =" + scode + ") AND (Route.Route_Destination =" + dcode + ") AND (Seats.Class=" + clas + ") ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlDataAdapter da = new SqlDataAdapter(slct, cn);
DataSet ds = new DataSet();
da.Fill(ds);
SearchView.DataSource = ds;
SearchView.DataBind();
You should use a parameterized query.
This would allow a more understandable query text, avoid simple syntax errors
(like the missing comma at the end of the first line (jdate)),
avoid Sql Injections and parsing problems with strings containing quotes or decimal separators
string slct = #"SELECT Route.Route_Source, Route.Route_Destination,
Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time,
Schedule.Route_rate_Ad, Seats." + jdate + ", Schedule.Sch_id " +
#"FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id
INNER JOIN Route ON Schedule.Route_id = Route.Route_id
INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id
WHERE (Route.Route_Source = #scode)
AND (Route.Route_Destination =#dcode)
AND (Seats.Class=#class)
ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlCommand cmd = new SqlCommand(slct, cn);
cmd.Parameters.AddWithValue("#scode", scode);
cmd.Parameters.AddWithValue("#dcode", dcode);
cmd.Parameters.AddWithValue("#class", clas);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);

Query works in Access but not in my program. Why?

I have this query set up in my application to work for searching through my database. I put this query into Access and it works fine. However, when I put it into my program the table has 0 entries. Can you please help?
private async Task FilterDB()
{
List<string> Filter = new List<string>();
if (CardNameCheck.IsChecked == true)
Filter.Add("*" + CardNameBox.Text + "*");
else
Filter.Add("*");
if (CardExpanCheck.IsChecked == true)
Filter.Add("*" + CardExpanBox.Text + "*");
else
Filter.Add("*");
OleDbConnection DBCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Properties.Settings.Default.DatabaseLocation);
await DBCon.OpenAsync();
OleDbDataAdapter CardDA = new OleDbDataAdapter("SELECT * FROM Cards WHERE Name like '" + Filter[0] + "' and Expansion like '" + Filter[1] + "'", DBCon);
DataSet CardDS = new DataSet();
CardDA.Fill(CardDS);
DBCon.Close();
I tried your code and modified it a bit. Works for me for the Access2003 .mdb format.
OleDbConnection DBCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=(k:\mydatabases\mydatabase.mdb");
DBCon.Open();
// Create a select Command - you need System.Data.OleDb and System.Data for this
OleDbCommand selectCommand = new OleDbCommand();
// define the CommandText with two parameters #Filter1 and #Filter2
selectCommand.CommandText = "SELECT * FROM Cards WHERE Name like #Filter1 and Expansion like #Filter2";
selectCommand.Connection = DBCon;
// Create two string / VarChar Parameters -
// the following is a standard I commonly use
// for string/varchar; you might also use OleDbType.NVarChar
OleDbParameter param01 = new OleDbParameter();
param01.ParameterName = "Filter1";
param01.DbType = DbType.AnsiString;
param01.OleDbType = OleDbType.VarChar;
param01.SourceVersion = DataRowVersion.Current;
param01.SourceColumn = "Name";
// provide them with values - I used text boxes for input
// use '%' for like statement - if no parameter provided use single '%' only
if (txtFilter1.Text.ToString().Equals(""))
{
param01.Value = '%';
}
else
{
param01.Value = '%' + txtFilter1.Text.ToString() + '%';
}
// add the parameter to the SelectCommand
selectCommand.Parameters.Add(param01);
// same goes for the second parameter
OleDbParameter param02 = new OleDbParameter();
param02.ParameterName = "Filter2";
param02.DbType = DbType.AnsiString;
param02.OleDbType = OleDbType.VarChar;
param02.SourceVersion = DataRowVersion.Current;
param02.SourceColumn = "Expansion";
if (txtFilter2.Text.ToString().Equals(""))
{
param02.Value = '%';
}
else
{
param02.Value = '%' + txtFilter2.Text.ToString() + '%';
}
selectCommand.Parameters.Add(param02);
OleDbDataAdapter CardDA = new OleDbDataAdapter();
// tell the DataAdapter to use a SelectCommand
CardDA.SelectCommand = selectCommand;
CardDA.GetFillParameters(); // actually not sure if you need this but does no harm either
DataSet CardDS = new DataSet();
CardDA.Fill(CardDS, "TargetTable");
DBCon.Close();
foreach(DataRow row in CardDS.Tables["TargetTable"].Rows)
{
// do something ;
}
Good luck!

Datagrid filter in c# using sql server

How to filter data in datagrid for example if you select the combo box in student number then input 1001 in the text field. All records in 1001 will appear in datagrid. I am using sql server
private void button2_Click(object sender, EventArgs e)
{
if (cbofilter.SelectedIndex == 0)
{
string sql;
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Server= " + Environment.MachineName.ToString() + #"\; Initial Catalog=TEST;Integrated Security = true";
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds1 = new DataSet();
ds1 = DBConn.getStudentDetails("sp_RetrieveSTUDNO");
sql = "Select * from Test where STUDNO like '" + txtvalue.Text + "'";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
da.SelectCommand = cmd;
da.Fill(ds1);
dbgStudentDetails.DataSource = ds1;
dbgStudentDetails.DataMember = ds1.Tables[0].TableName;
dbgStudentDetails.Refresh();
}
else if (cbofilter.SelectedIndex == 1)
{
//string sql;
//SqlConnection conn = new SqlConnection();
//conn.ConnectionString = "Server= " + Environment.MachineName.ToString() + #"\; Initial Catalog=TEST;Integrated Security = true";
//SqlDataAdapter da = new SqlDataAdapter();
//DataSet ds1 = new DataSet();
//ds1 = DBConn.getStudentDetails("sp_RetrieveSTUDNO");
//sql = "Select * from Test where Name like '" + txtvalue.Text + "'";
//SqlCommand cmd = new SqlCommand(sql,conn);
//cmd.CommandType = CommandType.Text;
//da.SelectCommand = cmd;
//da.Fill(ds1);
// dbgStudentDetails.DataSource = ds1;
//dbgStudentDetails.DataMember = ds1.Tables[0].TableName;
//ds.Tables[0].DefaultView.RowFilter = "Studno = + txtvalue.text + ";
dbgStudentDetails.DataSource = ds.Tables[0];
dbgStudentDetails.Refresh();
}
}
It's difficult to answer pricisely to a vague question. I guess that you'll have to adapt your SQL query with a WHERE statement containing the user input.
If 'student number' is selected in the combo box, query like this (numbers starting with):
SELECT id, name, number FROM students WHERE number LIKE #search + '%'
If 'student name' is selected, use another query (names containing):
SELECT id, name, number FROM students WHERE name LIKE '%' + #search + '%'
Please explain in what sense C# is concerned.
You don't say what is wrong with the code you commented out. You also don't say what type the Studno column is.
Have you tried something like:
ds1.Tables[0].DefaultView.RowFilter = "Studno = '" + txtvalue.text + "'";

Categories