Как получить трассировку стека для оригинального исключения в Oracle / PL из SQL-исключения?

У меня возникла проблема, когда исходная трассировка стека теряется, когда я ловлю исключение, а затем поднимаю его.

  1. Исключение выдается в proc_a
  2. Поймай исключение.
  3. Выполнить откат.
  4. Поднимите исключение.
  5. Поймать исключение (родительский блок)
  6. Трассировка стека печати: SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999)

Пример:

DECLARE
BEGIN
   DECLARE
      lv_val VARCHAR2(1);
   BEGIN
      SELECT dummy INTO lv_val -- Line# 6 (desired)
      FROM   dual
      WHERE  dummy = 'FFF';
   EXCEPTION
      WHEN OTHERS THEN
         --DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999));
         RAISE; -- Line# 12 (actual)
   END;
EXCEPTION
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999));
END;
/

Желаемый результат:

Номер строки для исходного исключения (шаг 1).

ORA-01403: no data found
ORA-06512: at line 6

или же

ORA-01403: no data found
ORA-06512: at line 12
Caused By:
ORA-01403: no data found
ORA-06512: at line 6

Фактический результат:

Номер строки для поднятия (шаг 4).

ORA-01403: no data found
ORA-06512: at line 12

Дополнительные попытки потерпели неудачу:

SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_STACK()

ORA-01403: no data found
ORA-01403: no data found

SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_CALL_STACK()

ORA-01403: no data found
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
0xee1cbd68        18  anonymous block

1 ответ

В вашем внутреннем обработчике исключений вместо использования RAISE использовать, использовать RAISE_APPLICATION_ERROR Процедура прохождения его результатов dbms_utility.format_error_backtrace Функция для получения исходного номера строки:

BEGIN
   DECLARE
      lv_val VARCHAR2(1);
   BEGIN
      SELECT dummy INTO lv_val -- Line# 6 (desired)
      FROM   dual
      WHERE  dummy = 'FFF';
   EXCEPTION
      WHEN OTHERS THEN
         RAISE_APPLICATION_ERROR(-20001, dbms_utility.format_error_backtrace,true);
   END;
EXCEPTION
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999));
END;
/

Без внешнего обработчика исключений вы получите следующий отчет об ошибке:

Error report -
ORA-20001: ORA-06512: at line 5
ORA-06512: at line 10
ORA-01403: no data found

С внешним обработчиком исключений вы получите следующее:

ORA-20001: ORA-06512: at line 5
ORA-01403: no data found
ORA-06512: at line 10

Порядок сообщений немного отличается, но информация все еще там.

Другие вопросы по тегам