[c#] Handling ExecuteScalar() when no results are returned

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?

This question is related to c# oracle ado.net

The answer is


this could help .. example::

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


sql = "select username from usermst where userid=2"
var _getusername = command.ExecuteScalar();
if(_getusername != DBNull.Value)
{
    getusername = _getusername.ToString();
}  

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;
}

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;

This is the easiest way to do this...

sql = "select username from usermst where userid=2"
object getusername = command.ExecuteScalar();
if (getusername!=null)
{
    //do whatever with the value here
    //use getusername.toString() to get the value from the query
}

According to MSDN documentation for DbCommand.ExecuteScalar:

If the first column of the first row in the result set is not found, a null reference (Nothing in Visual Basic) is returned. If the value in the database is null, the query returns DBNull.Value.

Consider the following snippet:

using (var conn = new OracleConnection(...)) {
    conn.Open();
    var command = conn.CreateCommand();
    command.CommandText = "select username from usermst where userid=2";
    string getusername = (string)command.ExecuteScalar();
}

At run-time (tested under ODP.NET but should be the same under any ADO.NET provider), it behaves like this:

  • If the row does not exist, the result of command.ExecuteScalar() is null, which is then casted to a null string and assigned to getusername.
  • If the row exists, but has NULL in username (is this even possible in your DB?), the result of command.ExecuteScalar() is DBNull.Value, resulting in an InvalidCastException.

In any case, the NullReferenceException should not be possible, so your problem probably lies elsewhere.


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


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.


I just used this:

    int? ReadTerminalID()
    {
        int? terminalID = null;

        using (FbConnection conn = connManager.CreateFbConnection())
        {
            conn.Open();
            FbCommand fbCommand = conn.CreateCommand();
            fbCommand.CommandText = "SPSYNCGETIDTERMINAL";
            fbCommand.CommandType = CommandType.StoredProcedure;

            object result = fbCommand.ExecuteScalar(); // ExecuteScalar fails on null
            if (result.GetType() != typeof(DBNull))
            {
                terminalID = (int?)result;
            }
        }

        return terminalID;
    }

SQL NULL value

  • equivalent in C# is DBNull.Value
  • if a NULLABLE column has no value, this is what is returned
  • comparison in SQL: IF ( value IS NULL )
  • comparison in C#: if (obj == DBNull.Value)
  • visually represented in C# Quick-Watch as {}

Best practice when reading from a data reader:

var reader = cmd.ExecuteReader();
...
var result = (reader[i] == DBNull.Value ? "" : reader[i].ToString());

In my experience, there are some cases the returned value can be missing and thus execution fails by returning null. An example would be

select MAX(ID) from <table name> where <impossible condition>

The above script cannot find anything to find a MAX in. So it fails. In these such cases we must compare the old fashion way (compare with C# null)

var obj = cmd.ExecuteScalar();
var result = (obj == null ? -1 : Convert.ToInt32(obj));

Always have a check before reading row.

if (SqlCommand.ExecuteScalar() == null)
{ 

}

Try this code, it appears to solve your problem.

Dim MaxID As Integer = Convert.ToInt32(IIf(IsDBNull(cmd.ExecuteScalar()), 1, cmd.ExecuteScalar()))


Alternatively, you can use DataTable to check if there's any row:

SqlCommand cmd = new SqlCommand("select username from usermst where userid=2", conn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adp.Fill(dt);
string getusername = "";
// assuming userid is unique
if (dt.Rows.Count > 0)
    getusername = dt.Rows[0]["username"].ToString();

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.


In your case either the record doesn't exist with the userid=2 or it may contain a null value in first column, because if no value is found for the query result used in SQL command, ExecuteScalar() returns null.


string VAR;    
if ((command.ExecuteScalar()).ToString() != string.Empty)

{VAR = (string)command.ExecuteScalar();} else{


I used this in my vb code for the return value of a function:

If obj <> Nothing Then Return obj.ToString() Else Return "" End If


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);
        }
    }
}

I have seen in VS2010 string getusername = command.ExecuteScalar(); gives compilation error, Cannot implicitly convert type object to string. So you need to write string getusername = command.ExecuteScalar().ToString(); when there is no record found in database it gives error Object reference not set to an instance of an object and when I comment '.ToString()', it is not give any error. So I can say ExecuteScalar not throw an exception. I think anserwer given by @Rune Grimstad is right.


I Use it Like This with Microsoft Application Block DLL (Its a help library for DAL operations)

public string getCopay(string PatientID)
{
       string sqlStr = "select ISNULL(Copay,'') Copay from Test where patient_id=" + PatientID ;
        string strCopay = (string)SqlHelper.ExecuteScalar(CommonCS.ConnectionString, CommandType.Text, sqlStr);
                if (String.IsNullOrEmpty(strCopay))
                    return "";
                else
                    return strCopay ;
}

I had this issue when the user connecting to the database had CONNECT permissions, but no permissions to read from the database. In my case, I could not even do something like this:

object userNameObj = command.ExecuteScalar()

Putting this in a try/catch (which you should probably be doing anyway) was the only way I could see to handle the insufficient permission issue.


private static string GetUserNameById(string sId, string connStr)
    {
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);
        System.Data.SqlClient.SqlCommand command;

        try
        {
            // To be Assigned with Return value from DB
            object getusername;

            command = new System.Data.SqlClient.SqlCommand();

            command.CommandText = "Select userName from [User] where userid = @userid";

            command.Parameters.AddWithValue("@userid", sId);

            command.CommandType = CommandType.Text;

            conn.Open();

            command.Connection = conn;

            //Execute
            getusername = command.ExecuteScalar();

            //check for null due to non existent value in db and return default empty string
            string UserName = getusername == null ? string.Empty : getusername.ToString();

            return UserName;


        }
        catch (Exception ex)
        {

            throw new Exception("Could not get username", ex);
        }
        finally
        {
            conn.Close();
        }

    }

Try this

sql = "select username from usermst where userid=2"

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

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to oracle

concat yesterdays date with a specific time ORA-28001: The password has expired how to modify the size of a column How to create a blank/empty column with SELECT query in oracle? Find the number of employees in each department - SQL Oracle Query to display all tablespaces in a database and datafiles When or Why to use a "SET DEFINE OFF" in Oracle Database How to insert date values into table error: ORA-65096: invalid common user or role name in oracle In Oracle SQL: How do you insert the current date + time into a table?

Examples related to ado.net

Error: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient' How to fill a datatable with List<T> Populate data table from data reader Increasing the Command Timeout for SQL command how to resolve DTS_E_OLEDBERROR. in ssis Convert DataSet to List How to connect access database in c# MySQL Data Source not appearing in Visual Studio How do I get values from a SQL database into textboxes using C#? Connection to SQL Server Works Sometimes