我想从数据库中获取第一行第一个单元格值,它与下面的代码很好地工作。但是当没有找到结果时,会抛出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());