报告错误时记录SQL Server调用堆栈

时间:2010-01-18 15:18:12

标签: sql-server-2005 tsql error-handling try-catch stack-trace

这是问题的后续行动 Nested stored procedures containing TRY CATCH ROLLBACK pattern?

在catch块中,我使用存储过程通过读取ERROR_MESSAGE(),ERROR_PROCEDURE(),ERROR_LINE()等来报告(重新报告)错误。如上所述here我还有一个检查,以便它可以确定错误是否已经被重新抛出(这种情况发生在嵌套的存储过程中,因为错误信息通过每个TRY CATCH块向下传递)。

我想做的事情,无论是直接在'ReportError'中,还是间接在我的模式中(如第一个问题中所述),都会记录一个堆栈跟踪 - 所以当ReportError检测到它正在接收一个错误时它自己抛出的错误,它将堆栈的下一级附加到错误消息。这可以帮助我避免我看到来自某个小实用程序存储过程的错误消息的情况,而无需知道调用它的内容。如果我尝试直接在ReportError中执行此操作,则会失败,因为重新抛出错误会将自身报告为来自ReportError - 只有原始错误可见。

ReportError是否有某种方法可以在SQL Server中执行堆栈跟踪,而无需将参数传递给每个存储过程,也无需使用#temp表手动维护这样的跟踪?基本上我想要一个ERROR_PROCEDURE()和ERROR_LINE()的递归调用。

2 个答案:

答案 0 :(得分:1)

好的,我将把错误处理添加回来: - )

ERROR _%()函数对CATCH块的范围可见。这意味着您可以在每个CATCH块中的存储过程或函数调用中使用它们

使用嵌套的存储过程,了解导致错误的原因以及记录错误的内容非常有用

...
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION
    EXEC dbo.MyExceptionHandler @@PROCID, @errmsg OUTPUT;
    RAISERROR (@errmsg, 16, 1);
END CATCH

---with this handler (cut down version of ours)
CREATE PROCEDURE dbo.MyExceptionHandler
    @CallerProcID int,
    @ErrorMessage varchar(2000) OUTPUT
WITH EXECUTE AS OWNER --may be needed to get around metadata visibility issues of OBJECT_NAME
AS
SET NOCOUNT, XACT_ABORT ON;

BEGIN TRY
    SET @ErrorMessage = --cutdown
            CASE
                WHEN @errproc = @callerproc THEN        --Caller = error generator
                        --build up stuff

                ELSE    --Just append stuff             --Nested error stack
            END;

    IF @@TRANCOUNT = 0
        INSERT dbo.Exception (Who, TheError, WhatBy, LoggedBy)
        VALUES (ORIGINAL_LOGIN()), RTRIM(ERROR_MESSAGE()), ERROR_PROCEDURE(), OBJECT_NAME(@CallerProcID));
END TRY
BEGIN CATCH
   --and do what exactly?
END CATCH
GO

无论如何,这是基本的想法:每个CATCH块都很简单,工作在错误处理程序中继续进行。如果你想

,请附加ERROR_NUMBER()

答案 1 :(得分:0)

对此的有限答案是将OBJECT_NAME(@@ PROCID)传递给ReportError过程 - 当ReportError检测到它正在收到递归错误(自身抛出的错误)时,它可以使用此值并将其附加到错误消息,提供部分堆栈跟踪(堆栈跟踪不包含除第一个元素之外的行号)