SQL CASE statement WHEN and THEN values from SqlParameterCollection - c#

I am not sure if this question already has answers on SO, but as I couldn't find one, I am writing here. I am trying to write an update query using CASE statement. The values of WHEN and THEN comes from user-given data where I need to update multiple rows with multiple values that the user gives. I am eliminating the loop that I have written in the original code in the snippet below as the problem is only with AddWithValue. Is there a way to use SqlParameterCollection to assign the THEN value? Or is a simple string concatenation a way to do this?
SqlCommand command = new SqlCommand("UPDATE [Table] SET Column = CASE ", connection);
command.CommandText += "WHEN Column = #Column1 THEN #Column2";
command.CommandText += "ELSE Column END";
command.Parameters.AddWithValue("#Column1", "Value1");
command.Parameters.AddWithValue("#Column2", "Value2");
connection.Open();
command.ExecuteNonQuery();
The error:
Incorrect syntax near '#Column2'

Just wanted to note that this syntax error probably also wouldn't have occurred if you'd used verbatim strings:
new SqlCommand(#"
UPDATE [Table]
SET
Column = CASE
WHEN Column = #Column1 THEN #Column2
ELSE Column
END"
, connection);
I tend to stick all the sql so it starts from indent level 0, and using the # string means it can be formatted how I like an sql to be without any interim c# making it messy.
If you're building a variable number of cases, string interpolation might also tidy things up and you can have an interpolated # string by prefixing $# - I remember which way round they go by "Microsoft are polite and didn't want to fill people's code with #$ (ass)" ;)
var whens = "WHEN...";
for(...){
whens += ...
parameters.Add(..)
}
new SqlCommand($#"
UPDATE [Table]
SET
Column = CASE
{whens}
ELSE Column
END
", connection);
And of course final debugging tip; if you build an sql dynamically and you get a syntax error, pause in the debugger and look at the command text just before you run it; point to the Command variable, open the tooltip, click the magnifying glass next to CommandText property to see the string as is in a notepad style window, with new lines etc as actual new lines not as \n that the debug tooltip shows - it's a lot easier to spot syntax errors in this visualizer
image courtesy of https://gunnarpeipman.com/ef-core-toquerystring/amp/

So finally it's all about the syntax errors as mentioned by #marc_s and #serg in the comments. This worked:
SqlCommand command = new SqlCommand("UPDATE [Table] SET Column = CASE ", connection);
command.CommandText += "WHEN Column = #Column1 THEN #Column2 ";
command.CommandText += "ELSE Column END";
command.Parameters.AddWithValue("#Column1", "Value1");
command.Parameters.AddWithValue("#Column2", "Value2");
connection.Open();
command.ExecuteNonQuery();

Try the following SQL Server code:
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.Parameters.AddWithValue("#Column1", "Value1");
command.Parameters.AddWithValue("#Column2", "Value2");
String StrSqlCommand = "UPDATE [Table] SET Column = CASE ";
StrSqlCommand += " WHEN Column = #Column1 THEN #Column2 ";
StrSqlCommand += " ELSE Column END ";
command.CommandText = StrSqlCommand;
connection.Open();
command.ExecuteNonQuery();
Also be careful about the terms "Value1" and "Value2". Because in the code you send, the above values are considered exactly the same as the string type. If you want another value, it is better to define a variable and put it as a parameter in the above expressions. Something like this:
String strValue1 = "Name1";
String steValue2 = "Name2";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.Parameters.AddWithValue("#Column1", strValue1);
command.Parameters.AddWithValue("#Column2", strValue2);
String StrSqlCommand = "UPDATE [Table] SET Column = CASE ";
StrSqlCommand += " WHEN Column = #Column1 THEN #Column2 ";
StrSqlCommand += " ELSE Column END ";
command.CommandText = StrSqlCommand;
connection.Open();
command.ExecuteNonQuery();

Related

need help minus value from database column

I am trying to minus value in database column from textbox I got error an expression of non-boolean type specified in a context where condition is expected
cn.Open();
SqlCommand command = new SqlCommand();
command.Connection = cn;
command.CommandText = "select * from class where quanitity - '"+Convert.ToInt32(textBox10.Text)+"'";
command.ExecuteNonQuery();
cn.Close();
You are not minus value to column.you want like this
command.CommandText = "update class set quanitity = quanitity - "+Convert.ToInt32(textBox10.Text) ;
This will definitely work
command.CommandText = string.Format("update class set quanitity= quanitity - {0}",Convert.ToInt32(textBox10.Text));
You need a value to compare your two numbers to. You are subtracting your TextBox10 value from quantity, but what result set do you want to see after subtracting the value? There needs to be a comparison somewhere to the right of your WHERE.
command.CommandText = "select (quantity - "+Convert.ToInt32(textBox10.Text)+") from class ;
I suspect you SQL Injection alert..Do not Concatenate string it's wide open for sql injection alert.So use parameterized query
command.CommandText = "select * from class where quanitity -#txtbox10";
command.Parameters.AddWithValue("#txtbox10", Convert.ToInt32(textBox10.Text));
command.ExecuteNonQuery();

unable to update in a database with c#

I am unable to update my database. I have a table called Table2 and I have in it 3 columns: time, strike and vol. Please check the comments made in the line statements. thanks in advance for the help.
VolLoc = Math.Sqrt(Math.Abs(VarianceLoc));
Console.WriteLine("Local Volatility at strike " + strike1_run + " and time " + time0_run + " is: " + VolLoc + "\n"); // works perfectly at this point, I have a new value for my variable VolLoc
string StrCmd1 = "UPDATE Table2 SET (vol = #vol_value) WHERE ((time = #T0_value) AND (strike = #K1_value))"; // HERE is the problem, when I debug, the cursor steps on it normally but the database is not updated !!
OleDbCommand Cmd1 = new OleDbCommand(StrCmd1, MyConn);
Cmd1.Parameters.Add("#vol_value", OleDbType.VarChar);
Cmd1.Parameters["#vol_value"].Value = VolLoc.ToString();
Cmd1.Parameters.Add("#T0_value", OleDbType.VarChar);
Cmd1.Parameters["#T0_value"].Value = time0_run.ToString();
Cmd1.Parameters.Add("#K1_value", OleDbType.VarChar);
Cmd1.Parameters["#K1_value"].Value = strike1_run.ToString(); //the cursor steps on each of the line statements above, but the database is still not updated
Apart from the missing call to ExecuteNonQuery as stated by other, your code has another error that will show itself when your code will reach the ExecuteNonQuery method.
The word TIME is a reserved keyword in MS-Access Jet SQL.
You need to encapsulate it with square brackets [time]
So, summarizing
string StrCmd1 = "UPDATE Table2 SET vol = #vol_value WHERE " +
"([time] = #T0_value AND strike = #K1_value)";
OleDbCommand Cmd1 = new OleDbCommand(StrCmd1, MyConn);
.......
cmd1.ExecuteNonQuery();
Also, all the parameters are passed as string values. Are you sure that the corresponding fields are of the same datatype (text)
You need to call an Execute method on your OleDbCommand object.
try adding
Cmd1.ExecuteNonQuery();

Adding textbox values to an SQL database in c#

I'm trying to add values from a textbox into a datagridview, I have asked this question before but I'm now getting a different error saying
There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
This is the code causing the error
private void SaveBtn_Click(object sender, EventArgs e)
{
SqlConnection sc = new SqlConnection();
SqlCommand com = new SqlCommand();
sc.ConnectionString = ("Data Source=localhost;Initial Catalog=LoginScreen;Integrated Security=True");
sc.Open();
com.Connection = sc;
com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");
com.ExecuteNonQuery();
sc.Close();
}
my database
The direct cause of the error is omitted commas (",") in the "value" section of the query.
You should have put it like that
VALUES ('"+ProdID.Text+"', '"+ProdName.Text+", '+'"+ProdCat.Text+", '+'"+ProdSup.Text+...
instead of
VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+...
Your code is also vulnerable to so called SQL-injection attack (imagine someone has put
'" delete from Stock --' into ProdID.Text: the execution'll result in Stock table
clearance)
The recommended way looks something like this:
using(SqlConnection sc = new SqlConnection()) {
sc.ConnectionString = "Data Source=localhost;Initial Catalog=LoginScreen;Integrated Security=True";
sc.Open();
using (SqlCommand com = sc.CreateCommand()) {
com.CommandText =
"insert into Stock(\n" +
" Prod_Id,\n" +
" Prod_Name,\n" +
" Prod_Cat,\n" +
" Supplier,\n" +
" Cost,\n" +
" Price_1,\n" +
" Price_2,\n" +
" Price_3)\n" +
"values(\n" +
" #prm_Prod_Id,\n" +
" #prm_Prod_Name,\n" +
" #prm_Prod_Cat,\n" +
" #prm_Supplier,\n" +
" #prm_Cost,\n" +
" #prm_Price_1,\n" +
" #prm_Price_2,\n" +
" #prm_Price_3)";
//TODO: Change my arbitrary "80" to actual Stock fields' sizes!
com.Parameters.Add("#prm_Prod_Id", SqlDbType.VarChar, 80).Value = ProdID.Text;
com.Parameters.Add("#prm_Prod_Name", SqlDbType.VarChar, 80).Value = ProdName.Text;
com.Parameters.Add("#prm_Prod_Cat", SqlDbType.VarChar, 80).Value = ProdCat.Text;
com.Parameters.Add("#prm_Supplier", SqlDbType.VarChar, 80).Value = ProdSub.Text;
com.Parameters.Add("#prm_Cost", SqlDbType.VarChar, 80).Value = ProdCost.Text;
com.Parameters.Add("#prm_Price_1", SqlDbType.VarChar, 80).Value = ProdPrice1.Text;
com.Parameters.Add("#prm_Price_2", SqlDbType.VarChar, 80).Value = ProdPrice2.Text;
com.Parameters.Add("#prm_Price_3", SqlDbType.VarChar, 80).Value = ProdPrice3.Text;
com.ExecuteNonQuery();
}
}
You are missing commas in your values part of your sql. When ever you are doing something like this (big concatination of a string) you should know two things. First, a good way to test is to write out to console, messagebox, ext. You often will see the error right away. The next thing to know is that if you are concatintating to insert into a DB, dont do it. Use parameterized queries. -> How do parameterized queries help against SQL injection?
com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");
should be something like this
com.CommandText = (#"INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');"));
Checkbox values in a form either result in nothing whatsoever if no boxes are checked, or a comma delimted list of values. The worst thing you can possibly do is to store this list in a single record. That would result in unusable data.
Instead, you want to change not only your code, but possible your database design so that you have a single record for every box that was checked. Remember to account for the scenario where no boxes are checked.
Try :
com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');");
You should Replace
('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");`
with
('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');");`
(VALUES part needs commas for each column)

How does JET OLEDB Parameters compare strings with text field in and Access DB

I have the following update query in C# using a JET OLEDB connection, connecting to a ms access DB file. The query fails to change the fields, it runs correctly but just 0 rows changed.
I think the problem is how parameters are processed and compared against the DB but have no idea how to fix it.
The "User" column is set as text. I have an insert statement that works perfectly set up in the same fashion with the parameters.
com.CommandText = "UPDATE [ExamMaster] SET [User] = (DLookup('LName', 'Users', 'ID' = '#correctUser') WHERE [User] = '#user'";
com.Parameters.AddWithValue("#correctUser", correctUser);
com.Parameters.AddWithValue("#user", userName);
If I do not use a parameter for the where clause and just insert it into the command string like so:
WHERE [User] = '"+userName+"'";</code>
it will update the DB just fine. What am I missing here?
UPDATE:
With or with single quotes makes no difference and rearranging the order of the parameters does not work either.
The order matters. I "think" in your query user is being called first before the correctUser due to the DLOOKUP function.
com.Parameters.AddWithValue("#user", userName);
com.Parameters.AddWithValue("#correctUser", correctUser);
You don't need to single quote parameters:
WHERE [User] = #user";
and I'll guess that the DLOOKUP doesn't need the single quotes either, just [brackets] if the field name has a space or is a reserved word (which [User] might be).
You will need to change that a bit, try:
OleDbConnection cn = new OleDbConnection(aconnectionstring);
cn.Open();
//testing
int correctUser = 1;
string userName = "1";
OleDbCommand com = new OleDbCommand();
com.Connection = cn;
//You cannot have a parameter in DLookUp
com.CommandText = "UPDATE [ExamMaster] SET [User] = " +
"DLookup('LName', 'Users', 'ID = " + correctUser + "') WHERE [User] = #user";
com.Parameters.AddWithValue("#user", userName);
//You must execute the query
com.ExecuteNonQuery();

Getting error Input string was not in a correct format when updating via MySQL

I am getting error "Input string was not in a correct format" when trying to update a table via the MySQL .NET connector.
The update statement works fine when run via MySQL workbench, but not via code and I am hoping someone can tell me why.
Code is:
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId like '" + amazonOrderId + "%';";
command.ExecuteNonQuery();
I have tried both executing as a non query, and as ExecuteReader(); with no luck.
I am sure this is a simple mistake I am making, but I can't seem to find it for the life of me so any help would be greatly appreciated.
-- Edit --
I have tried the following with no luck:
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId like '#amazonOrderId';";
command.Parameters.AddWithValue("#amazonOrderId", amazonOrderId);
also changed CommandText to:
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where convert(varchar(50), amazonOrderId) like '" + amazonOrderId + "';";
and
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId = '#amazonOrderId';";
and
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId = #amazonOrderId;";
-- Resolution --
My resolution was actually found in another piece of code. After running through the debugger several times it became apparent that a MySqlConnection object was trying to be instantiated twice - with the same name etc. I removed the second instantiation and it has resolved the issue. It's too bad the error was misleading.
I appreciate everyone's responses as I feel they have made my code better and as such I have given +1's to Jon, Steve and Chris. Thanks for the help!
Is the variable amazonOrderId numeric? If so, you can't + a string to it without calling ToString() on the variable.
amazonOrderId.ToString() + "%"
Is amazonOrderId numeric in the database? If so, have you tried convert(varchar)?
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where convert(varchar(50), amazonOrderId) like #OrderID;";
command.Parameters.AddWithValue("#orderID", amazonOrderId + "%");
command.ExecuteNonQuery();
But I'm not sure why you need LIKE with %. Would this also update:
1001 - amazon order id
10010
10011
10012
10013
etc.
Is that what you really want?
If not, then use equal instead, without single quotes.
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId = #OrderId;";
command.Parameters.AddWithValue("#orderID", amazonOrderId);
command.ExecuteNonQuery();
If it IS what you want, then why not use between or greater than?
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId > #OrderId;";
command.Parameters.AddWithValue("#orderID", int.Parse(amazonOrderId.ToString() + "0"));
command.ExecuteNonQuery();
Probably you need to use parameters
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId like #orderID";
command.Parameters.AddWithValue("#orderID", amazonOrderId + "%");
command.ExecuteNonQuery();
This will avoid errors when the parameter value is a string and contains single quotes and prevent SqlInjection attacks.
The code above assumes that amazonOrderID field on the database is a text datatype and amazonOrderID variable is of string type.
However, the error message says that it doesn't recognize the input string.
This leads to the real problem. What kind of column is amazonOrderID in the database table?
It's varchar (or other text type)? or is a numeric datatype?.
If it is a text type then the syntax with like and parameters should work provided that the amazonOrderID var in code is also a string.
If the column is of a numeric datatype then the LIKE has no sense and you should change the query using = operator and also be sure that the amazonOrderID var is of numeric type.
MySqlCommand command = new MySqlCommand();
command.Connection = conn;
command.CommandText = "update fulfilled_shipments_data set addedCustomer=1 where amazonOrderId = #orderID";
command.Parameters.AddWithValue("#orderID", amazonOrderId);
command.ExecuteNonQuery();
My resolution was actually found in another piece of code. After running through the debugger several times it became apparent that a MySqlConnection object was trying to be instantiated twice - with the same name etc. I removed the second instantiation and it has resolved the issue. It's too bad the error was misleading.

Categories

Resources