没有返回结果时处理ExecuteScalar()

Hem*_*yal 55 c# oracle ado.net

我使用以下SQL查询和ExecuteScalar()方法从Oracle数据库中获取数据:

sql = "select username from usermst where userid=2"
string getusername = command.ExecuteScalar();
Run Code Online (Sandbox Code Playgroud)

它向我显示此错误消息:

System.NullReferenceException:未将对象引用设置为对象的实例

当数据库表中没有行时,会发生此错误userid=2.
我该如何处理这种情况?

Bra*_*vic 52

根据DbCommand.ExecuteScalar的MSDN文档:

如果未找到结果集中第一行的第一列,则返回空引用(在Visual Basic中为Nothing).如果数据库中的值为null,则查询返回DBNull.Value.

请考虑以下代码段:

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();
}
Run Code Online (Sandbox Code Playgroud)

在运行时(在ODP.NET下测试但在任何ADO.NET提供程序下应该是相同的),它的行为如下:

  • 如果该行不存在,则结果command.ExecuteScalar()为null,然后将其转换为空字符串并分配给getusername.
  • 如果该行存在,但在用户名中有NULL(这在您的数据库中是否可能?),结果command.ExecuteScalar()DBNull.Value,导致一个InvalidCastException.

无论如何,这NullReferenceException不可能,所以你的问题可能在其他地方.


Run*_*tad 49

首先,您应该确保您的命令对象不为null.然后,您应该将命令的CommandText属性设置为您的SQL查询.最后,您应该将返回值存储在对象变量中,并在使用它之前检查它是否为null:

command = new OracleCommand(connection)
command.CommandText = sql
object userNameObj = command.ExecuteScalar()
if (userNameObj != null)
  string getUserName = userNameObj.ToString()
 ...
Run Code Online (Sandbox Code Playgroud)

我不确定VB语法,但你明白了.

  • 你不应该避免使用ExecuteScalar.当您只需要查询中的单个返回值时,建议使用此方法.问题是它返回一个Object,而不是您想要的类型的值.原因是数据库可以在列中包含空值,并且查询可能根本不返回值.这就是为什么将值存储在转换为适当类型的对象类型变量中的原因. (6认同)

Fan*_*nda 22

我刚用过这个:

    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;
    }
Run Code Online (Sandbox Code Playgroud)


Tom*_*ier 10

以下行:

string getusername = command.ExecuteScalar();
Run Code Online (Sandbox Code Playgroud)

...将尝试隐式将结果转换为字符串,如下所示:

string getusername = (string)command.ExecuteScalar();
Run Code Online (Sandbox Code Playgroud)

如果对象为null,则常规的转换操作符将失败.尝试使用as-operator,如下所示:

string getusername = command.ExecuteScalar() as string;
Run Code Online (Sandbox Code Playgroud)


小智 7

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


jjj*_*jjj 6

这可能会有所帮助..例子::

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

这里来


Sag*_*gar 5

在阅读行之前始终进行检查。

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

}
Run Code Online (Sandbox Code Playgroud)

  • 这不会双重执行查询吗?检查查询结果是否不为空,如果不为空,则执行分配给 var? 的查询 (3认同)

Biz*_*han 5

SQL NULL

  • C# 中的等效项是DBNull.Value
  • 如果 NULLABLE 列没有值,则返回值
  • SQL中的比较: IF ( value IS NULL )
  • C#中的比较: if (obj == DBNull.Value)
  • 在 C# Quick-Watch 中直观地表示为 {}

从数据读取器读取时的最佳实践:

var reader = cmd.ExecuteReader();
...
var result = (reader[i] == DBNull.Value ? "" : reader[i].ToString());
Run Code Online (Sandbox Code Playgroud)

根据我的经验,在某些情况下,返回值可能会丢失,因此通过返回 null 导致执行失败。一个例子是

select MAX(ID) from <table name> where <impossible condition>
Run Code Online (Sandbox Code Playgroud)

上面的脚本无法找到任何可以找到 MAX 的东西。所以它失败了。在这些情况下,我们必须比较旧时尚方式(与 C# 比较null

var obj = cmd.ExecuteScalar();
var result = (obj == null ? -1 : Convert.ToInt32(obj));
Run Code Online (Sandbox Code Playgroud)


rad*_*byx 5

如果您想要stringempty string以防万一某些内容为空,没有任何内容可能会中断

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;
}
Run Code Online (Sandbox Code Playgroud)