Как вывести весь стек перехватываемого исключения в EXCEPTION?
Предположим такой код:
declare
PROCEDURE p1
AS
BEGIN
RAISE no_data_found;
END;
PROCEDURE p2
AS
BEGIN
RAISE no_data_found;
END;
PROCEDURE p
AS
BEGIN
p1;
p2;
EXCEPTION
WHEN OTHERS /*no_data_found*/ THEN
RAISE;
END;
BEGIN
p;
end;
При выполнении его получаю ошибку :
ORA-01403: no data found
ORA-06512: at line 21
ORA-06512: at line 25
По такому стеку не понятно, в какой именно процедуре возникло исключение, так как оно перехватывается в процедуре p.
Вопрос, как элегантно реализовать EXCEPTION, чтобы при получении ошибки, выводился полный стек?
Для того, чтобы быстро понять в какой именно из вложенных процедур, в данном случае p1 или p2, вызвался RAISE. Вложенность процедур может быть любой.
Ответы (1 шт):
Возможно стоит устаревший клиент. У меня получается полный стек исключения:
SQL> run
1 declare
2 PROCEDURE p1
3 AS
4 BEGIN
5 RAISE no_data_found;
6 END;
7
8 PROCEDURE p2
9 AS
10 BEGIN
11 RAISE no_data_found;
12 END;
13
14 PROCEDURE p
15 AS
16 BEGIN
17 p1;
18 p2;
19 EXCEPTION
20 WHEN OTHERS /*no_data_found*/ THEN
21 RAISE;
22 END;
23
24 BEGIN
25 p;
26* end;
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 21
ORA-06512: at line 5
ORA-06512: at line 17
ORA-06512: at line 25
Видно, что при вызове процедуры P1 в 17 строке произошло исключение в 5 строке.
Если интереснна обработка исключения внутри блока EXCEPTION, то следует воспользоваться функциями пакета DBMS_UTILITY, или более нового UTL_CALL_STACK.
Вот простой пример:
create or replace package pack as
procedure p1;
procedure p2;
procedure p;
end;
/
create or replace package body pack as
procedure p1 as
begin raise no_data_found; -- 3 строка
end;
procedure p2 as
begin raise no_data_found;
end;
procedure p as
begin
p1; -- 10 строка
p2;
exception when others then
dbms_output.put_line (sqlerrm||chr(10)||dbms_utility.format_error_backtrace ());
end;
end pack;
/
Даст обратный стек исключения, ошибка в 3 строке при вызове процедуры p1 в 10 строке:
begin
pack.p;
end;
/
ORA-01403: no data found
ORA-06512: at "ME.PACK", line 3
ORA-06512: at "ME.PACK", line 10