33

我想从数据库中获取第一行第一个单元格值,它适用于以下代码。但是当没有找到结果时,它会抛出异常。

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

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

代码:

    public string absentDayNo(DateTime sdate, DateTime edate, string idemp)
    { 
       string result="0";
       string myQuery="select COUNT(idemp_atd) 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;
    }
4

11 回答 11

66

无需继续调用.ToString(),因为getValue它已经是一个字符串。

除此之外,这条线可能是你的问题:

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

如果没有行将.ExecuteScalar返回null,因此您需要进行一些检查。

例如:

var firstColumn = cmd.ExecuteScalar();

if (firstColumn != null) {
    result = firstColumn.ToString();
}
于 2013-05-20T10:16:03.027 回答
20

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

如果没有返回单元格,.NET 中的结果将是null;您不能调用ToString(). null您当然可以捕获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();

所有问题都解决了,包括“无行”场景。日期作为日期(不是字符串)传递;使用参数关闭喷射孔。您还可以获得查询计划的重用作为额外的奖励。顺便说一句,group by这里是多余的-如果只有一组(通过相等条件),您不妨只选择COUNT(1).

于 2013-05-20T10:17:35.707 回答
9

试试这个

var getValue = cmd.ExecuteScalar();    
conn.Close();
return (getValue == null) ? string.Empty : getValue.ToString();
于 2013-05-20T10:17:33.803 回答
5

你可以像下面这样使用

string result = null;
object value = cmd.ExecuteScalar();
 if (value != null)
 {
    result = value.ToString();
 }     
 conn.Close();
return result;
于 2013-05-20T10:11:30.427 回答
5

值不为空,而是 DBNull.Value。

object value = cmd.ExecuteScalar();
if(value == DBNull.Value)
于 2013-05-20T10:34:42.060 回答
2

试试这个 :

 string getValue = Convert.ToString(cmd.ExecuteScalar());
于 2013-05-20T10:13:23.473 回答
1

这应该有效:

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 ...
于 2013-05-20T10:16:06.267 回答
0

使用 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;
}
于 2016-02-23T21:34:30.680 回答
0

试试这个,如果 null 设置为 0 什么的

return command.ExecuteScalar() == DBNull.Value ? 0 : (double)command.ExecuteScalar();
于 2017-06-24T00:12:14.263 回答
0

c#有一个高级特性,使用'?.' . 字符串 getValue = cmd.ExecuteScalar()?.ToString(); 谢谢大家。

于 2019-01-31T04:31:07.010 回答
-1

要使用 NpgsqlCommand 或标准 sqlCommand 使用:

int result = int.Parse(cmd.ExecuteScalar().ToString());
于 2015-04-22T17:29:09.193 回答