Dav*_*vid 6 t-sql error-handling sql-server-2005 try-catch stack-trace
这是一个包含TRY CATCH ROLLBACK模式的嵌套存储过程的问题的后续跟进 ?
在catch块中,我使用存储过程通过读取ERROR_MESSAGE(),ERROR_PROCEDURE(),ERROR_LINE()等来报告(重新加载)错误.如此处所述,我还有一个检查,以便它可以确定错误是否有已经被重新抛出(这种情况发生在嵌套的存储过程中,因为错误信息通过每个TRY CATCH块向下传递).
我想做的是,直接在'ReportError'中,或者间接在我的模式中(如第一个问题中所述),记录一个堆栈跟踪 - 所以当ReportError检测到它正在接收自己抛出的错误时,它会追加堆栈的下一级到错误消息.这可以帮助我避免我看到来自某个小实用程序存储过程的错误消息的情况,而无需知道调用它的内容.如果我尝试直接在ReportError中执行此操作,则会失败,因为重新抛出错误会将自身报告为来自ReportError - 只有原始错误可见.
ReportError是否有一些方法可以在SQL Server中执行堆栈跟踪,而无需将参数传递给每个存储过程,也无需使用#temp表手动维护这样的跟踪?基本上我想要一个ERROR_PROCEDURE()和ERROR_LINE()的递归调用.
好的,我将添加我们的错误处理:-)
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
Run Code Online (Sandbox Code Playgroud)
无论如何,这是基本思想:每个 CATCH 块都很简单,工作在错误处理程序中继续进行。例如,ERROR_NUMBER()如果您愿意,请追加