int value2;
using (SqlConnection dataConnection = new SqlConnection(#"Data Source=MANNAN-PC\SQLEXPRESS;Initial Catalog=WareHouse;Integrated Security=True;"))
using (SqlCommand dataCommand = new SqlCommand("Select Sum(I_Quantity) from Itemswork where I_Detail='" + maskedTextBox2.Text + "' and Order_No ='" + maskedTextBox1.Text + "'", dataConnection))
{
dataConnection.Open();
value2 = Convert.ToInt32(dataCommand.ExecuteScalar());
}
It shows the Error of DBnull because the column from which I'm getting the value is already int. I want to know what is the other way to get that value in variable's value2 definition.
Check the remarks section here:SqlCommand.ExecuteScalar Method
value2 = (Int32)dataCommand.ExecuteScalar();
As #Soner states you should be using parameterized queries to reduce the issues relating to SQL Injection etc. One of the problems you're actually experiencing is that the result being returned is NULL.
The SUM where no columns are returned is not 0, what you could do is change your output to check whether the returned value IsDbNull before trying to parse it into an integer. (See Unable to cast object of type 'System.DBNull' to type 'System.String` - although it's parsing to string the logic is the same)
ExecuteScalar will return
null if there is no result set
otherwise the first column of the first row of the resultset, which may be DBNull.
(Example modified from linked question and not syntax checked)
var tempObject = dataCommand.ExecuteScalar();
value2 = (tempObject == null || Convert.IsDBNull(tempObject) ? (int) tempObject: 0;
Related
I'm trying to create a method that returns a string from my db that fulfills my conditions.
The first condition is working.
But, the second condition is that part of entry in access is empty, at least one field.
This is my code:
OleDbCommand datacommand = new OleDbCommand();
datacommand.Connection = dataConnection;
datacommand.CommandText = "SELECT numNumber, numLocation " +
"FROM tblNumbers " +
"ORDER BY numID ";
OleDbDataReader dataReader = datacommand.ExecuteReader();
while (dataReader.Read())
{
if (MatchServiceLetters(dataReader.GetString(0))) // && dataReader.GetInt32(1) == null?/)
}
return dataReader.GetString(0);
If the int field is empty, the comparison to null isn't working. so how can I know if it is empty?
From MSDN:
No conversions are performed; therefore, the data retrieved must already be a 32-bit signed integer.
Call IsDBNull to look for null values before calling this method.
So you would use:
if(!dataReader.IsDBNull(1))
{
return dataReader.GetInt32(1);
}
else
{
return 0; // or better yet, make your method return Nullable<int>
}
My friend wants to transfer her data from the database to a textbox to her program in c# but it gets an error of this:
"Data is Null. This method or property cannot be called on Null
values."
Here is the code by the way:
sql_command = new MySqlCommand("select sum(lt_min_hours) as TotalLate from tbl_late where (late_date between '" + date_start + "' and '" + date_to + "' and empid = '" + empid + "')", sql_connect);
sql_reader = sql_command.ExecuteReader();
if (sql_reader.Read())
{
textBox_tlate.Text = sql_reader.GetString("TotalLate");
}
else
{
MessageBox.Show("No Data.");
}
From documentation;
SUM() returns NULL if there were no matching rows.
But first of all, You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
After that, you can use ExecuteScalar instead of ExecuteReader which is returns only one column with one row. In your case, this is exactly what you want.
textBox_tlate.Text = sql_command.ExecuteScalar().ToString();
Also use using statement to dispose your connection and command automatically.
You need to test for DbNull.Value against your field before assigning it to the textbox
if (sql_reader.Read())
{
if(!sql_reader.IsDbNull(sql_reader.GetOrdinal("TotalLate")))
textBox_tlate.Text = sql_reader.GetString("TotalLate");
}
EDIT
According to your comment, nothing happens, so the WHERE condition fails to retrieve any record and the result is a NULL.
Looking at your query I suppose that your variables containing dates are converted to a string in an invalid format. This could be fixed using a ToString and a proper format string (IE: yyyy-MM-dd) but the correct way to handle this is through a parameterized query
sql_command = new MySqlCommand(#"select sum(lt_min_hours) as TotalLate
from tbl_late
where (late_date between #init and #end and empid = #id", sql_connect);
sql_command.Parameters.Add("#init", MySqlDbType.Date).Value = date_start;
sql_command.Parameters.Add("#end", MySqlDbType.Date).Value = date_end;
sql_command.Parameters.Add("#id", MySqlDbType.Int32).Value = empid;
sql_reader = sql_command.ExecuteReader();
This assumes that date_start and date_end are DateTime variables and empid is an integer one. In this way, the parsing of the parameters is done by the MySql engine that knows how to handle a DateTime variable. Instead your code uses the automatic conversion made by the Net Framework that, by default, uses your locale settings to convert a date to a string.
I need to perform an update to a View that has multiple underlying tables using the ExecuteCommand method of a DataContext. I am using this method because of the known restriction of linqToSQL when performing this type of operation on Views having multiple underlying tables.
My existing SQL statement is similar to the following where I am setting newFieldID to a null value simply for this post to illustrate the issue. In the application, newFieldID is assigned a passed parameter and could actually be an integer value; but my question is specific to the case where the value being provided is a null type:
using (var _ctx = new MyDataContext())
{
int? newFieldID = null;
var updateCmd = "UPDATE [SomeTable] SET fieldID = " + newFieldID + "
WHERE keyID = " + someKeyID;
try
{
_ctx.ExecuteCommand(updateCmd);
_ctx.SubmitChanges();
}
catch (Exception exc)
{
// Handle the error...
}
}
This code will fail for the obvious reason that the updateCmd won't be completed in the case of a null value for the newFieldID. So how can I replace or translate the CLR null value with an SQL null to complete the statement?
I know I could move all of this to a Stored Procedure but I am looking for an answer to the existing scenario. I've tried experimenting with DBNull.Value but aside from the challenge of substituting it for the newFieldID to use in the statement, simply placing it into the string breaks the validity of the statement.
Also, enclosing it within a single quotes:
var updateCmd = "UPDATE [SomeTable] SET fieldID = '" + DBNull.Value + "'
WHERE keyID = " + someKeyID;
Will complete the statement but the value of the field is translated to an integer 0 instead of an SQL null.
So How does one go about converting a CLR null or nullable int to an SQL Null value given this situation?
Correct way to do it: use override of ExecuteCommand accepting not only command text, but also array of parameters and use parameterized query instead of command string concatenation:
var updateCmd = "UPDATE [SomeTable] SET fieldID = {0} WHERE keyID = {1}";
_ctx.ExecuteCommand(updateCmd, new [] {newFieldID, someKeyID});
It will not only prevent you from sql injection, but also it will do following for you (from MSDN description):
If any one of the parameters is null, it is converted to DBNull.Value.
Try checking newFieldID == null and change the statement accordingly.
Something like below or using separate if / else statement.
var updateCmd = "UPDATE [SomeTable] SET fieldID =" + (newFieldID == null ? "null" : Convert.ToString(newFieldID)) + " WHERE keyID = " + someKeyID;
Normally, when using Stored Procedures or Prepared Statements, you use Parameters to assign values. When you have a DbParameter, you can assign null or DBNull.Value to the Value-Property or your parameter.
If you want to have the null as text in the statement, simply use the SQL-keyword NULL
var updateCmd = "UPDATE [SomeTable] SET fieldID = NULL WHERE keyID = " + someKeyID;
As pointed out by Andy Korneyev and others, a parameterized array approach is the best and probably the more appropriate method when using Prepared statements. Since I am using LinqToSQL, the ExecuteCommand method with the second argument which takes an array of parameters would be advised but it has the following caveats to its usage.
A query parameter cannot be of type System.Nullable`1[System.Int32][] (The main issue I'm trying to resolve in this case)
All parameters must be of the same type
Shankar's answer works although it can quickly become very verbose as the number of parameters could potentially increase.
So my workaround for the problem involve somewhat of a hybrid between the use of parameters as recommended by Andy and Shankar's suggestion by creating a helper method to handle the null values which would take an SQL statement with parameter mappings and the actual parameters.
My helper method is:
private static string PrepareExecuteCommand (string sqlParameterizedCommand, object [] parameterArray)
{
int arrayIndex = 0;
foreach (var obj in parameterArray)
{
if (obj == null || Convert.IsDBNull(obj))
{
sqlParameterizedCommand = sqlParameterizedCommand.Replace("{" + arrayIndex + "}", "NULL");
}
else
sqlParameterizedCommand = sqlParameterizedCommand.Replace("{" + arrayIndex + "}", obj.ToString());
++arrayIndex;
}
return sqlParameterizedCommand;
}
So I can now execute my statement with parameters having potential null values like this:
int? newFieldID = null;
int someKeyID = 12;
var paramCmd = "UPDATE [SomeTable] SET fieldID = {0} WHERE keyID = {1}";
var newCmd = PrepareExecuteCommand(paramCmd, new object[] { newFieldID });
_ctx.ExecuteCommand(newCmd);
_ctx.SubmitChanges();
This alleviates the two previously referenced limitations of the ExecuteCommand with a parameter array. Null values get translated appropriately and the object array may varied .NET types.
I am marking Shankar's proposal as the answer since it sparked this idea but posting my solution because I think it adds a bit more flexibility.
Hello I'm trying to select SUM of all payments but got this exception: nvl is not a recognized function name
with this code:
SqlCommand sc2 = new SqlCommand("SELECT SUM(NVL(payments,0)) AS sumcastka FROM kliplat WHERE akce=" + zakce.Text, spojeni);
spojeni.Open();
int sumOfPrice = 0;
object vysledek2 = sc2.ExecuteScalar();
if (vysledek2 != DBNull.Value)
sumOfPrice = Convert.ToInt32(vysledek2);
// int vysledek2 = Convert.ToInt32(sc2.ExecuteScalar());
spojeni.Close();
This should work as when no records are found for column "payments" I would like to get "0" if possible.
Thank you for reading this.
NVL() is an oracle-specific function. You can use the ANSI COALSECE function to perform the same task. The benefit of COALESCE is that it takes more than two parameters, and picks the first non-null value.
This should work as when no records are found for column "payments"
No, it will only treat NULL values in the payments column as 0.
If no records are found, then ExecuteScalar returns null (not DBNull):
SqlCommand sc2 = new SqlCommand("SELECT SUM(ISNULL(payments,0)) AS sumcastka FROM kliplat WHERE akce=" + zakce.Text, spojeni);
spojeni.Open();
int sumOfPrice = 0;
object vysledek2 = sc2.ExecuteScalar();
if (vysledek2 != null && vysledek2 != DBNull.Value)
sumOfPrice = Convert.ToInt32(vysledek2);
spojeni.Close();
You should also look into using SqlParameters instead of concatenating strings, but that's a separate issue.
In SQL server there is a funcation called ISNULL for the purpose. Please find the query below:
SELECT SUM(ISNULL(payments,0)) AS sumcastka FROM kliplat WHERE akce=" + zakce.Text, spojeni
I want to update a row by code in my form. Maybe some columns are null. So while command is
executing, an error will rise and say Incorrect syntax near the keyword 'where':
SqlCommand Update = new SqlCommand("Update Table_065_Turn SET Column02=" + Row["Column48"] + " , Column15= " + Row["Column15"].ToString() +
" where ColumnId=" + StatusTable.Rows[0]["ColumnId"], Con);
Update.ExecuteNonQuery();
I know this error will be displayed because Row["Column15"] is null.
How can I check if the column in datarow is null; of course without any extra variable or commands before Update command.
I mean check columns exactly in update command.
I would recommend using SqlParameters, also SqlCommand implements IDisposable so you should wrap it up in a using statement e.g.
using (SqlCommand update = new SqlCommand("Update Table_065_Turn SET Column02=#Col2, Column15=#Col15 where ColumnId=#ColId", con))
{
update.Parameters.AddWithValue("#Col2", Row["Column48"]);
update.Parameters.AddWithValue("#Col15", Row["Column15"]);
update.Parameters.AddWithValue("#ColId", StatusTable.Rows[0]["ColumnId"]);
update.ExecuteNonQuery();
}
Also you might be better actually validating the fields before you execute the query unless null is a valid column value.
I suspect you have to "replace" .net null with database keyword NULL, e.g.
string sql = "Column15 = " + (row[15] == null ? "NULL" : row[15].ToString()) in your case, but the much better way is to use Parameters as written by James, also keep in mind someone could provide hamful strings to your query:
row[15] = ";DROP DATABASE; --" would be enough in your case to cause all your data to be lost ;) (see "SQL injection" on your favorite search engine
you could use
var value = "" + Row["columnname"] ;
so ,you do not need to check the object is null
it is safe..
You could do like this:
string filterString;
if (StatusTable.Rows[0]["ColumnId"]!=System.DBNull.Value)
filterString= #" WHERE ColumnID= StatusTable.Rows[0]["ColumnId"]";//I assume the value returned is a string
else
filterString="";
And then you can just append the filterString variable to your SQLCommand string.