I want to fetch 1st row 1st cell value from database it works well with below code . But when there is no result found it throws Exception.
How to handle with DBNull
.
Should i change my query ? which return some value if theirs no record ?
System.NullReferenceException: Object reference not set to an instance of an object.
Code:
public string absentDayNo(DateTime sdate, DateTime edate, string idemp) { string result="0"; string myQuery="select COUNT(idemp_atd) absentDayNo from td_atd where "; myQuery +=" absentdate_atd between '"+sdate+"' and '"+edate+" "; myQuery +=" and idemp_atd='"+idemp+"' group by idemp_atd "; SqlCommand cmd = new SqlCommand(myQuery, conn); conn.Open(); //System.NullReferenceException occurs when their is no data/result string getValue = cmd.ExecuteScalar().ToString(); if (getValue != null) { result = getValue.ToString(); } conn.Close(); return result; }
the OracleCommand ExecuteScalar returns an object for the result. It's not strongly typed because the SQL statement is arbitrary, so the type isn't known until it's parsed (which is by the DB engine, not by the . NET runtime). The object returned can be null .
ExecuteScalar method is used to execute SQL Commands or storeprocedure, after executing return a single value from the database. It also returns the first column of the first row in the result set from a database.
Use the ExecuteScalar method to retrieve a single value (for example, an aggregate value) from a database. This requires less code than using the ExecuteReader method, and then performing the operations that you need to generate the single value using the data returned by a SqlDataReader.
The ExecuteScalar() in C# SqlCommand Object is using for retrieve a single value from Database after the execution of the SQL Statement. The ExecuteScalar() executes SQL statements as well as Stored Procedure and returned a scalar value on first column of first row in the returned Result Set.
There is no need to keep calling .ToString()
as getValue
is already a string.
Aside that, this line could possibly be your problem:
string getValue = cmd.ExecuteScalar().ToString();
If there are no rows .ExecuteScalar
will return null
so you need to do some checking.
For instance:
var firstColumn = cmd.ExecuteScalar(); if (firstColumn != null) { result = firstColumn.ToString(); }
If the first cell returned is a null
, the result in .NET will be DBNull.Value
If no cells are returned, the result in .NET will be null
; you cannot call ToString()
on a null
. You can of course capture what ExecuteScalar
returns and process the null
/ DBNull
/ other cases separately.
Since you are grouping etc, you presumably could potentially have more than one group. Frankly I'm not sure ExecuteScalar
is your best option here...
Additional: the sql in the question is bad in many ways:
I strongly suggest you parameterize; perhaps with something like "dapper" to make it easy:
int count = conn.Query<int>( @"select COUNT(idemp_atd) absentDayNo from td_atd where absentdate_atd between @sdate and @edate and idemp_atd=@idemp group by idemp_atd", new {sdate, edate, idemp}).FirstOrDefault();
all problems solved, including the "no rows" scenario. The dates are passed as dates (not strings); the injection hole is closed by use of a parameter. You get query-plan re-use as an added bonus, too. The group by
here is redundant, BTW - if there is only one group (via the equality condition) you might as well just select COUNT(1)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With