Как получить трассировку стека для оригинального исключения в Oracle / PL из SQL-исключения?
У меня возникла проблема, когда исходная трассировка стека теряется, когда я ловлю исключение, а затем поднимаю его.
- Исключение выдается в proc_a
- Поймай исключение.
- Выполнить откат.
- Поднимите исключение.
- Поймать исключение (родительский блок)
- Трассировка стека печати:
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
Порядок сообщений немного отличается, но информация все еще там.