SQL存储过程返回值正常,为何C#中读取ReturnValue为null?
问题描述
我在SQL Server中创建了如下存储过程,执行后会返回0:
create procedure myProc as begin select * from sampleTable return 0 end
在SQL中调用该存储过程时,返回值符合预期:
exec @i = myProc select @i -- value is 0
我在C#中通过以下代码调用该存储过程:
SqlDataReader dr = await CommandObj.ExecuteReaderAsync(CommandBehavior.SequentialAccess, token).ConfigureAwait(false);
但尝试读取设置为ParameterDirection.ReturnValue的参数时,其值为null。
有趣的是,对于不查询数据表的存储过程,使用以下代码可以正常读取ReturnValue:
await CommandObj.ExecuteNonQueryAsync(token).ConfigureAwait(false);
我希望使用ReturnValue而非out参数,请问该如何解决?
解决方案
这是因为使用ExecuteReaderAsync时,存储过程的返回值要等到SqlDataReader完全关闭后才能获取到,具体操作步骤如下:
- 首先确保已正确添加返回值参数:
var returnParam = new SqlParameter("@ReturnVal", SqlDbType.Int) { Direction = ParameterDirection.ReturnValue }; CommandObj.Parameters.Add(returnParam);
- 读取
SqlDataReader的所有结果集,之后关闭reader:
using (SqlDataReader dr = await CommandObj.ExecuteReaderAsync(CommandBehavior.SequentialAccess, token).ConfigureAwait(false)) { // 读取第一个结果集的所有数据 while (await dr.ReadAsync(token).ConfigureAwait(false)) { // 根据实际需求处理每行数据 // 示例:var sampleColumn = dr.GetString(0); } // 若存储过程存在多个结果集,需遍历所有结果集 while (await dr.NextResultAsync(token).ConfigureAwait(false)) { while (await dr.ReadAsync(token).ConfigureAwait(false)) { // 处理其他结果集的数据 } } } // 此时即可读取到正确的返回值 int returnValue = (int)CommandObj.Parameters["@ReturnVal"].Value;
核心逻辑:SQL Server会优先返回存储过程生成的结果集,返回值是最后发送的内容。因此在C#中必须先消费完SqlDataReader的全部数据并关闭它,才能获取到返回值参数的实际内容。
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

