【问题标题】:Handle message return from calling stored procedure in try.. catch -- T-SQL在try..catch中处理调用存储过程返回的消息——T-SQL
【发布时间】:2022-01-06 20:52:08
【问题描述】:

我在 try..catch 中调用旧版存储过程。当存储过程以简单的语言向用户返回带有错误详细信息的消息时,我的try..catch 无法检测到。

遗留存储过程返回的消息如下:

错误状态:1,错误严重程度:16,错误编号:50000 错误行: 33、错误过程:LegacyStoredProcedure
错误信息:请多多关照...... 回滚事务。

有没有办法检测存储过程返回的消息?

BEGIN TRY
  BEGIN Transaction
    .....
    EXEC *thelegacySP*
    .....
  COMMIT Transaction
END TRY
BEGIN CATCH
        DECLARE
          @ErrorLine        int,
          @ErrorMessage     nvarchar(2048),
          @ErrorNumber      int,
          @ErrorProcedure   nvarchar(126),
          @ErrorSeverity    int,
          @ErrorState       int;
                      
    SELECT  @ErrorLine = ERROR_LINE(),
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorNumber = ERROR_NUMBER(),
            @ErrorProcedure = '*MyNewSP*',
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE(),
            @now = GETDATE()
    
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)
    IF @@TRANCOUNT > 0 
      ROLLBACK TRANSACTION    
    INSERT INTO Validation.Table
      VALUES(
            @ErrorProcedure
            ,@ErrorNumber
            ,@ErrorMessage
            ,@ErrorSeverity
            ,@ErrorState
            ,@ErrorLine
            ,@now
      )
END CATCH

【问题讨论】:

标签: sql sql-server tsql stored-procedures error-handling


【解决方案1】:

实现错误处理的最佳方法是使用THROW; 重新引发原始错误

SET XACT_ABORT ON;

BEGIN TRY
  BEGIN TRAN;
    .....
    EXEC *thelegacySP*
    .....
  COMMIT;
END TRY
BEGIN CATCH
    INSERT INTO Validation.Table (
            ErrorProcedure
            ,ErrorNumber
            ,ErrorMessage
            ,ErrorSeverity
            ,ErrorState
            ,ErrorLine
            ,Date)
    VALUES (ERROR_LINE(),
            ERROR_MESSAGE(),
            ERROR_NUMBER(),
            '*MyNewSP*',
            ERROR_SEVERITY(),
            ERROR_STATE(),
            GETDATE());
    
    IF @@TRANCOUNT > 0 
      ROLLBACK TRANSACTION    

    THROW;
END CATCH;

请注意,仅当您要记录错误时才需要此代码。

如果您不想记录错误,则根本不应该使用TRY/CATCH。只需要SET XACT_ABORT ON;就可以保证自动回滚

SET XACT_ABORT ON;

BEGIN TRAN;
    .....
EXEC *thelegacySP*
    .....
COMMIT;

你可能会发现Erland Sommarskog's articles,内容丰富,如果相当冗长

【讨论】:

    猜你喜欢
    • 2014-10-25
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多