Восстановление ошибки T-SQL - PullRequest
0 голосов
/ 08 ноября 2011

В следующей процедуре, которую я нашел здесь :

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) и строчки (% 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.
          );

Я сделал два небольших изменения в подпрограмме: одно, чтобы уменьшить серьезность, если> 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 <19". Я не слишком обеспокоен тем, что если возникнет ошибка> 18, то ошибка будет переброшена с серьезностью 18. В любом случае, я прекращаю работу, и исходная серьезность будет зарегистрирована. Есть ли что-то еще в этой рутине, о которой мне нужно беспокоиться?

1 Ответ

3 голосов
/ 08 ноября 2011

Надеюсь, это поможет!

Вы на правильном пути, ErrorMessage - строка шаблона, которая используется RAISERROR. Грамматическая структура RAISERROR поможет разобраться в путанице:

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

Первые три обязательных аргумента - это строка шаблона сообщения (msg_str), серьезность и состояние. За ними следуют необязательные аргументы, которые заменят параметры подстановки в msg_str.

Итак, код позволяет:

msg_str be ErrorMessage

серьезность будет ErrorSeverity

состояние будет ErrorState

аргументы: RethrownErrorNumber, ErrorSeverity, ErrorState, ErrorProcedure, ErrorLine

Ссылка http://msdn.microsoft.com/en-us/library/ms178592.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...