存储过程返回受影响行数,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
相关产品推荐
相关产品推荐

