0

I have the following function which checks to see if a user(strU) exist in the table for a column, if so return 1, otherwise return 0:

public int AddDataScalar(string strU)
{
    string strQueryExistence = "SELECT 1 FROM [OB].[h].[OP_PEONS] WHERE Executive= '" + strU + "'";
    int inNum;
    using (SqlConnection con = new SqlConnection(strConn))
    {
        con.Open();
        SqlCommand cmd = new SqlCommand(strQueryExistence, con);
        object value = cmd.ExecuteScalar().ToString();
        if (value != null)
        {
            inNum = 1;
        }
        else
        {
            inNum = 0;
        }
        con.Close();
    }
    return inNum;
}

It is failing in this line: object value = cmd.ExecuteScalar().ToString();

With the following error: Object reference not set to an instance of an object.

How do I resolve it?

SearchForKnowledge
  • 3,663
  • 9
  • 49
  • 122

4 Answers4

3

ExecuteScalar returns null if your WHERE condition doesn't produce any result.
If you apply any kind of conversion when ExecuteScalar returns null you are in trouble.

Said that, I really suggest some changes to your query

public int AddDataScalar(string strU)
{
    string strQueryExistence = @"IF EXISTS(SELECT 1 FROM [OB].[h].[OP_PEONS] 
                                 WHERE Executive= @stru) SELECT 1 ELSE SELECT 0";
    int inNum = 0;
    using (SqlConnection con = new SqlConnection(strConn))
    using ( SqlCommand cmd = new SqlCommand(strQueryExistence, con))
    {
        con.Open();
        cmd.Parameters.AddWithValue("@stru", strU);
        inNum = Convert.ToInt32(cmd.ExecuteScalar());
    }
    return inNum;
}

The first thing is the IF EXISTS t-sql functions that is the fastest way to discover if a specific record exists or not in the table. The second point is the usage of a parameterized query to avoid parsing problems and Sql Injection scenarios.

The IF EXISTS statement allows to be sure that the ExecuteScalar doesn't return null because in that case the ELSE part will return zero

Steve
  • 213,761
  • 22
  • 232
  • 286
3

whenever cmd.ExecuteScalar() returns null then null.ToString() throws the exception. In your case, just use teкnary operator:

inNum = cmd.ExecuteScalar() == null ? 0 : 1;

The implementation could be

public int AddDataScalar(string strU) {
  using (SqlConnection con = new SqlConnection(strConn)) {
    con.Open();

    // Make your SQL readable: use @"" strings
    strQueryExistence = 
      @"SELECT 1
          FROM [OB].[h].[OP_PEONS]
         WHERE Executive = @prm_Executive";

    // using is a better practice 
    using (SqlCommand cmd = new SqlCommand(strQueryExistence, con)) {
      // parameters are better than hardcoding
      cmd.Parameters.AddWithValue("@prm_Executive", strU); 

      return cmd.ExecuteScalar() == null ? 0 : 1; 
    }
  }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
2

According to MSDN (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar(v=vs.110).aspx):

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.

You're calling .ToString() (why?) on a null object, since there are no results being returned. Skip the .ToString() call and it should work fine.

Bryan Boettcher
  • 4,412
  • 1
  • 28
  • 49
1

If object returned by cmd.ExecuteScalar() is null, you will get this exception. Use:

string value = System.Convert.ToString(cmd.ExecuteScalar());

if you need the result converted to string.

Igor
  • 15,833
  • 1
  • 27
  • 32