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