【问题标题】:Return value using String result=Command.ExecuteScalar() error occurs when result returns null返回值使用 String result=Command.ExecuteScalar() 结果返回 null 时发生错误
【发布时间】:2013-05-20 10:09:25
【问题描述】:

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

如何处理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;
    }

【问题讨论】:

  • 哪里会抛出异常??
  • Exception throws string getValue = cmd.ExecuteScalar().ToString(); mean error 当他们没有结果时发生
  • 顺便说一句,这是构建查询的真的不好的方法;清晰明了的sql注入孔;还有一个国际化问题,以及一些不必要的中间字符串。我希望这不是你平时做 sql 的方式...
  • @MarcGravell:对不起,我的坏习惯是,下次我通过使用参数化查询来处理 sqlInjection
  • @Satindersingh 根据我编辑的答案:您实际上可以一口气解决这两个问题......只是说......

标签: c# sql asp.net sql-server database


【解决方案1】:

没有必要继续调用.ToString(),因为getValue已经是一个字符串了。

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

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

如果没有行 .ExecuteScalar 将返回 null 所以你需要做一些检查。

例如:

var firstColumn = cmd.ExecuteScalar();

if (firstColumn != null) {
    result = firstColumn.ToString();
}

【讨论】:

  • 感谢这很好用,Naresh Parmar 的回答也对我有用,方法是添加检查字符串是 ""
  • 或者你可以使用Convert.ToString(cmd.ExecuteScalar()); - 如果值为null,这会给你String.Empty
【解决方案2】:

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

如果没有返回单元格,.NET 中的结果将为null;您不能在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();

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

【讨论】:

  • 感谢您的精彩解释,第一次听说dapper,今天学习新知识
  • @Satindersingh 它在 nuget 上免费提供:nuget.org/packages/Dapper
【解决方案3】:

试试这个

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

【讨论】:

    【解决方案4】:

    你可以像下面这样使用

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

    【讨论】:

    • @Satindersingh 你在哪里试过?你用了什么代码?问题中的代码没有显示这个...
    • @Satindersingh:没问题...请不要道歉。能解决问题就好了。
    • @saravanan:本话题外的一个查询,你是如何在博客中添加的,想添加到我的satindersinght.blogspot.in/2013/04/…
    • @Satindersingh:请按照此链接中的步骤操作:support.google.com/blogger/bin/answer.py?hl=en&answer=50288。您必须使用您的帐户注册 Adsense,并将适当的内容添加到博客中。
    【解决方案5】:

    Value 不是 null,而是 DBNull.Value。

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

    【讨论】:

      【解决方案6】:

      试试这个:

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

      【讨论】:

        【解决方案7】:

        这应该可行:

        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 ...
        

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                要使用 NpgsqlCommand 或标准 sqlCommand 使用:

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-04-23
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-08-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多