【问题标题】:Stored Procedure doesn't return affected rows after exception handling异常处理后存储过程不返回受影响的行
【发布时间】:2015-09-14 06:17:25
【问题描述】:

我在存储过程中添加了异常处理,如下所示。

ALTER PROCEDURE [dbo].[BUDGETUPDATE] 
 @DistrictID        int
AS
BEGIN
 SET NOCOUNT ON ;

 BEGIN TRY
         BEGIN TRAN
                    UPDATE bud
                    SET bud.BudgetStateID    = @BudgetStateID
                    FROM [dbo].[BudgetOffice] bud
                        INNER JOIN [dbo].[vw_Office] vw
                            ON (vw.OfficeID   = bud.OfficeID)
                        WHERE   vw.DistrictID = @DistrictID
         IF @@ERROR = 0
      BEGIN   
          COMMIT TRAN;
          SELECT @@ROWCOUNT AS AffectedRow;
      END
 END TRY
 BEGIN CATCH
           SELECT @@ERROR AS ERROR
 ROLLBACK TRAN;
 END CATCH

 SET NOCOUNT OFF ;

 END

我需要使用@@ROWCOUNT 返回受影响的行数。但是这个stored procedure 总是返回行数为0。任何原因。我需要在update 之后写@@rowcount 语句吗?

【问题讨论】:

  • 我认为你需要在UPDATE之后选择@@rowcount

标签: sql sql-server tsql


【解决方案1】:

您需要在UPDATE 语句之后选择@@ROWCOUNT。根据documentation

语句如 USE, SET , DEALLOCATE CURSOR, CLOSE CURSOR, BEGIN TRANSACTION 或 COMMIT TRANSACTION 将 ROWCOUNT 值重置为 0。

由于您的@@ROWCOUNTCOMMIT TRAN 之后,@@ROWCOUNT 返回 0。

【讨论】:

    【解决方案2】:

    您需要将全局变量的结果存储在局部变量中,因为它会在下一条指令后发生变化,例如:

    ALTER PROCEDURE [dbo].[BUDGETUPDATE] 
     @DistrictID        int
    AS
    BEGIN
     SET NOCOUNT ON ;
     DECLARE @rowcount INT, @error INT;
    
     BEGIN TRY
             BEGIN TRAN
                        UPDATE bud
                        SET bud.BudgetStateID = @BudgetStateID
                        FROM [dbo].[BudgetOffice] bud
                        JOIN [dbo].[vw_Office] vw
                          ON vw.OfficeID   = bud.OfficeID
                        WHERE vw.DistrictID = @DistrictID;
    
          SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT;
    
          IF @error = 0
          BEGIN   
              COMMIT TRAN;
              SELECT @rowcount AS AffectedRow;
          END
    
     END TRY
     BEGIN CATCH
         SELECT @@ERROR AS ERROR
         ROLLBACK TRAN;
     END CATCH
     END
    

    TRY CATCH 块中使用@@ERROR 甚至更好:

    ALTER PROCEDURE [dbo].[BUDGETUPDATE] 
     @DistrictID        int
    AS
    BEGIN
     SET NOCOUNT ON ;
    
     BEGIN TRY
        BEGIN TRAN
               UPDATE bud
               SET bud.BudgetStateID = @BudgetStateID
               FROM [dbo].[BudgetOffice] bud
               JOIN [dbo].[vw_Office] vw
                 ON vw.OfficeID   = bud.OfficeID
               WHERE vw.DistrictID = @DistrictID;
    
               SELECT @@ROWCOUNT AS AffectedRow;
    
        COMMIT TRAN; 
     END TRY
     BEGIN CATCH
        SELECT ERROR_MESSAGE() AS ERROR
        ROLLBACK TRAN;
     END CATCH
     END
    

    @BudgetStateID 是在哪里定义的?

    【讨论】:

    • 我拿了部分代码进行演示。忘记在输入参数列表中添加@budgetstatid :)
    猜你喜欢
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 2014-07-02
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 2014-07-18
    相关资源
    最近更新 更多