我正在重构一个调用以以下结尾的存储过程的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
值时,问题就会出现。
答案 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。