35

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;
    }
5
  • 1
    Where it throws exception ?? Commented May 20, 2013 at 10:14
  • 1
    Exception throws string getValue = cmd.ExecuteScalar().ToString(); mean error occurs when their is no result Commented May 20, 2013 at 10:16
  • 5
    btw, that is a really bad way to build a query; clear and blatant sql injection hole; there's also an internationalisation issue, and some unnecessary intermediate strings. I hope that isn't how you do sql normally... Commented May 20, 2013 at 10:22
  • @MarcGravell: Sry for my bad practising habbit , and yes next time i take care of sqlInjection, by using parameterize queries Commented May 20, 2013 at 10:27
  • 1
    @Satindersingh as per my edited answer: you can actually solve both issues in one go... just saying... Commented May 20, 2013 at 10:29

11 Answers 11

69

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();
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks this works well, also Naresh Parmar answer worked for my by adding check for string is ""
or you could use Convert.ToString(cmd.ExecuteScalar()); - this will give you String.Empty if the value is null.
22

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:

  • sql injection
  • internationalization (let's hope the client and server agree on what a date looks like)
  • unnecessary concatenation in separate statements

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).

2 Comments

Thanks for nice explanation, 1st time heard about dapper, learn new today
@Satindersingh it is freely available on nuget: nuget.org/packages/Dapper
9

Try this one

var getValue = cmd.ExecuteScalar();    
conn.Close();
return (getValue == null) ? string.Empty : getValue.ToString();

Comments

7

Value is not null, but DBNull.Value.

object value = cmd.ExecuteScalar();
if(value == DBNull.Value)

Comments

5

You can use like the following

string result = null;
object value = cmd.ExecuteScalar();
 if (value != null)
 {
    result = value.ToString();
 }     
 conn.Close();
return result;

4 Comments

@Satindersingh where did you try? what code did you use? the code in the question does not show this...
@Satindersingh: No issues... please do not apologize. Its fine if it solves the problem.
@saravanan: one query out of this topic, how you added adds in you blog, want to add in my satindersinght.blogspot.in/2013/04/…
@Satindersingh: Please follow the steps in this link: support.google.com/blogger/bin/answer.py?hl=en&answer=50288. You will have to register for Adsense with your account and add the appropriate content to the blog.
2

try this :

 string getValue = Convert.ToString(cmd.ExecuteScalar());

Comments

1

This should work:

var result = cmd.ExecuteScalar();
conn.Close();

return result != null ? result.ToString() : string.Empty;

Also, I'd suggest using Parameters in your query, something like (just a suggestion):

var cmd = new SqlCommand
{
    Connection = conn,
    CommandType = CommandType.Text,
    CommandText = "select COUNT(idemp_atd) absentDayNo from td_atd where absentdate_atd between @sdate and @edate and idemp_atd=@idemp group by idemp_atd"
};

cmd.Parameters.AddWithValue("@sdate", sdate);
cmd.Parameters.AddWithValue("@edate", edate);
// etc ...

Comments

1

There is a advance feature of c#, use that '?.' . string getValue = cmd.ExecuteScalar()?.ToString(); thants all.

Comments

0

Use SQL server isnull function

public string absentDayNo(DateTime sdate, DateTime edate, string idemp)
{ 
    string result="0";
    string myQuery="select isnull(COUNT(idemp_atd),0) as 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;
}

Comments

0

Try this one, if null set 0 or something

return command.ExecuteScalar() == DBNull.Value ? 0 : (double)command.ExecuteScalar();

Comments

-1

To work with NpgsqlCommand or the standard sqlCommand use:

int result = int.Parse(cmd.ExecuteScalar().ToString());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.