This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I'm trying to run a query in MySQL database with C#. I want the column prioritySettings returned when the 3 previous columns are within certain values. This query works, but only with one variable at a time, so at the moment I can only specify the value of one of the columns. Are my AND statements correct?
string query = "SELECT prioritySetting FROM {DATABASE} WHERE handling ='" + handling + "'" + "AND corner ='" + corner + "'" + "AND power ='" + power + "'";
some more code;
MySqlDataReader sqlReader;
string handling = overOrUnderInput;
string corner = cornerPartInput;
string power = onOrOffPowerInput;
string query = "SELECT prioritySetting FROM {DATABASE} WHERE handling ='" + handling + "'" + " AND corner ='" + corner + "'" + " AND power ='" + power + "'";
MySqlCommand getRecords = new MySqlCommand(query, connection);
connection.Open();
sqlReader = getRecords.ExecuteReader();
while (sqlReader.Read())
{
try
{
try
{
suggestions[i] = (sqlReader.GetString(0));
}
catch
{
}
i++;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
and the error;
System.NullReferenceException: Object reference was not set to an instance of an object.
Seem like a space is required before each AND.
Add a space before each AND
string query = "SELECT prioritySetting FROM {DATABASE} WHERE handling ='" + handling + "'" + " AND corner ='" + corner + "'" + " AND power ='" + power + "'";
Let's see how your query looks if the parameters are inserted. I assume parameters have values equal to their names.
SELECT prioritySetting
FROM {DATABASE}
WHERE handling ='handling'AND corner ='corner'AND power ='power'
If it's really DATABASE after the FROM you should change it to TABLE. I'm not very sure if it causes any problems, but I strongly recommend putting spaces before ANDs. So your code line will be like:
string query = "SELECT prioritySetting FROM {DATABASE.TABLE} WHERE handling ='" + handling + "'" + " AND corner ='" + corner + "'" + " AND power ='" + power + "'";
string query = "SELECT prioritySetting FROM {TABLE}
WHERE handling ='" + handling + "'" + "
AND corner ='" + corner + "'" + "
AND power ='" + power + "'";
Related
This question already has answers here:
SQL update statement in C#
(10 answers)
Closed 5 years ago.
enter image description here
I am trying to update data in a SQL Server table. I get a message that data is saved, after a query execution.
But when I check in that table, I find that the data is not saved. Is anything wrong in my query?
I am using SQL Server 2008 and C# for coding.
SqlCommand cmd1 = new SqlCommand("UPDATE Inward_Rpt SET Date='" + date + "',Cashier_Name='" + cashier_name + "',Supplier_Code='" + sup_code + "',Supplier_Name='" + name + "',Payment_Mode ='" + p_method + "',Total_Bill='" + tot_bill + "',Total_Paid='" + tot_paid + "',Previous_Due = '" + total_due + "',Current_Due ='" + c_due + "',Remark ='" + remark + "'WHERE Supplier_Name='" + name + "'", con);
cmd1.ExecuteNonQuery();
MessageBox.Show("Data Saved..");
I think I found your error. Your WHERE clause is using the same name that you are updating the Supplier Name to. Assuming this is a new name, you will never find the record you want to update. The below code is cleaner, not prone to injection issues, and it should work the way you want.
Note that you will have to provide a new variable to cater to the name / sup_name situation.
SqlCommand cmd1 = new SqlCommand();
cmd1.Connection = con;
cmd1.CommandText = #"
UPDATE Inward_Rpt
SET Date = #date
, Cashier_Name = #cashier_name
, Supplier_Code = #sup_code
, Supplier_Name = #sup_name
, Payment_Mode = #p_method
, Total_Bill = #tot_bill
, Total_Paid = #tot_paid
, Previous_Due #total_due
, Current_Due = #c_due
, Remark = #remark
WHERE Supplier_Name = #name";
cmd1.Parameters.AddWithValue("#date", date);
cmd1.Parameters.AddWithValue("#cashier_name", cashier_name);
cmd1.Parameters.AddWithValue("#sup_code", sup_code);
cmd1.Parameters.AddWithValue("#sup_name", sup_name);
cmd1.Parameters.AddWithValue("#p_method", p_method);
cmd1.Parameters.AddWithValue("#tot_bill", tot_bill_name);
cmd1.Parameters.AddWithValue("#tot_paid", tot_paid);
cmd1.Parameters.AddWithValue("#total_due", total_due);
cmd1.Parameters.AddWithValue("#c_due", c_due);
cmd1.Parameters.AddWithValue("#remark", remark);
cmd1.Parameters.AddWithValue("#name", name);
cmd1.ExecuteNonQuery();
MessageBox.Show("Data Saved..");
Is the All the Fields are String Datatype in your Database Table? Check the Datatypes Because u give Single Quotes for all Data. If the Table Datatype is Number Remove the Single Quotes.
SqlCommand cmd1 = new SqlCommand("UPDATE Inward_Rpt SET Date='" + date + "',Cashier_Name='" + cashier_name + "',Supplier_Code=" + sup_code + ",Supplier_Name='" + name + "',Payment_Mode ='" + p_method + "',Total_Bill='" + tot_bill + "',Total_Paid='" + tot_paid + "',Previous_Due = '" + total_due + "',Current_Due ='" + c_due + "',Remark ='" + remark + "'WHERE Supplier_Name='" + name + "'", con);
I am currently reading and parsing 10 different file(.txt, .csv), each file has a different number of columns.
Here is a sample from one file:
SqlCommand cmd = new SqlCommand("insert into " + table_name + " VALUES('"+data_from_file[0]+"', '" + data_from_file[1] + "', '" + data_from_file[2] + "', '" + data_from_file[3] + "', '" + data_from_file[4] + "','" + data_from_file[5] + "', '" + data_from_file[6] + "', '" + data_from_file[7] + "', '" + data_from_file[8] + "', '" + data_from_file[9] + "');", connection);
cmd.ExecuteNonQuery();
This file has a total of 10 columns that gets inserted into its own table. If I do it like this for the 10 files, I would have 10 different if/else if statements. And to me that sounds like bad way of doing this. Is there a way to iterate through the array and insert each element? I have been looking for ways to do it, but cannot find a proper solution for my problem. Thanks for the help.
The most classical way would be to iterate and append to a string and then execute:
string command = "insert into " + table_name + " VALUES(";
foreach(string data in data_from_file)
{
command += "'" + data + "',";
}
command = command.TrimEnd(','); // remove the last extra ','
command += ");";
SqlCommand cmd = new SqlCommand(command);
cmd.ExecuteNonQuery();
However, I recommend that you have a look at SqlBulkCopy for Large Insert Queries.
First you iterate over your collection, and then you insert every entry from the collection into the database.
foreach (var oneColumn in data)
{
SqlCommand cmd = new SqlCommand("INSERT INTO " + table_name + " VALUES(" + oneColumn + ")");
cmd.ExecuteNonQuery();
}
I am new to C# and SQL. Now from a form I access a function in a class.
My code is
public void updateSupplierInformation(string id, string name, string balance, string place, string address, string phone, string bankname, string bankbranch, string accountno)
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
SqlCommand NewCmd = conn.CreateCommand();
NewCmd.Connection = conn;
NewCmd.CommandType = CommandType.Text;
NewCmd.CommandText = " update supplier set " + " ID = " + "'" + id + "'" + " , NAME = " + "'" + name + "'" + " , BALANCE = " + "'" + balance + "'" + " , PLACE = " + "'" + place + "'" + " , LOCATION = " + "'" + address + "'" + ", PHONE = " + "'" + phone + "'" + " , BANK_NAME = " + "'" + bankname + "'" + " , BANK_BRANCH = " + "'" + bankbranch + "'" + ", ACCOUNT_NO = " + "'" + accountno + "'" + " where ID = " + "#id";
NewCmd.Parameters.AddWithValue("#id",id);
NewCmd.ExecuteNonQuery();
conn.Close();
}
Now if a record doesn't exist in the database with the given id the application stops immediately. How can I handle this? I want to show a message that the data entered is wrong and ask the user to enter another data
ExecuteNonQuery() returns number of rows affected by an INSERT, UPDATE or DELETE statement.If you need to check sql exception you have to include a try catch statement in your function.
public void updateSupplierInformation(string id, string name, string balance, string place, string address, string phone, string bankname, string bankbranch, string accountno)
{
try
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
SqlCommand NewCmd = conn.CreateCommand();
NewCmd.Connection = conn;
NewCmd.CommandType = CommandType.Text;
NewCmd.CommandText = " update supplier set " + " ID = " + "'" + id + "'" + " , NAME = " + "'" + name + "'" + " , BALANCE = " + "'" + balance + "'" + " , PLACE = " + "'" + place + "'" + " , LOCATION = " + "'" + address + "'" + ", PHONE = " + "'" + phone + "'" + " , BANK_NAME = " + "'" + bankname + "'" + " , BANK_BRANCH = " + "'" + bankbranch + "'" + ", ACCOUNT_NO = " + "'" + accountno + "'" + " where ID = " + "#id";
NewCmd.Parameters.AddWithValue("#id",id);
int a=NewCmd.ExecuteNonQuery();
conn.Close();
if(a==0)
//Not updated.
else
//Updated.
}
catch(Exception ex)
{
// Not updated
}
}
ExecuteNonQuery returns the number of rows affected - if it's 0, that means there were no matching rows to update. Of course, that's only if the update actually "works" in terms of not throwing an exception... whereas I suspect it's throwing an exception in your case, which probably isn't to do with the row not existing in the database. (It's possible that there's some code you haven't shown which does depend on the row existing, mind you.)
Additionally:
You should use parameterized SQL for all parameters rather than including the values directly in your SQL.
You should use using statements to dispose of resources reliably.
It looks like you're using a single connection - don't do that. Create (and dispose via using) a new connection each time you want to perform a database operation, and let the connection pool handle the efficiency
Work out why the application is just stopping. An exception is almost certainly being thrown, and it's really important that when that happens, you get the details of the exception. You may want to catch it and keep going (at some high level) depending on the exact context... but you should always at least end up logging it.
My guess (on a casual inspection) is that the problem is that your update statement tries to update the ID, which would presumably be read-only. But you'll find that out when you fix your exception handling.
Simply check the condition
int a=NewCmd.ExecuteNonQuery();
if(a==0)
//Not updated.
else
//Updated.
ExecuteNonQuery() -> This function return integer value.
Thank you
I know that there is already an answer posted but let`s try something else:
SqlConnection SQLConn = new SqlConnection("datahere");
SqlCommand SQLComm = new SqlCommand();
SQLcomm.Connection = SQLConn;
SQLConn.Open();
SQLComm.CommandText = "SQL statement goes here"
SqlDataReader dataReader = SQLComm.ExecuteReader();
dataReader.Read();
if(dataReader.HasRows == true){ //if it has rows do code
//do code
}
else{
// do other code
}
HasRows will return a bool value
let sql = UPDATE TABLE SET column = '${data}' WHERE column = "value
db.query(sql, (err, result)=> {
console.log(result.affectedRows);
if(err) {
console.log(err);
return res.send({
message: "Error occured. please retry",
});
} else if(result.affectedRows != 0) {
console.log(result)
return res.send({
success:true,
message: "updated!"
});
}else if(result.affectedRows == 0) {
console.log(result)
return res.send({
success:false,
message: "not updated!"
});
} else {
console.log(result)
}
})
//this is a nodejs code
I realize IDataReader is outdated and some view it as dirty code, but on the site I am working on this is what they use. I have an IDataReader statement to run a query to get a specific id from a table using multiple joins. Now this site has a DAL but it only supports the ability to select from one table at a time, so using select statements with joins do not work with it. This is why I am forced to use IDataReader with this.
if (Request.QueryString["CategoryId"].ToString() == "0")
{
using (IDataReader getCategoryID = DB.GetRS("SELECT ItemCatalogCategory.CategoryID FROM UserCustomerCatalog INNER JOIN ItemCatalogCategory ON UserCustomerCatalog.ItemProfileCatalogID = ItemCatalogCategory.ItemProfileCatalogID " +
"INNER JOIN ItemCategory ON ItemCatalogCategory.CategoryID = ItemCategory.CategoryID INNER JOIN StoreCatalog ON UserCustomerCatalog.StoreCatalogID = StoreCatalog.StoreCatalogID " +
"WHERE UserCustomerCatalog.ItemProfileCatalogID = '" + Request.QueryString["CatalogID"] + "' AND UserCustomerCatalog.CustomerID =' " + Session["Customer"].ToString() + "' AND ItemCategory.ProductID = '" + productis + "'"))
{
if (getCategoryID.Read())
{
string categoryID = getCategoryID["ItemCatalogCategory.CategoryID"].ToString();
string lookmike = Request.Url.AbsolutePath + "?CatalogID=" + catalogis + "&ProductID=" + productis + "&CatalogIndex=" + Request.QueryString["CatalogIndex"] + "&CategoryID=" + categoryID;
Response.Redirect(Request.Url.AbsolutePath + "?CatalogID=" + catalogis + "&ProductID=" + productis + "&CatalogIndex=" + Request.QueryString["CatalogIndex"] + "&CategoryID=" + categoryID);
}
else
{
Response.Redirect(Request.Url.AbsolutePath + "?CatalogID=" + catalogis + "&ProductID=" + productis + "&CatalogIndex=" + Request.QueryString["CatalogIndex"] + "&CategoryID=" + Request.QueryString["CategoryId"]);
}
}//end using getCategoryID
}
this is what I have, but when it gets to:
if (getCategoryID.Read())
it renders as false, there are no exceptions thrown, and no errors or warnings. I have done this type of select in the past with no problems, but I cannot figure out why .Read() is returning false.
Can anyone suggest possible reasons for it not reading? If more code is needed, I can provide as needed. Any help is appreciated, thank you in advance.
Looking at your SQL text there is a little typo that could wreak havoc with the results
"WHERE UserCustomerCatalog.ItemProfileCatalogID = '" + Request.QueryString["CatalogID"] +
"' AND UserCustomerCatalog.CustomerID =' " + Session["Customer"].ToString() + "' AND ..... "
here ^
That space mangles your query and give no result.
Let me also repeat that you have a problem with SQL Injection as other members have already said. You could add an overload to your actual implementation of GetRS that receive also a SQLParameter collection to add to the command used to build your SqlDataReader. Something like this
public SqlDataReader GetRS(string sqlText, SqlParameter[] prm)
{
....
SqlCommand cmd = new SqlCommand(sqlText, conn);
cmd.Parameters.AddRange(prm);
.....
}
and then start to upate the calling code.
I have a windows service which inserts data into some tables. It does so fine when in debug mode, but when I install it says "Data type mismatch in criteria expression." for every insert.
query = "INSERT INTO printers (" +
"hostname," +
"ip_address," +
"model," +
"picture_id," +
"connect_type," +
"status," +
"product_number," +
"Floor_ID," +
"print_corner," +
"serial_number," +
"printer_features" +
") VALUES ('" +
exp.Devices[i].HostName.ToString() + "', '" +
exp.Devices[i].IpAddress.ToString() + "', '" +
exp.Devices[i].Model.ToString() + "', '" +
exp.Devices[i].PictureId.ToString() + "', '" +
exp.Devices[i].ConnectType.ToString() + "', '" +
exp.Devices[i].Status.ToString() + "', '" +
exp.Devices[i].ProductNumber.ToString() + "', '" +
exp.Devices[i].Floor.ToString() + "', '" +
exp.Devices[i].PrintCorner.ToString() + "', '" +
exp.Devices[i].SerialNumber.ToString() + "', '" +
exp.Devices[i].PrinterFeatures.ToString() +
"')";
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + confParams.MpaSearchDatabase;
OleDbConnection conn = new OleDbConnection(connectionString);
OleDbCommand myCommand = new OleDbCommand(query);
myCommand.Connection = conn;
conn.Open();
myCommand.ExecuteNonQuery();
conn.Close();
insertedPrintersCount = insertedPrintersCount + 1;
Utils.Logger.Info("Device inserted: " + exp.Devices[i].HostName);
help!
The data type mismatch error indicates the query is expecting data of one type but you're providing another. This query expression is passing every value as a string literal but several columns indicate they are likely a numerical value. ProductNumber and SerialNumber for example.
In order to pass the values correctly (and prevent easy injection attacks) you'll want to use the OleDbCommand class to build up the call with values of the correct type. Then let the underlying infrastructure translate it to the appropriate values.