重新抛出T-SQL错误

时间:2011-11-08 00:34:18

标签: sql-server-2008 tsql

在以下例程中我找到了here

ALTER PROCEDURE [dbo].[usp_RethrowError]
AS -- Return if there is no error information to retrieve.
    IF ERROR_NUMBER() IS NULL
        RETURN;

    DECLARE @ErrorMessage           NVARCHAR(4000),
            @OriginalErrorNumber    INT,
            @RethrownErrorNumber    INT,
            @ErrorSeverity          INT,
            @ErrorState             INT,
            @ErrorLine              INT,
            @ErrorProcedure         NVARCHAR(200);

    -- Assign variables to error-handling functions that 
    -- capture information for RAISERROR.
    SELECT
         @OriginalErrorNumber    = ERROR_NUMBER()
        ,@ErrorSeverity          = ERROR_SEVERITY()
        ,@ErrorSeverity          = ERROR_SEVERITY()
        ,@ErrorState             = ERROR_STATE()
        ,@ErrorLine              = ERROR_LINE()
        ,@ErrorProcedure         = ISNULL(ERROR_PROCEDURE(),'-');

    --Severity levels from 0 through 18 can be specified by any user. 
    --Severity levels from 19 through 25 can only be specified by members of the sysadmin fixed server role or users with ALTER TRACE permissions
    IF @OriginalErrorNumber < 19 
        SET @RethrownErrorNumber = @OriginalErrorNumber
    ELSE
        SET @RethrownErrorNumber = 18

    -- Building the message string that will contain original
    -- error information.
    SELECT
        @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 'Message: ' + ERROR_MESSAGE();


    -- Raise an error: msg_str parameter of RAISERROR will contain
    -- the original error information.
    RAISERROR (@ErrorMessage,
               @ErrorSeverity,
               @ErrorState,
               @RethrownErrorNumber,        -- parameter: original error number or 18, if the original was >=19.
               @ErrorSeverity,              -- parameter: original error severity.
               @ErrorState,                 -- parameter: original error state.
               @ErrorProcedure,             -- parameter: original error procedure name.
               @ErrorLine                   -- parameter: original error line number.
              );

有人可以解释以下内容:

 SELECT
        @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 'Message: ' + ERROR_MESSAGE();

我意识到%的出现是有符号整数(%d)和strinf(%s)的占位符,但我不明白哪些变量映射到这些占位符。它们似乎没有映射到RAISERROR调用中指定的参数:

RAISERROR (@ErrorMessage,
           @ErrorSeverity,
           @ErrorState,
           @RethrownErrorNumber,        -- parameter: original error number or 18, if the original was >=19.
           @ErrorSeverity,              -- parameter: original error severity.

       @ErrorState,                 -- parameter: original error state.
       @ErrorProcedure,             -- parameter: original error procedure name.
       @ErrorLine                   -- parameter: original error line number.
          );

我对子程序做了两处小改动,一个是为了降低严重性,如果&gt; 19和另一个使用原始状态而不是总是传递1。

如果你们因为我的微小变化而没有拍摄这个例程,我会在重新投入之前将记录错误信息添加到用户表中。

致电:

DECLARE @Zero INT
SET @Zero = 0

BEGIN TRY
 SELECT 5 / @Zero
END TRY
BEGIN CATCH
 PRINT 'We have an error...'
 EXEC usp_RethrowError
END CATCH

跟进问题:

1)上面的链接提到此例程不适用于死锁。有什么理由吗?

2)我添加了“IF @OriginalErrorNumber&lt; 19”部分。我并不太担心如果出现错误&gt; 18错误将被重新发生,则严重性为18.无论如何,我会中止并且将记录原始严重性。这个例程还有什么我需要担心的吗?

1 个答案:

答案 0 :(得分:3)

希望这会有所帮助!

您走在正确的轨道上,ErrorMessage是RAISERROR使用的模式字符串。查看RAISERROR的语法结构将消除混淆:

RAISERROR ( { msg_id | msg_str | @local_variable }
    { ,severity ,state }
    [ ,argument [ ,...n ] ] )
    [ WITH option [ ,...n ] ]

前三个必需参数是消息模式字符串(msg_str),严重性和状态。接下来是可选参数,它们将替换msg_str中的替换参数。

所以代码允许:

msg_str是ErrorMessage

严重性为ErrorSeverity

状态为ErrorState

参数是RethrownErrorNumber,ErrorSeverity,ErrorState,ErrorProcedure,ErrorLine

参考http://msdn.microsoft.com/en-us/library/ms178592.aspx