query = "SELECT MAX([Date]) FROM [Events]";
DataTable dt = execute(query);
DateTime date;
if (dt!= null && dt.Rows.Count != 0)
{
date = (DateTime) dt.Rows[0][0];
}
else
{
date = DateTime.Now;
}
now what is my question, when the table Events is empty, it returns me some invalid value, which is not even null...how can i write a normal validation for it?
The value is probably DBNull.Value, you could check for that, but out of the box, you could adapt the query (Assuming sql server): SELECT isnull(MAX([Date]),getdate()) FROM [Events]
That way, the value returned is always a valid datetime and the check can be omitted
SqlCommand cmd=new SqlCommand("SELECT MAX([Date]) FROM [Events]",ConnectionObject);
int _value = cmd.ExecuteScalar();
while(_value!=0)
{
//do something
_value--;
}
Related
How do I compare a SQL Server DATETIME with the DateTime.Now value? As you can see I assigned it to a Session and tried comparing it with DateTime.Now.
string timestamp = #"SELECT sr.*, ud.* FROM SuspensionRecord sr, UserData ud WHERE sr.User_ID=#User_ID AND ud.User_ID=#User_ID";
using (SqlCommand cmd2 = new SqlCommand(timestamp, con))
{
cmd2.Parameters.AddWithValue("#User_ID", Session["UserID"].ToString());
using (SqlDataReader dr = cmd2.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
Session["suspensiondate"] = dr["End_Date_Suspension"].ToString();
}
if (Convert.ToDateTime(Session["supensiondate"]) >= DateTime.Now.Date)
{
lblMessage.Text = "The account's status is suspended.";
lblMessage.Visible = true;
}
}
}
}
You should pass in the date and do the comparison in the query instead of in c#. That is one less step. If you do want to do it in c# then use the appropriate types, do not convert the DateTime to a string and then convert it back again.
There is no need for the join (2nd table) in your query
You do not have to use a DataReader for this, you can use ExecuteScalar which returns 1 value instead.
Use Add so you can specify the correct schema types with SqlDbType and not AddWithValue
string timestamp = #"SELECT 1 FROM SuspensionRecord sr WHERE sr.User_ID = #User_ID AND supensiondate > #now";
using (SqlCommand cmd2 = new SqlCommand(timestamp, con))
{
cmd2.Parameters.Add("#User_ID", SqlDbType.Int).Value = Session["UserID"]; // do not convert to string
cmd2.Parameters.Add("#now", SqlDbType.DateTime).Value = DateTime.Now.Date;
var result = cmd2.ExecuteScalar();
if(result != null) // if null then there were no records so account is not suspended
{
lblMessage.Text = "The account's status is suspended.";
lblMessage.Visible = true;
}
}
First, your SQL is terrible.
You are returning way too much data, and you are using an implicit join (when explicit joins are a part of ANSI-SQL for almost 30 years now!)
Second, Can we stop using AddWithValue() already?
Instead of all this code you can do the entire test on SQL and return a single value:
string sql =
#"SELECT CASE WHEN EXISTS
(
SELECT 1
FROM SuspensionRecord
WHERE User_ID = #User_ID
AND End_Date_Suspension >= CAST(GETDATE() AS DATE)
) THEN 1 ELSE 0 END";
Then you can use ExecuteScalar instead of ExecuteReader, and you don't need to loop through all the irrelevant data:
using (SqlCommand cmd2 = new SqlCommand(timestamp, con))
{
cmd2.Parameters.Add("#User_ID", SqlDbType.Int).Value = Session["UserID"];
if ((int)cmd2.ExecuteScalar() == 1)
{
lblMessage.Text = "The account's status is suspended.";
lblMessage.Visible = true;
}
}
I'm trying to write a method that returns me the sum of a column from entries between two dates. However it keeps returning a DBnull no matter what. I have other similar methods that work when the queries are simpler (no SUM, simple select * where statement). performQuery() is just helper method that returns a filled datatable with the query results.
public static int getBookedQuantity(int shopID, int bikeID, DateTime datetime)
{
string query = "SELECT sum(quantity) as \"quantity\" FROM booking WHERE bikeID=#bikeID AND shopID = #shopID AND starttime >= #Datetime AND endtime < #Datetime";
SqlParameter param1 = new SqlParameter("#bikeID", bikeID);
SqlParameter param2 = new SqlParameter("#shopID", shopID);
SqlParameter param3 = new SqlParameter("#Datetime", SqlDbType.DateTime);
param3.Value = datetime;
DataTable bookingData = performQuery(query, param1, param2, param3);
DataRow[] row = bookingData.Select();
int totalBooked = 0;
if ((row.Count()) > 0 && (bookingData != null)) // if there are rows returned
totalBooked = Convert.ToInt32(row[0]["quantity"]);
return totalBooked;
}
Thank you in advance!
Try modifying query to
string query = "SELECT sum(quantity) as 'quantity' FROM booking WHERE bikeID=#bikeID AND shopID = #shopID AND starttime >= #Datetime AND endtime < #Datetime";
DataTable is not a correct way to get the sum. To fix your problem you have to do this:
var sum = Convert.ToInt32(bookingData.Rows[0]["quantity"]);
return sum;
But, the correct way to execute this command, is this:
var statement = "SELECT COUNT(*) ...";
var command = new SqlCommand(statement, connection);
command.AddParam(param1);
command.AddParam(param2);
command.AddParam(param3);
var sum = Convert.ToInt32(command.ExecuteScalar());
return sum;
Please, refer to MSDN doc about scalar: https://msdn.microsoft.com/it-it/library/system.data.sqlclient.sqlcommand.executescalar(v=vs.110).aspx
Hope this can help.
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.
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
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