Это - следование до вопроса Вложенные хранимые процедуры, содержащие шаблон ОТКАТА ВЫГОДЫ ПОПЫТКИ?
В блоке выгоды я использую хранимую процедуру для создания отчетов (повторно повышают) ошибку путем чтения из ERROR_MESSAGE (), ERROR_PROCEDURE (), ERROR_LINE (), и т.д. Как описано здесь у меня также есть проверка так, чтобы она могла определить, была ли ошибка уже повторно брошена (это происходит с вложенными хранимыми процедурами, поскольку информация об ошибке передается через каждый блок ВЫГОДЫ ПОПЫТКИ).
То, что я хотел бы сделать, или непосредственно в 'ReportError', или косвенно с моим шаблоном (как описано в первом вопросе), является рекордным отслеживание стека - поэтому, когда ReportError обнаруживает, что это - receving ошибка, брошенная отдельно, это добавляет следующий уровень стека к сообщению об ошибке. Это помогло бы мне избежать случаев, где я вижу, что сообщение об ошибке прибывает из некоторой небольшой служебной хранимой процедуры без любого способа знать то, что назвало его. Если я пытаюсь делать это непосредственно в ReportError, он перестал работать, начиная с повторно брошенных сообщений об ошибке сам как прибывающий из ReportError - только исходная ошибка видима.
Есть ли некоторый путь к ReportError для выполнения отслеживания стека в SQL Server, не передавая аргумент каждой хранимой процедуре, и вручную не поддерживая такую трассировку с #temp таблицей? В основном я хочу рекурсивный вызов ERROR_PROCEDURE () и ERROR_LINE ().
Хорошо, я добавлю нашу ошибку обратно в: -)
Функции _% () видны на область улова блокировать. Это означает, что вы можете использовать их в хранимом вызове Proc или Function в каждом блоке 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 ()
Если вы хотите
Ограниченным ответом на это будет передача OBJECT_NAME(@@PROCID) в процедуру ReportError - когда ReportError обнаруживает, что получает рекурсивную ошибку (ошибка, брошенная сама по себе), он может использовать это значение и добавить его к сообщению об ошибке, предоставив частичную трассу стека (трасса стека не будет иметь номеров строк, кроме первого элемента)
.