dbms_utility.format_error_backtrace - отслеживание ошибок в pl/sql
Статьи про Oracle -> Программирование
dbms_utility.format_error_backtrace - отслеживание ошибок в pl/sql
v:1.0 03.12.2011
Петрелевич Сергей
Часто при обработке исключений в pl/sql разработчики ограничиваются использованием встроенной функции sqlerrm, однако в Oracle есть и другие интересные средства для обработки ошибок. Одно из этих средств - функция dbms_utility.format_error_backtrace.
Функция dbms_utility.format_error_backtrace возвращает список вызовов функций и процедур от места генерации исключения до места его обработки.
Для рассмотрения работы dbms_utility.format_error_backtrace создадим тестовый пакет с процедурами, которые подобно матрешкам вызываются одна из другой.
create or replace package Err as
procedure testProc1;
procedure testProc2;
procedure testProc3;
procedure testProc4;
end;
Пример 1. dbms_utility.format_error_backtrace в каждом обработчике исключений
В первом примере функция dbms_utility.format_error_backtrace вставлена в обработчики исключений каждой процедуры.
- create or replace package body Err as
-
- procedure testProc1 is
- begin
- dbms_output.put_line('testProc1');
- testProc2;
- exception
- when others then
- dbms_output.put_line('testProc1 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- end;
-
- procedure testProc2 is
- begin
- dbms_output.put_line('testProc2');
- testProc3;
- exception
- when others then
- dbms_output.put_line('testProc2 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- raise;
- end;
-
- procedure testProc3 is
- begin
- dbms_output.put_line('testProc3');
- testProc4;
- exception
- when others then
- dbms_output.put_line('testProc3 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- raise;
- end;
-
- procedure testProc4 is
- begin
- dbms_output.put_line('testProc4');
- raise no_data_found;
- exception
- when others then
- dbms_output.put_line('testProc4 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- raise;
- end;
-
- end;
begin
err.testProc1;
end;
testProc1 testProc2 testProc3 testProc4 testProc4 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 38 testProc3 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 43 ORA-06512: at "DEV.ERR", line 27 testProc2 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 32 ORA-06512: at "DEV.ERR", line 16 testProc1 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 21 ORA-06512: at "DEV.ERR", line 6Видно, что функция dbms_utility.format_error_backtrace выводит пакет, в котором сработало исключение и номер строки. Надо отметить, что в данном примере и строки вида dbms_output.put_line('testProc3 error:'||dbms_utility.format_error_stack); отлично формируют стек ошибки, dbms_utility.format_error_backtrace лишь уточняет конкретную строку.
Пример 2. dbms_utility.format_error_backtrace в стартовой процедуре, во всех процедурах есть обработчики исключений
Рассмотрим другой пример.
На этот раз dbms_utility.format_error_backtrace будет в стартовой процедуре, из которой вызываются другие.
В других процедурах будут обработчики исключений, но в них не будет вызова dbms_utility.format_error_backtrace.
- create or replace package body Err as
-
- procedure testProc1 is
- begin
- dbms_output.put_line('testProc1');
- testProc2;
- exception
- when others then
- dbms_output.put_line('testProc1 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- end;
-
- procedure testProc2 is
- begin
- dbms_output.put_line('testProc2');
- testProc3;
- exception
- when others then
- raise;
- end;
-
- procedure testProc3 is
- begin
- dbms_output.put_line('testProc3');
- testProc4;
- exception
- when others then
- raise;
- end;
-
- procedure testProc4 is
- begin
- dbms_output.put_line('testProc4');
- raise no_data_found;
- exception
- when others then
- raise;
- end;
-
- end;
begin
err.testProc1;
end;
testProc1 testProc2 testProc3 testProc4 testProc1 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 19 ORA-06512: at "DEV.ERR", line 6Информации не очень-то много. Складывается впечатление, что ошибка возникла в 19 строке кода, хотя правильное место - строка 34. Причина в том, что dbms_utility.format_error_backtrace показывает стек не с места фактического появления ошибки, а с мест ее последнего перехвата. В нашем случае это процедура proc2, строка 21.
Получается, в этом случае dbms_utility.format_error_backtrace ни только не помогает, а еще и мешает, запутывает следы.
Пример 3. dbms_utility.format_error_backtrace в стартовой процедуре, в других процедурах нет обработчиков исключений
На этот раз все исключения обрабатываются только в одном месте - вызывающей функции, и только в ней используется dbms_utility.format_error_backtrace.
- create or replace package body Err as
-
- procedure testProc1 is
- begin
- dbms_output.put_line('testProc1');
- testProc2;
- exception
- when others then
- dbms_output.put_line('testProc1 error:'||dbms_utility.format_error_stack);
- dbms_output.put_line('stack:'||dbms_utility.format_error_backtrace);
- end;
-
- procedure testProc2 is
- begin
- dbms_output.put_line('testProc2');
- testProc3;
- end;
-
- procedure testProc3 is
- begin
- dbms_output.put_line('testProc3');
- testProc4;
- end;
-
- procedure testProc4 is
- begin
- dbms_output.put_line('testProc4');
- raise no_data_found;
- end;
-
- end;
begin
err.testProc1;
end;
testProc1 testProc2 testProc3 testProc4 testProc1 error:ORA-01403: no data found stack:ORA-06512: at "DEV.ERR", line 32 ORA-06512: at "DEV.ERR", line 25 ORA-06512: at "DEV.ERR", line 18 ORA-06512: at "DEV.ERR", line 7На этот раз информации куда больше. По выводу функции dbms_utility.format_error_backtrace можно точно отследить, что ошибка появилась в функции testProc4, строка 32, и какие процедуры выполнялись.
Из этих примеров можно вывести две основные тактики применения dbms_utility.format_error_backtrace.
Эту функцию надо вставлять в каждый обработчик исключений или обрабатывать все исключения в одной точке - стартовой процедуре(функции).
Метки: PL/SQL
Внимание.
Комментировать могут только зарегистрированные пользователи.
Возможно использование следующих HTML тегов: <a>, <b>, <i>, <br>.