ExecuteScalar if DBNull issue - c#

I was trying to handle DbNull exception like this:
string sql_com_sumcastka = "SELECT SUM(price) AS sumprice FROM kliplat WHERE akce='" + zakce.Text + "' AND year=" + year;
SqlCommand sc2 = new SqlCommand(sql_com_sumprice, spojeni);
spojeni.Open();
if (sc2 != DBNull.Value)
{
int result = Convert.ToInt32(sc2.ExecuteScalar());
}
else
{
int result = 0;
}
spojeni.Close();
string sql_com_update_sum = "UPDATE zajezd SET s_prijmy=#s_prijmy WHERE akce='"+zakce.Text+"' AND year="+year;
SqlCommand sc3 = new SqlCommand(sql_com_update_sum,spojeni);
sc3.Parameters.AddWithValue("#s_prijmy", result );
spojeni.Open();
sc3.ExecuteNonQuery();
spojeni.Close();
But as I don't know how to properly handle if result is DBNull I get this erros: Operator '"=' cannot be applied to operands of type system.Data.SqlClient.SqlCommand and System.Dbnull
and
The name 'result' does not exist in the current context
My problem is this line of code:
if (sc2 != DBNull.Value)
{
int result = Convert.ToInt32(sc2.ExecuteScalar());
}
else
{
int result = 0;
}
Thanks for helping.

ExecuteScalar doesn't return DBNull (unless..., please read comments below) but null and you need to test the return value of ExecuteScalar not the SqlCommand that executes the command
int sumOfPrice = 0;
object result = sc2.ExecuteScalar();
if(result != null)
sumOfPrice = Convert.ToInt32(result);
From MSDN
ExecuteScalar returns the first column of the first row in the result
set, or a null reference (Nothing in Visual Basic) if the result set
is empty.
As a side note, do not use string concatenation to build a command text to pass to your database. You risk Sql Injection and parsing erroros. Use instead a parameterized query like this
string sql_com_sumcastka = "SELECT SUM(price) AS sumprice FROM kliplat " +
"WHERE akce=#zak AND year=#year";
SqlCommand sc2 = new SqlCommand(sql_com_sumprice, spojeni);
sc2.Parameters.AddWithValue("#zak", zakce.Text);
sc2.Parameters.AddWithValue("#year", year);

Here is the correct way to do that
var objResult = sc2.ExecuteScalar();
if (objResult != DBNull.Value && objResult != null )
{
int result = (int)objResult; //you can just do a normal cast, "SUM(X)" returns a int.
}
else
{
int result = 0;
}

A SqlCommand can never be compared to DBNull.Value in your example. What it sounds like you want is to check the result of your execute scalar invocation to see if that is null:
var result = sc2.ExecuteScalar();
if(result as DBNull == null)
{
// value is not null, do processing
}

I know the answer is late but this is the simplest answer that I have found
SELECT (SUM(price),0) FROM kliplat
If the result is null it will be replaced with 0

Related

Return SUM SQL Statement, C#, NULL

If the query returns null the goal is to get it to return 0, else return the number. The SUM statement returns the sum of the column values in column ConcurrentUsers.
The code below returns a casting error:
Specified cast is not valid.
It could be because the query is returning a null and is having trouble converting it to int.
Below is the attempt.
Please edit question if anything should be clarified.
SQL query:
string query = #"SELECT SUM(CAST(ConcurrentUsers AS INT))
FROM [website].[db]
WHERE(ConcurrencyLicensing NOT LIKE 0)";
Return value:
SqlConnection conn = new SqlConnection(entityBuilder.ProviderConnectionString);
SqlCommand cmd = new SqlCommand(query, conn);
try
{
conn.Open();
object userNameObj = cmd.ExecuteScalar();
if(userNameObj != null)
{
int getUserName = (int)userNameObj;
return getUserName;
}
else
{
return 0;
}
}
finally
{
conn.Close();
}
Did you try COALESCE ?
string query = #"SELECT COALESCE(SUM(CAST(ConcurrentUsers AS INT)), 0) FROM [website].[db]
WHERE(ConcurrencyLicensing NOT LIKE 0)";
https://msdn.microsoft.com/en-us/library/ms190349.aspx
Evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL.

Check for the existence of a record in Access database using C#

First, I did search for this first and found this question answered: Previous Answer
The problem I have with this answer is that using this method causes a NullReferenceException. Obviously the code will still work with a try/catch block, but I had always understood that intentionally using an Exception as a means of controlling flow was poor design. Is there a better method of doing this?
To be clear as to the parameters, I am using OleDbConnection and OleDbCommand to read/write an Access 2010 database (.accdb format).
Below is the code I have currently using the above answer's approach:
public bool ReadAccessDb(string filePath, string queryString, bool hasRecords)
{
string connectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data Source=" + filePath + ";" +
#"User Id=;Password=;";
using (OleDbConnection connection = new OleDbConnection(connectionString))
using (OleDbCommand command = new OleDbCommand(queryString, connection))
{
try
{
connection.Open();
int count = (int)command.ExecuteScalar();
//This works, but if no records exist it uses the Exception system to halt further action. Look for better approach.
if(count > 0)
{
hasRecords = true;
}
}
catch (System.Exception ex)
{
}
}
return hasRecords;
}
You can use :
int count = command.ExecuteScalar() is DBNull ? 0 : Convert.ToInt32(command.ExecuteScalar());
or use :
object obj = command.ExecuteScalar();
int count = obj is DBNull ? 0 : Convert.ToInt32(obj);
I'm posting this answer because the question is a bit ambiguous and the (currently) accepted answer can conceivably be "fooled" if a row exists but the first column returned by the SELECT statement happens to contain a NULL. Consider the test table
CREATE TABLE MyTable (ID COUNTER PRIMARY KEY, NullableColumn INTEGER NULL)
INSERT INTO MyTable (NullableColumn) VALUES (NULL)
which would look like
ID NullableColumn
-- --------------
1 <NULL>
If the SELECT statement used for testing was
string sql = "SELECT NullableColumn FROM MyTable WHERE ID=1";
then the method
static bool RecordExists(string queryString, OleDbConnection conn)
{
bool rtn;
using (var command = new OleDbCommand(queryString, conn))
{
object obj = command.ExecuteScalar();
int count = obj is DBNull ? 0 : Convert.ToInt32(obj);
rtn = (count != 0);
}
return rtn;
}
would return False, whereas this method
static bool RecordExists(string queryString, OleDbConnection conn)
{
bool rtn;
string rowCountString = String.Format("SELECT COUNT(*) AS n FROM ({0})", queryString);
using (var command = new OleDbCommand(rowCountString, conn))
{
int count = (int)command.ExecuteScalar();
rtn = (count != 0);
}
return rtn;
}
would return True.

C# and SQL Server 2008 : how to handle null from database

I am selecting max(id) from database which are grouped by date. Sometimes there might be situation where date does not have any id. That time it rising error so how to handle it n assign to int variable.
SqlCommand maxid = new SqlCommand("select max(block) from blocks_allocation where date='" + DR.ItemArray.GetValue(7).ToString() + "'", con);
SqlDataReader maxrd = maxid.ExecuteReader();
if (maxrd.Read())
block_no = int.Parse(maxrd["block"].ToString()) + 1;
maxrd.Close();
SqlCommand returns DBNull.Value if the value is null, so if you have a query that could return null values you need to test against DBNull.Value first, like this:
var date = DR.ItemArray.GetValue(7).ToString();
const string sql = "SELECT MAX(block) FROM blocks_allocation WHERE date = #date";
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddWithValue("#date", date);
var maxBlock = cmd.ExecuteScalar();
block_no = maxBlock == DBNull.Value ? null : (int?) maxBlock;
}
(This assumes that block_no is a nullable int). I've also changed a few other things:
If q query returns a single value you can use ExecuteScalar instead of Read etc...
You should use using blocks instead of manually closing / disposing of objects.
You shouldn't build dynamic SQL as it can lead to SQL Injection - I've modified the query to use a parametrized query instead.
I've used the inline-if syntax to set block_no, but you can also use a standard if should you prefer:
if (maxBlock == DBNull.Value)
{
block_no = null;
}
else
{
block_no = (int?) maxBlock;
}
Check whether the max(id) is null, if it so then return 1 using ISNULL()
select isnull(max(block),1) from blocks_allocation

SqlCommand result - Object cannot be cast from dbnull to other types

I have got this SqlCommand that Sum all payments for client, but the issue is where there are no payments the result is null or 0 - I'm not sure. But I still receive the same exception: Object cannot be cast from dbnull to other types
What Exception or if statement can fix it?
private void select_payments()
{
try
{
SqlCommand sc = new SqlCommand("SELECT SUM(payment) AS sumpayment FROM clientpayments WHERE subkey='" + selectid + "' AND year='" + selectedyear+ "'", con);
con.Open();
int result = Convert.ToInt32(sc.ExecuteScalar());
con.Close();
if (result != 0)
{
Convert.ToDecimal(textBox20.Text = result .ToString().Replace(',', '.'));
}
}
catch (Exception ex)
{
MessageBox.Show(" " + ex.Message.ToString());
}
}
I'm still receiving this exception:
object cannot be cast from dbnull to other types
I know that this is low-quality question but I'm not sure how can I fix this.
Thank you for your time and answers.
You have two options. Fix your SQL Statement, or your Convert.
SQL - Wrap your SUM in an ISNULL:
SELECT ISNULL(SUM(payment), 0)
Convert - Compare it to DBNull.Value first:
var result = sc.ExecuteScalar();
int intResult = result == DBNull.Value ? 0 : Convert.ToInt32(result);
object o = sc.ExecuteScalar();
con.Close();
if (o != null)
{
int result = (int) o;
if(result != 0) Convert.ToDecimal(textBox20.Text = result .ToString().Replace(',', '.'));
}

Error when receiving null from database

When i execute this command on my database i receive sometimes result=null. i want to enter the "else" part when is this happening, but i receive
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll.
Additional information: Input string was not in a correct format.
DB database = new DB();
int reservedSeats = 0;
using (database.sqlConnection)
{
database.sqlConnection.Open();
string command = "select SUM(nrLocuri) as result from Rezervari where idRand = #idRand and idShow=#idShow";
using (SqlCommand cmd = new SqlCommand(command, database.sqlConnection))
{
cmd.Parameters.Add("#idRand", SqlDbType.Int).Value = idRand;
cmd.Parameters.Add("#idShow", SqlDbType.Int).Value = idShow;
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
if (dr["result"].ToString() != null)
reservedSeats = Convert.ToInt32(dr["result"].ToString());
else
return totalSeats;
}
}
}
return totalSeats-reservedSeats;
Instead of:
if (dr["result"].ToString() != null)
Do:
if (dr["result"] != DbNull.Value)
When the dr["result"] returns a database null, its value is DbNull.Value - when you try to call Convert.ToInt32 on this value, you get a format exception.
try:
if(!dr.IsDBNull(i)){ //replace i with the column id
//get the data
}
If you want SUM() to return 0.00 in the event no records were found, replace it with:
COALESCE(SUM(...), 0.00)
COALESCE will return the first non-null value passed to it.
try isnull:
string command = "select isnull(SUM(nrLocuri),0.00 )as result from Rezervari where idRand = #idRand and idShow=#idShow";

Categories