使用字符串返回值result=Command.ExecuteScalar()当结果返回null时会发生错误



我想从数据库中获取第一行第一个单元格值,它与下面的代码很好地工作。但是当没有找到结果时,会抛出Exception。

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

系统。

代码:

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

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

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

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

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

例如:

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

如果返回的第一个单元格是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)

试试这个

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

Value不是null,而是DBNull.Value.

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

您可以使用如下

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

try this:

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

应该可以:

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

使用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#有一个高级特性,使用它。' .string getValue = cmd.ExecuteScalar()?thant。

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

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

最新更新