Return SUM SQL Statement, C#, NULL - c#

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.

Related

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

ExecuteScalar if DBNull issue

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

Return value from SQLCommand

I have this SqlCommand, but i dont know, how i give the return value?
string param = Request.QueryString["id"];
System.Data.SqlClient.SqlConnection se = new System.Data.SqlClient.SqlConnection(GetConnectionString());
{
System.Data.SqlClient.SqlCommand cme;
se.Open();
cme = new System.Data.SqlClient.SqlCommand("select Sum(case when (Domaci_tym = 'Tupesy') then Domaci_branky else Hoste_branky end) from Zapas AS branky where (ID_zapas=#ID_zapas)", se);
cme.Parameters.AddWithValue("#ID_zapas", param);
cme.ExecuteNonQuery();
se.Close();
Change this line cme.ExecuteNonQuery(); to:
double sum = 0d;
var result = cme.ExecuteScalar(); //returns object that needs casting to get proper value
if (result != null && double.TryParse(result.ToString(), out sum))
{
//query returned valid sum
}
More info about that method here

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