将catch中的错误详细信息传递给日志存储过程

时间:2011-03-29 21:31:07

标签: sql tsql sql-server-2008 stored-procedures

我在SQL Server中使用try catch有一个存储过程。我想在catch循环中做的是调用我自己的Stored过程来记录所有错误变量,如下所示:

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()

我想要做的是只有一行用参数调用存储过程,因为我将在许多存储过程中使用它,并且不希望有很多代码设置错误参数(我会有更多比这三个)在我尝试捕获的每个存储过程中。

有人知道如何将这些传递给另一个存储过程吗?

此致 约翰

2 个答案:

答案 0 :(得分:2)

不幸的是,T-SQL不是DRY代码重用紧凑语法程序员友好语言。你必须以艰难的方式去做,这意味着在每个CATCH块内至少编写4-5行代码。此外,您还需要考虑事务语义:它是否已回滚?或者更糟糕的是,你是否处于注定的交易中?这就是为什么我创建了这个T-SQL error handling template

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

它比你想要的更长吗?我打赌。它是正确的?是。

最后,您如何处理事务环境中的日志记录?如果出现错误,插入到日志表中的内容将与其他所有内容一起回滚。有时这是可以的,其他时间甚至是需要的,但有时是有问题的。其中一个最有趣的解决方案是Simon Sabin的Logging messages during a transaction

答案 1 :(得分:1)

尝试更改log.LogError过程,以便直接访问ERROR_NUMBER()和其他错误函数。 documentation中有一个例子。