Handling ExecuteScalar() when no results are returned

Viewed 184733

I am using the following SQL query and the ExecuteScalar() method to fetch data from an Oracle database:

sql = "select username from usermst where userid=2"
string getusername = command.ExecuteScalar();

It is showing me this error message:

System.NullReferenceException: Object reference not set to an instance of an object

This error occurs when there is no row in the database table for userid=2.
How should I handle this situation?

23 Answers

First you should ensure that your command object is not null. Then you should set the CommandText property of the command to your sql query. Finally you should store the return value in an object variable and check if it is null before using it:

command = new OracleCommand(connection)
command.CommandText = sql
object userNameObj = command.ExecuteScalar()
if (userNameObj != null)
  string getUserName = userNameObj.ToString()
 ...

I'm not sure about the VB syntax but you get the idea.

The following line:

string getusername = command.ExecuteScalar();

... will try to implicitly convert the result to string, like below:

string getusername = (string)command.ExecuteScalar();

The regular casting operator will fail if the object is null. Try using the as-operator, like this:

string getusername = command.ExecuteScalar() as string;

Check out the example below:

using System;
using System.Data;
using System.Data.SqlClient;

class ExecuteScalar
{
  public static void Main()
  {
    SqlConnection mySqlConnection =new SqlConnection("server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;");
    SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
    mySqlCommand.CommandText ="SELECT COUNT(*) FROM Employee";
    mySqlConnection.Open();

    int returnValue = (int) mySqlCommand.ExecuteScalar();
    Console.WriteLine("mySqlCommand.ExecuteScalar() = " + returnValue);

    mySqlConnection.Close();
  }
}

from this here

If you either want the string or an empty string in case something is null, without anything can break:

using (var cmd = new OdbcCommand(cmdText, connection))
{
    var result = string.Empty;
    var scalar = cmd.ExecuteScalar();
    if (scalar != DBNull.Value) // Case where the DB value is null
    {
        result = Convert.ToString(scalar); // Case where the query doesn't return any rows. 
        // Note: Convert.ToString() returns an empty string if the object is null. 
        //       It doesn't break, like scalar.ToString() would have.
    }
    return result;
}

Slight conjecture: if you check the stack for the exception, it is being thrown then the ADO.NET provider for Oracle is reading the underlying rowset to get the first value.

If there is no row, then there is no value to find.

To handle this case execute for a reader and handle Next() returning false for the case of no match.

object objUserName;
objUserName = command.ExecuteScalar();

if (objUserName == null)  //if record not found ExecuteScalar returns null
{
    return "";
}
else
{
    if (objUserName == DBNull.Value)  //if record found but value in record field is null
    {
        return "";
    }
    else
    {
        string getusername = objUserName.ToString();
        return getusername; 
    }
}

/* Select some int which does not exist */
int x = ((int)(SQL_Cmd.ExecuteScalar() ?? 0));

I'm using Oracle. If your sql returns numeric value, which is int, you need to use Convert.ToInt32(object). Here is the example below:

public int GetUsersCount(int userId)
{
    using (var conn = new OracleConnection(...)){
        conn.Open();
        using(var command = conn.CreateCommand()){
            command.CommandText = "select count(*) from users where userid = :userId";
            command.AddParameter(":userId", userId);            
            var rowCount = command.ExecuteScalar();
            return rowCount == null ? 0 : Convert.ToInt32(rowCount);
        }
    }
}
Related