You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:38:19