Запись стека вызовов SQL Server при создании отчетов об ошибках

Это - следование до вопроса Вложенные хранимые процедуры, содержащие шаблон ОТКАТА ВЫГОДЫ ПОПЫТКИ?

В блоке выгоды я использую хранимую процедуру для создания отчетов (повторно повышают) ошибку путем чтения из ERROR_MESSAGE (), ERROR_PROCEDURE (), ERROR_LINE (), и т.д. Как описано здесь у меня также есть проверка так, чтобы она могла определить, была ли ошибка уже повторно брошена (это происходит с вложенными хранимыми процедурами, поскольку информация об ошибке передается через каждый блок ВЫГОДЫ ПОПЫТКИ).

То, что я хотел бы сделать, или непосредственно в 'ReportError', или косвенно с моим шаблоном (как описано в первом вопросе), является рекордным отслеживание стека - поэтому, когда ReportError обнаруживает, что это - receving ошибка, брошенная отдельно, это добавляет следующий уровень стека к сообщению об ошибке. Это помогло бы мне избежать случаев, где я вижу, что сообщение об ошибке прибывает из некоторой небольшой служебной хранимой процедуры без любого способа знать то, что назвало его. Если я пытаюсь делать это непосредственно в ReportError, он перестал работать, начиная с повторно брошенных сообщений об ошибке сам как прибывающий из ReportError - только исходная ошибка видима.

Есть ли некоторый путь к ReportError для выполнения отслеживания стека в SQL Server, не передавая аргумент каждой хранимой процедуре, и вручную не поддерживая такую трассировку с #temp таблицей? В основном я хочу рекурсивный вызов ERROR_PROCEDURE () и ERROR_LINE ().

6
задан Community 23 May 2017 в 10:29
поделиться

2 ответа

Хорошо, я добавлю нашу ошибку обратно в: -)

Функции _% () видны на область улова блокировать. Это означает, что вы можете использовать их в хранимом вызове 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 () Если вы хотите

1
ответ дан 17 December 2019 в 22:13
поделиться

Ограниченным ответом на это будет передача OBJECT_NAME(@@PROCID) в процедуру ReportError - когда ReportError обнаруживает, что получает рекурсивную ошибку (ошибка, брошенная сама по себе), он может использовать это значение и добавить его к сообщению об ошибке, предоставив частичную трассу стека (трасса стека не будет иметь номеров строк, кроме первого элемента)

.
0
ответ дан 17 December 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: