C# 使用字符串result=Command返回值。结果返回null时发生ExecuteScalar()错误

C# 使用字符串result=Command返回值。结果返回null时发生ExecuteScalar()错误,c#,sql,asp.net,sql-server,database,C#,Sql,Asp.net,Sql Server,Database,我想从数据库中获取第一行第一个单元格的值,它与下面的代码配合得很好。但当并没有找到结果时,它抛出异常 如何处理DBNull。 我应该更改我的查询吗?如果他们没有记录,哪个会返回一些值 System.NullReferenceException:对象引用未设置为对象的实例 代码: 您可以像下面这样使用 string result = null; object value = cmd.ExecuteScalar(); if (value != null) { result = value

我想从数据库中获取第一行第一个单元格的值,它与下面的代码配合得很好。但当并没有找到结果时,它抛出异常

如何处理DBNull。 我应该更改我的查询吗?如果他们没有记录,哪个会返回一些值

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

代码:


您可以像下面这样使用

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

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

无需继续调用。ToString as getValue已经是字符串

除此之外,这一行可能是您的问题:

 string getValue = cmd.ExecuteScalar().ToString();  
如果没有行,ExecuteScalar将返回null,因此需要进行一些检查

例如:

var firstColumn = cmd.ExecuteScalar();

if (firstColumn != null) {
    result = firstColumn.ToString();
}
这应该起作用:

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

return result != null ? result.ToString() : string.Empty;
此外,我建议在查询中使用参数,例如建议:

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 ...
试试这个

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

如果返回的第一个单元格为null,则.NET中的结果将为DBNull.Value

如果没有返回单元格,.NET中的结果为空;不能在null上调用ToString。当然,您可以捕获ExecuteScalar返回的内容,并分别处理null/DBNull/其他情况

由于您正在分组等,您可能会有多个组。坦白地说,我不确定ExecuteScalar是你最好的选择

另外:问题中的sql在很多方面都不好:

sql注入 国际化让我们希望客户机和服务器在日期上达成一致 单独语句中不必要的连接 我强烈建议你参数化;也许可以用一些像dapper这样的简单方法:

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

所有问题都已解决,包括无行场景。日期作为日期而不是字符串传递;通过使用参数来关闭注射孔。您还可以获得查询计划重用作为额外奖励。顺便说一句,此处的组是冗余的-如果通过相等条件只有一个组,您最好选择COUNT1。

值不是null,而是DBNull.Value

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

要使用NpgsqlCommand或标准sqlCommand,请使用:

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

使用SQL server isnull函数

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

如果null设置为0或其他值,请尝试此选项

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

c有一个高级特性,使用“?”。
字符串getValue=cmd.ExecuteScalar?.ToString;thants all.

它在哪里抛出异常??异常抛出字符串getValue=cmd.ExecuteScalar.ToString;平均错误发生在没有结果时,这是构建查询的一种非常糟糕的方法;清晰而明显的sql注入孔;还有一个国际化问题,以及一些不必要的中间字符串。我希望这不是您通常使用sql的方式…@MarcGravell:Sry,感谢我糟糕的实践习惯,是的,下次我使用参数化处理sqlInjection时queries@Satindersingh根据我编辑的答案:你可以一次解决两个问题。。。只是说…@Satindersingh你在哪里试过?你用了什么代码?问题中的代码没有显示这一点…@Satindersingh:没有问题。。。请不要道歉。如果它解决了问题就可以了。@saravanan:本主题中的一个查询,你是如何在你的博客中添加添加的,想在我的@Satindersingh:中添加吗?请按照此链接中的步骤进行操作:。您必须使用您的帐户注册Adsense,并将适当的内容添加到博客中。谢谢,这很好,Naresh Parmar的回答也适用于我,通过添加字符串is的检查,或者您可以使用Convert.ToStringcmd.ExecuteScalar;-这将为您提供字符串。如果值为空,则为空。感谢您的精彩解释,第一次听说dapper,了解新内容today@Satindersingh它在nuget上免费提供:
return command.ExecuteScalar() == DBNull.Value ? 0 : (double)command.ExecuteScalar();