Передача подробностей ошибки из catch в хранимую процедуру журнала - PullRequest
1 голос
/ 30 марта 2011

У меня есть хранимая процедура в SQL Server с try catch.В цикле catch я хочу вызвать собственную хранимую процедуру для регистрации всех переменных ошибок, например:

BEGIN TRY
    -- Generate a divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    exec log.LogError ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_MESSAGE();
END CATCH;

Когда я запускаю это, я получаю ошибку в скобках.

Я могу запустить:

select ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_MESSAGE();

Я также могу сделать

print ERROR_NUMBER()

Я хочу сделать только одну строку, которая вызывает хранимую процедуру с параметрами, потому чтоУ меня это будет во многих хранимых процедурах, и я не хочу иметь много кода, устанавливающего параметры ошибок (у меня их будет больше, чем три) в каждой хранимой процедуре, где у меня есть try-catch.

Кто-нибудьзнаете, как я могу передать их в другую хранимую процедуру?

С уважением, Иоганн

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

К сожалению, T-SQL не является DRY-кодом для повторного использования компактного синтаксиса, дружественного программисту.Вы должны сделать это трудным путем, и это подразумевает написание минимум 4-5 строк кода внутри каждого блока CATCH.Кроме того, необходимо учитывать и семантику транзакций: откат произошел или нет?Или хуже, вы в обреченной сделке?Вот почему я создал этот шаблон обработки ошибок T-SQL :

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER()
                   , @message = ERROR_MESSAGE()
                   , @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
        return;
    end catch   
end

Это длиннее, чем вы ищете?Держу пари.Это правильно?Да.

И, наконец, как вы ведете регистрацию в транзакционной среде?Вставки в таблицу журнала будут откатываться вместе со всем остальным в случае ошибки.Иногда это нормально, иногда даже желательно, но иногда проблематично.Одним из наиболее интересных решений является регистрация сообщений во время транзакции .

Саймона Сабина.
1 голос
/ 30 марта 2011

Попробуйте изменить процедуру log.LogError, чтобы она напрямую обращалась к ERROR_NUMBER () и другим функциям ошибок. В документации есть пример .

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