Using parameterized SQL LIKE Statements - c#

I'm trying to parameterize my SQL Statements but I'm having some trouble with the LIKE statement. I tried different solutions but nothing works. My code:
sqlCmd = new SqlCommand("SELECT " + form1.cusId.Text + "," + form1.cusName.Text" FROM " + form1.getTable() + " WHERE " + form1.getCusId() + " LIKE #filterCustomers", connection);
sqlCmd.Parameters.AddWithValue("#filterCustomers", form1.filterCus().Trim() + "%");
I'm getting
"Must declare the scalar variable #filterCustomers".
Why ist that happening? Since this is th common solution...

What if you try
sqlCmd.Parameters.Add("#filterCustomers",SqlDbType.VarChar,8).Value = form1.filterCus().Trim() + "%";
Instead of:
sqlCmd.Parameters.AddWithValue("#filterCustomers", form1.filterCus().Trim() + "%");
You can change the.VarChar for what you data type is and the 8 for the required max field lenght, or remove the ,8 completely for no limit in the parameter lenght

you need to put your string inside single quotes ':
...+" LIKE '"+ form1.filterCus().Trim()+"%'", connection);
if you don't worry about SQL INJECTION
EDIT: you can also use dynamic sql:
sqlCmd = new SqlCommand("EXEC ('SELECT..... WHERE FIELD LIKE ''' + #filterCustomers + '%''')", connection);
sqlCmd.Parameters.AddWithValue("#filterCustomers", form1.filterCus().Trim() + "%");

Related

C#: How to pass parmeterize values to System.Data.Entity.SqlSquery

I'm going to execute SQL query directly on database.
I've define connection to my database using:
System.Data.Entity.DbContext rawDbContext = new DbContext(connectionString);
I don't want to insert parameters directly to query string to avoid SQL Injection so I want to set parametrized values for my SQL query this way:
string sqlCommandString =
"IF EXISTS(select* from #MappingTableName where " + Environment.NewLine +
"BranchID= #PrimaryKeyID and " + Environment.NewLine +
"BranchNo = #BranchNo and " + Environment.NewLine +
"TableName = #TableName and " + Environment.NewLine +
"BranchSchema = #SchemaNameInBranch and " + Environment.NewLine +
"TableID = #TableID) " + Environment.NewLine +
" select 1" + Environment.NewLine +
"ELSE " + Environment.NewLine +
"select 0 " + Environment.NewLine;
SqlParameter parameterMappingTableName = new SqlParameter("#MappingTableName", vipMappingTableName);
SqlParameter parameterSchemaNameInBranch = new SqlParameter("#SchemaNameInBranch", schemaName);
SqlParameter parameterPrimaryKeyInBranch = new SqlParameter("#PrimaryKeyID", primaryNodeId);
SqlParameter parameterBranchNo = new SqlParameter("#BranchNo", branchNo);
SqlParameter parameterTableId = new SqlParameter("#TableID", tableId);
SqlParameter parameterTableName = new SqlParameter("#TableName", tableName);
DbRawSqlQuery<int> result = rawDbContext.Database.SqlQuery<int>(sqlCommandString,
new[] {
parameterMappingTableName,
parameterSchemaNameInBranch,
parameterPrimaryKeyInBranch,
parameterBranchNo,
parameterTableId,
parameterTableName
});
int finalResult = result.Single();
Running this query leads to excpetion "Must declare the table variable \"#MappingTableName\"."
How can I fix this?
Check this from Microsoft forums
Database objects (tables, stored procedures or any other objects)
cannot be passed as parameters. Only actual values for columns or
variables can be parameters. You need to build your SQL statement
dynamically in this case
Which basically means that you have to provide and/or build the table name, under the danger that this can be compromised.
How to mitigate the risk. Declare a set of probable table name and do an exact match.
Then build your query with text concatenation. This is something that can't be done with parameters cause you can't expect the possible values, but can be done with tables because they are only so many. Be carefull to use Equals instead of Contains in your list of names.

Error when trying to insert into MS Access Database

I am developing a program that uses a relational database. In one particular form I am trying to insert new products information into the database.
using System.Data.OleDb;
When I try to save a new product this code runs...
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = "insert into Products (ProductName,ProductSKU,RP,WP,Stock,FPS,Ammo,MagazineCap,HopUp,Range,Brand,Colour,Action,Features) values('" + txt_ProductName.Text + "','" + txt_SKU.Text + "'," + txt_RP.Text + "," + txt_WP.Text + "," + numericUpDown_Inventory.Value + "," + cobo_FPS.Text + ",'" + cobo_Ammo.Text + "'," + cobo_MagazineCap.Text + ",'" + cobo_HopUp.Text + "'," + cobo_Range.Text + ",'" + cobo_Brand.Text + "','" + cobo_Colour.Text + "','" + cobo_Action.Text + "','" + txt_Features.Text + "')";
//Action field currently causes an error
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
connection.Close();
...and an error is thrown
"Error System.Data.OleDb.OleDbException (0x80040E14): Syntax error in
INSERT INTO statement."
(and then a bunch of stuff which I don't think is important)
Apologies for the HUGE SQL query. I am using the exact same method of using the insert SQL query in several other places in my program and they all work completely fine. This example however is causing this error. Through the tedious process of "commenting out" individual parts of my SQL query I found that the error lies with the "Action" field. I have checked that the data type in my database is correct and that I am using the '' punctuation to surround the text string that is being inserted into the database.
I think I've checked everything, so why am I still getting this error?
Many thanks in advance and if more information is required just let me know ;)
Action is a reserved keyword in OLE DB Provider. You need to use it with square brackets like [Action]. As a best practice, change it to non-reserved word.
But more impontant
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your OleDbConnection and OleDbCommand automatically instead of calling .Close() method manually.

String field with single quotation mark is causing an error when inserting record in table

I have below code:
query = "insert into tblB2B_OrderStatusTopStillInRB (LSRNbr, ShipName, Units, DroppedInRB, EPT, Status, OnTimeStatus, ShipVia, DroppedInRB_Order, RealEPT) ";
query += "values ('"
+ ListOrdStatusTopInRB[i].LSRNbr + "','"
+ ListOrdStatusTopInRB[i].ShipName + "',"
+ ListOrdStatusTopInRB[i].Units + ",'"
+ ListOrdStatusTopInRB[i].DroppedInRB + "','"
+ ListOrdStatusTopInRB[i].EPT + "','"
+ ListOrdStatusTopInRB[i].Status + "','"
+ ListOrdStatusTopInRB[i].OnTimeStatus + "','"
+ ListOrdStatusTopInRB[i].ShipVia + "','"
+ ListOrdStatusTopInRB[i].DroppedInRB_Order + "','"
+ ListOrdStatusTopInRB[i].RealEPT + "')";
cmd.CommandText = query;
cmd.ExecuteNonQuery();
And I just realized, that when the ShipName has a value with a single quotation mark, is causing an error in the insert statement, for instance: int'l Transp.
Is there any way to fix that, without removing the single quotation mark from the string?
I was trying using the following but didn't work:
cmd.CommandText = #query
+ #ListOrdStatusTopInRB[i].ShipName + "',"
Any ideas?
Is there any way to fix that, without removing the single quotation mark from the string?
Yes - use parameterized SQL instead. You should never use variable values directly in your SQL like this. It can allow SQL injection attacks, cause conversion oddities, and generally make the SQL more confusing to read.
See the documentation for SqlCommand.Parameters for an example of parameterized SQL.
Basically, the idea is that your SQL includes references to parameters, e.g.
INSERT INTO SomeTable(Foo, Bar) VALUES (#Foo, #Bar)
and then you specify the values for #Foo and #Bar separately. The values then aren't part of the SQL itself, so it doesn't matter whether or not they contain characters which would have special meaning within the SQL.

SQL statement, OleDbException error INSERT

There is no error in the code, but no information is appearing in the database.
string mysql;
mysql = "INSERT INTO Cars(Make,Model,Price,[Image]) VALUES ('"
+ tbMake.Text + "','" + tbModel.Text + "'," + tbPrice.Text + ",'" + FileUpload1.FileName + "')";
siteDB.InsertCommand = mysql;
DataList1.DataBind();
Cheers.
With an Access database the word IMAGE is a reserved keyword.
If you want to use it you need to encapsulate with square brakets
"INSERT INTO Cars(Make,Model,Price,[Image]) VALUES ......"
This will resolve you immediate problem, but as John Skeet pointed out in its comment you need to use a parametrized query because this solves also the problem of proper formatting of your text values.
What happens to your handy crafted query if a model name (or make) contains a single quote?
Another syntax error is waiting for you (and from my experience it will bite you just when you have finished to code and are ready to work)
Just to complete the answer, feel free to test if in this way it adds the record to your db
mysql = "INSERT INTO Cars(Make,Model,Price,[Image]) VALUES (?,?,?,?)";
OleDbCommand cmd = new OleDbCommand(mysql, con);
cmd.Parameters.AddWithValue("#p1", tbMake.Text);
cmd.Parameters.AddWithValue("#p2", tbModel.Text);
cmd.Parameters.AddWithValue("#p3", Convert.ToDecimal(tbPrice.Text));
cmd.Parameters.AddWithValue("#p4", FileUpload1.FileName);
cmd.ExecuteNonQuery();
I am assuming siteDB is an SQLDataAdapter.
In this case your code should at least be changed to this:
string mysql;
mysql = "INSERT INTO Cars(Make,Model,Price,Image) VALUES ('"
+ tbMake.Text + "','" + tbModel.Text + "'," + tbPrice.Text + ",'" + FileUpload1.FileName + "')";
siteDB.InsertCommand = mysql;
DataList1.DataBind();

how to get a count(*) for number of records updated

i am updating a sql server 2008 database using c# like this:
foreach (DataRow row in dt.Rows)
{
faxstatus = row.ItemArray[5].ToString().Contains("0000") ? "Faxed" : "Error";
query =
#"update FileLog set
FaxStatus=" + "'" + faxstatus + "'," +
"FaxedPageCount=" + "'" + row.ItemArray[1] + "'," +
"dtFaxed=" + "'" + row.ItemArray[2] + "'," +
"BiscomCode=" + "'" + row.ItemArray[5] + "', " +
"RetryCount=" + "'" + row.ItemArray[4] + "' " +
"where CONVERT(VARCHAR(255), JobID) =" + "'" + row.ItemArray[3] + "'" +
" and FaxStatus<>'Faxed'";
command = new SqlCommand(query, myConnection);
command.ExecuteNonQuery();
NumberOfRecordsUpdated++;
}
i would like to know whether it is possible to return how many records were updated?
Yes. Use ExecuteNonQuery's return value. :-)
Quoting ExecuteNonQuery's documentation:
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
Capture and use the result of ExecuteNonQuery to an integer. That method returns the number of records affected by the operation.
See SqlCommand.ExecuteNonQuery Method.
That being said, how much do you trust your datasource? Enough to bet your data integrity on it? I'd be remissed if I didn't implore you to explore parameterized queries. A using statement would also be warranted so that your disposable resources (SqlConnection, SqlCommand, etc.) are properly dealt with.
Append SELECT ##ROWCOUNT to your statement and use ExecuteScalar instead of ExecuteNoneQuery.
Refering to SqlCommand.ExecuteNonQuery Method :
Return Value
Type: System.Int32
The number of rows affected.
You could use ##ROWCOUNT .

Categories

Resources