【问题标题】:Output parameter returns zero while stored procedure returns affected rows count输出参数返回零,而存储过程返回受影响的行数
【发布时间】:2018-10-21 20:04:42
【问题描述】:

我正在做一个用户注册页面。插入用户存储过程工作正常,在 SQL Server 和配置文件查看器中,输出参数返回@@Rowcount,从 C# 调用此存储过程时,它始终返回“0”。

我的存储过程是这样的:

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 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

还有我的 C# 代码:

cmd = dbClient.GetCommand("cm.usp_InsertUser", CommandType.StoredProcedure);

dbClient.AddParameter(cmd, "@pEncrUserId", DALayer.EnumEx.DBDataTypes.NVarChar, ParameterDirection.Input, 0, objInput.EncrUseId);
dbClient.AddParameter(cmd, "@pApplicationTypeId", DALayer.EnumEx.DBDataTypes.BigInt, ParameterDirection.Input, 150, objInput.ApplicationtypeId);
dbClient.AddParameter(cmd, "@pLanguageId", DALayer.EnumEx.DBDataTypes.BigInt, ParameterDirection.Input, 150, objInput.LanguageId);
dbClient.AddParameter(cmd, "@pUsername", DALayer.EnumEx.DBDataTypes.VarChar, ParameterDirection.Input, 15, objInput.UserName);
dbClient.AddParameter(cmd, "@pPassword", DALayer.EnumEx.DBDataTypes.NVarChar, ParameterDirection.Input, 0, objInput.Password);
dbClient.AddParameter(cmd, "@pRecoverEmail", DALayer.EnumEx.DBDataTypes.VarChar, ParameterDirection.Input, 150, objInput.RecoverEmail);
dbClient.AddParameter(cmd, "@pCreatedBy", DALayer.EnumEx.DBDataTypes.BigInt, ParameterDirection.Input, 150, objInput.CreatedBy);
dbClient.AddParameter(cmd, "@pReturnId", DALayer.EnumEx.DBDataTypes.BigInt, ParameterDirection.Output, 150);
dbClient.AddParameter(cmd, "@pErrorMessage", DALayer.EnumEx.DBDataTypes.NVarChar, ParameterDirection.Output, 150);

IDataReader dsTemp = dbClient.ExecuteDataReader(cmd);

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

任何建议对我都有帮助。我不明白这有什么问题。此方法适用于项目的其他插入。

【问题讨论】:

  • 为什么不改用SqlCommand.ExecuteNonQuery Method ()?它将返回受影响的行数。
  • 需要调试GetParameterValue方法。
  • 可能不会有什么不同,但您在 SQL 中将其声明为 int,在 C# 代码中声明为 bigint
  • 你的表有主键吗?您正在使用 INSERT 并且如果该行已经存在具有相同的主键,您将获得零返回,因为没有更改任何行。插入不会改变一行。然后您将需要使用更新。
  • 什么是dbClient?为什么不执行SELECT @@ROWCOUNT 并读取结果输出?

标签: c# sql stored-procedures sqlclient idatareader


【解决方案1】:

感谢您贡献宝贵的知识和时间。

我找到了它返回 0 的原因,我正在使用另一个 SP 生成 sequenceId(本问题中未提及)并将该值作为主键传递到此 [CM].[tb_ApplicationUser] 表中。当我评论该行并将一些值传递给 [CM].[tb_ApplicationUser] 表时。所以它会返回 @@Rowcount 或任何完美的值,

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

在这种情况下,我了解多次 DML 尝试可能会导致获取 @@ROWCOUNT 的问题。 DML 查询可以正常工作,它会影响表格,但我们无法在代码端(ExecuteDataReader 或其他)获得所需的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    相关资源
    最近更新 更多