【问题标题】:Passing error details from catch into log stored procedure将 catch 中的错误详细信息传递到日志存储过程中
【发布时间】:2011-03-29 21:31:06
【问题描述】:

我在 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 的每个存储过程中。

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

问候, 约翰

【问题讨论】:

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


    【解决方案1】:

    不幸的是,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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2012-12-22
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 2017-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多