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

存储过程返回受影响行数,C#调用时输出参数却始终为0

我帮你排查出两个核心问题,应该能解决你的输出参数始终返回0的问题:

1. 参数类型不匹配

你的存储过程里@pReturnId定义的是INT OUTPUT类型,但C#代码中添加这个输出参数时,却指定了BigInt类型:

dbClient.AddParameter(cmd, "@pReturnId", DALayer.EnumEx.DBDataTypes.BigInt, ParameterDirection.Output, 150);

这种类型不兼容会导致SQL Server无法正确把INT值传递给C#端的参数,最终读取到错误的0值。你需要把C#里的参数类型改成Int,和存储过程的定义保持一致:

dbClient.AddParameter(cmd, "@pReturnId", DALayer.EnumEx.DBDataTypes.Int, ParameterDirection.Output, 0);

2. ExecuteDataReader的输出参数读取时机错误

当使用ExecuteDataReader执行存储过程时,数据库连接会被DataReader占用,输出参数的实际值只有在DataReader被关闭(或者完全读取完所有结果集)之后才会从服务器返回。你现在的代码直接在执行DataReader后就读取参数,这时候参数还没被赋值:

IDataReader dsTemp = dbClient.ExecuteDataReader(cmd);
returnID = Convert.ToInt64(dbClient.GetParameterValue(cmd, "@pReturnId"));

因为你的存储过程是INSERT操作,没有返回结果集,更适合用ExecuteNonQuery来执行,这样执行后可以直接读取输出参数:

// 替换ExecuteDataReader为ExecuteNonQuery
dbClient.ExecuteNonQuery(cmd);
// 因为存储过程返回的是INT,用Convert.ToInt32更合适
returnID = Convert.ToInt32(dbClient.GetParameterValue(cmd, "@pReturnId"));

如果确实需要用ExecuteDataReader(比如后续有结果集返回),一定要先关闭DataReader再读取参数:

using (IDataReader dsTemp = dbClient.ExecuteDataReader(cmd))
{
    // 这里读取结果集(如果有的话)
}
// 关闭DataReader后再获取输出参数
returnID = Convert.ToInt32(dbClient.GetParameterValue(cmd, "@pReturnId"));

额外优化建议

在存储过程开头添加SET NOCOUNT ON;,可以抑制SQL Server返回“受影响行数”的冗余消息,避免干扰参数传递,同时提升操作性能:

ALTER PROCEDURE [CM].[usp_InsertUser] 
    @pEncrUserId NVARCHAR(max), 
    @pApplicationTypeId BIGINT, 
    @pLanguageId BIGINT, 
    @pUsername VARCHAR(15), 
    @pPassword NVARCHAR(max), 
    @pRecoverEmail VARCHAR(128), 
    @pCreatedBy BIGINT, 
    @pReturnId INT OUTPUT , 
    @pErrorMessage NVARCHAR(Max) OUTPUT 
AS 
BEGIN
    SET NOCOUNT ON; -- 添加这一行
    BEGIN TRY 
        INSERT INTO [CM].[tb_ApplicationUser] 
        ([EncrUserId], [ApplicationTypeId],[LanguageId], [UserName], [UserPassword], [RecoverEmail], [CreatedBy], [StatusId], [ConcurId]) 
        VALUES (@pEncrUserId, @pApplicationTypeId, @pLanguageId, @pUsername, @pPassword, @pRecoverEmail, @pCreatedBy, 1, NEWID()) 
        SET @pReturnId = @@ROWCOUNT 
    END TRY 
    BEGIN CATCH 
        SET @pReturnID = @@ERROR; 
        SET @pErrorMessage = ERROR_MESSAGE(); 
    END CATCH 
END

内容的提问来源于stack exchange,提问作者Aniyan Kolathur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:20:13