SqlDataReader和SqlCommand使用SUM()

3
我有一个简单的查询,当满足条件时,它会从SQL数据库中的表中对一列进行求和。
decimal stock = 0;

SqlCommand cmd = new SqlCommand();
SqlDataReader myRdr;
cmd.Connection = connection;
cmd.CommandText = "SELECT SUM(stock) AS stock FROM table WHERE id=@id AND condition=@condition";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("@id", SqlDbType.NVarChar, 15).Value = id;
cmd.Parameters.Add("@condition", SqlDbType.NVarChar, 15).Value = condition;

connection.Open();
myRdr = cmd.ExecuteReader();
if (myRdr.HasRows)
{
    myRdr.Read();
    stock += Convert.ToDecimal(myRdr1["stock"]);
}

myRdr1.Close();
cmd1.Dispose();
connection.Close();

如果表中有满足条件的条目,它可以正常工作。但是如果没有条目,它会抛出异常,说我试图将DBNull类型转换为十进制数,这是不可能的。我尝试了以下方法:

if (myRdr.HasRows)
{
    myRdr.Read();
    if (myRdr["stock"] != null)
    {
        stock += Convert.ToDecimal(myRdr1["stock"]);
    }
}

但仍然会抛出异常。感谢您的帮助。
2个回答

3

只需稍微更改您的查询方式:

SELECT SUM(stock) AS stock
FROM table
WHERE id=@id AND condition=@condition

转换为:

SELECT ISNULL(stock, 0) AS stock
FROM (
    SELECT SUM(stock) AS stock
    FROM table
    WHERE id=@id AND condition=@condition
) q

1
使用了您的解决方案,只需添加一个小细节:SELECT ISNULL(stock, 0) AS stock FROM... - user1080533

3

myRdr1["stock"] 返回的是 DBNull,所以请检查它是否为 null

if (myRdr1["stock"] != DBNull)
{
    stock += Convert.ToDecimal(myRdr1["stock"]);
}

1
你可以在COALESCE中嵌入SUM(stock):COALESCE(SUM(stock), 0),这样当没有库存时它将返回0。 - user170442
确实,最好在客户端和服务器上都进行修复。 - Justin Pihony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接