ExecuteScalar返回0执行存储过程

时间:2011-08-09 13:55:21

标签: c# stored-procedures executescalar

我正在重构一个调用以以下结尾的存储过程的C#程序:

SELECT @ResultCode AS ResultCode

C#代码如下所示:

SqlDbCommand.CommandType = System.Data.CommandType.StoredProcedure;
SqlDbCommand.CommandText = "PR_Foo";

SqlDbCommand.Parameters.Clear();
SqlDbCommand.Parameters.Add("@Foo", SqlDbType.Char);  
SqlDbCommand.Parameters["@Foo"].Value = 'Foo';

System.Data.SqlClient.SqlDataAdapter SqlDbAdapter = new System.Data.SqlClient.SqlDataAdapter();
System.Data.DataSet SQLDataSet = new System.Data.DataSet();
SqlDbAdapter.SelectCommand = SqlDbCommand;
SqlDbAdapter.Fill(SQLDataSet);
SQLDataSet.Tables[0].TableName = "PR_Foo";

if (SQLDataSet.Tables.Count != 0) {
       Result = int.Parse(SQLDataSet.Tables[SQLDataSet.Tables.Count - 1].Rows[0][0].ToString());
}

使用上面的代码,Result正确填充了由
返回的值 存储过程。

使用更简单的ExecuteScalar

重构代码
SqlDbCommand.CommandType = System.Data.CommandType.StoredProcedure;
SqlDbCommand.CommandText = "PR_Foo";

SqlDbCommand.Parameters.Clear();
SqlDbCommand.Parameters.Add("@Foo", SqlDbType.Char); 
SqlDbCommand.Parameters["@Foo"].Value = 'Foo';

Result = (int)SqlDbCommand.ExecuteScalar(); 

Result值奇怪地设置为0,而预期结果应该是大于零的整数值。

你知道造成这种奇怪行为的原因是什么吗?

注意:

存储过程有几个if块,在特殊检查的情况下返回低于零的结果值;这些情况由ExecuteScalar()正确处理。

当存储过程正确执行其工作,提交各种更新的事务并在结尾返回Result值时,问题就会出现。

4 个答案:

答案 0 :(得分:4)

如果返回多个表,则两个代码段不会做同样的事情。您的原始代码采用 last 表的第一行的第一个字段,而执行标量将采用第一个表的第一行的第一个字段。这可能是你的问题所在吗?

答案 1 :(得分:4)

我也遇到过这个问题。 在我看来,这是非常相关的。 所以我决定在这里给出正确的代码示例。

    SqlCommand cmd2 = new SqlCommand();
    cmd2.Connection = conn;
    cmd2.CommandType = System.Data.CommandType.StoredProcedure;
    cmd2.CommandText = "dbo.Number_Of_Correct";

    SqlParameter sp0 = new SqlParameter("@Return_Value", System.Data.SqlDbType.SmallInt);
    sp0.Direction = System.Data.ParameterDirection.ReturnValue;
    SqlParameter sp1 = new SqlParameter("@QuestionID", System.Data.SqlDbType.SmallInt);

    cmd2.Parameters.Add(sp0);
    cmd2.Parameters.Add(sp1);

    sp1.Value = 3;

    cmd2.ExecuteScalar();     // int Result = (int)cmd2.ExecuteScalar();  trowns System.NullReferenceException
    MessageBox.Show(sp0.Value.ToString());

答案 2 :(得分:2)

您似乎想要的是 最后一个结果集 第一行第一列 。不幸的是,如果您的过程中有多个select语句,从而生成多个结果集,ExecuteScalar只会获得第一行的第一列 < / strong> 第一个结果集

您的第一个C#代码块会检查数据集中的 last 表,该表将(正确地)与过程中 last select语句相关联。

答案 3 :(得分:2)

如果您有多个潜在的结果集,并且可能存在歧义,您可以考虑更改存储过程以使用输出参数而不是@ResultCode上的select。