2

可能重复:
ExecuteScalar 返回 null 或 DBNull(开发或生产服务器)

我有一个存储过程,用于检查预先存在的文件 ID 是否与项目相关联。如果 select 语句返回值,它应该是 true 并将“true”分配给 bool。但是,当 select 语句因为不存在而返回 null 时,我后面的代码仍然使 .Execute 返回“true”

这是我的存储过程:

ALTER PROCEDURE [dbo].[Events_TaskIDExists] 
@EventID int
AS
BEGIN
    select TaskID from Events where EventID = @EventID
END

这是我的代码:

public void hasTaskAssociatedToNote()
{
    String[] Notes = hidSelectedEventIDs.Value.Split(',');
    bool exists = false;
    foreach (var note in Notes)
    {
        var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["OSCIDConnectionString"].ToString());
        var command = new SqlCommand("Events_TaskIDExists", connection);
        command.Parameters.Add(new SqlParameter("@EventID", SqlDbType.Int));
        command.Parameters["@EventID"].Value = Convert.ToInt32(note.Trim());
        command.CommandType = CommandType.StoredProcedure;
        try
        {
            connection.Open();
            exists = command.ExecuteScalar() != null;//causes true when it returns null......
            var temp = command.ExecuteScalar();//this was just to check something else
            if (exists)
            {
                exhibitWarning.Visible = true;
                Warning1.Text = "There is an existing Task associated 0.";
            }
        }
        catch (SqlException sql)
        {
            lblStatus.Text = "Couldn't connect to the Database - Error";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        catch (Exception ex)
        {
            lblStatus.Text = "An error occured";
            lblStatus.ForeColor = System.Drawing.Color.Red;
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }
    }
}
4

2 回答 2

3

您的exists变量应设置为:

object result = command.ExecuteScalar();
exists = result != DBNull.Value && result != null;

来自的 null 结果SqlCommand.ExecuteScalar()返回 a DBNull.Value,而不是null。只有一个空的结果集会返回一个null.

由于您是根据 EventID 选择 TaskID,我猜您的数据库并没有被限制为每个事件都需要一个 TaskID,因此您有空的 TaskID 字段。换句话说,您有包含 的事件记录@EventID,但没有关联的任务记录(基于TaskID)。此条件将返回 aDBNull.Value而不是 a null

"返回值 类型:System.Object结果集中第一行的第一列,如果结果集为空,则为空引用(在 Visual Basic 中为 Nothing)。最多返回 2033 个字符。- MSDN - SqlCommand.ExecuteScalar()

于 2012-10-22T21:07:10.550 回答
1

我可能会枪杀这个,只是

exists = (command.ExecuteScalar() ?? DBNull.Value) != DBNull.Value;

这假设由于某种原因,您的存储过程实际上返回了第一列等于 DBNull 的行,并且在这种情况下您希望存在 == false。一个简短的调试应该证明或反驳这一点。

于 2012-10-22T21:11:15.883 回答