|
Программирование >> Oracle
Пакет DBMS UTILITY 1725 Procedure created. scott8TKYTE816> create or replace procedure p3 2 as 3 begin 4 p2; 5 end; Procedure created. scott@TKYTE816> exec p3 BEGIN p3; END; EBROR at line 1: ORA-06501: PL/SQL: program error ORA-06512: at SCOTT.P1 , line 4 ORA-06512: at SCOTT.P2 , line 4 ORA-06512: at SCOTT.P3 , line 4 ORA-06512: at line 1 В случае возникновения ошибки, если она не перехвачена обработчиком, выдается весь стек ошибок, который можно будет использовать в программе, использующей интерфейсы Pro*C, OCI, JDBC и т.п. Можно ожидать, что функция DBMS UTILITY.FORMAT ERROR STACK будет возвращать подобную информацию. Оказывается, однако, что эту важную информацию она теряет: scottQTKYTE816> create or replace procedure p3 2 as 3 begin 4 p2; 5 exception 6 when others then 7 dbms output.put line(dbms utility.format error stack); 8 end; Procedure created. scott@TKYTE816> exec p3 ORA-06501: PL/SQL: program error PL/SQL procedure successfully completed. Как видите, при вызове функции FORMAT ERROR STACK информация стека ошибок потеряна! Функция возвращает ту же информацию, что и SQLERRM: scott@TKYTE816> create or replace procedure p3 2 as 3 begin 4 p2; 5 exception 6 when others then 7 dbms output.put line(sqlerrm); 1726 Приложение А 8 end; Procedurecreated. scott@TKYTE816> exec p3 ORA-06501: PL/SQL: program error PL/SQL procedure successfully completed. Я утверждал, что функция FORMAT ERROR STACK обеспечивает меньше возможностей, чем SQLERRM. Дело в том, что функция SQLERRM может не только возвращать сообщение о текущей ошибке, но и сообщение о любой ошибке, код которой передан как параметр: scott@TKYTE816> exec dbms output.put line(sqlerrm(-l)); ORA-00001: unique constraint (.) violated PL/SQL procedure successfully completed. К сожалению, сейчас нет способа получить весь стек ошибок в языке PL/SQL. Чтобы получить фактический номер строки кода, при выполнении которой произошла ошибка, приходится пропускать фатальные ошибки до вызывающей процедуры в клиентском приложении. Функция FORMAT CALL STACK К счастью, эта функция действительно очень полезна - не то, что функция FORMAT ERROR STACK. Она возвращает текущий стек вызовов. С ее помощью можно написать ряд полезных утилит, например MY CALLER и WHO AM I. (Они вгда-ют информацию о том, откуда вызвана текущая подпрограмма и как она называется - прим. научн. ред.) Эти утилиты вызывают рассматриваемую функцию чтобы определить, из какой строки какой подпрограммы вызваны. Такие сведения могут пригодиться при отладке и регистрации. Кроме того, процедуры могут работать по-разному, в зависимости от того, кто их вызвал и в какой среде. Прежде чем представить код моих утилит MY CALLER и WHO AM I, давайте посмотрим, какую информацию можно получить в стеке вызовов и какие результаты должны выдавать эти утилиты. Если использовать процедуры P1, P2, P3 из представленного ранее примера и переписать процедуру P1 следующим образом: scott@TKYTE816> create or replace procedure p1 2 as 3 l owner varchar2(3 0) ; 4 l name varchar2(3 0) ; 5 l lineno number; 6 l type varchar2(3 0) ; 7 begin 8 dbms output.put line (-) ; 9 dbms output.put line(dbms utility.format call stack) ; 10 dbms output.put line (-) ; 11 who called me(l owner, l name, l lineno, l type); 12 dbms output.put line(l type 13 l owner . l name 14 15 16 17 18 19 dbms output.put line (- dbms output.put line(who am i); dbms output.put line(- raise program error; l lineno Пакет DBMS UTILITY 1727 end; Procedure created, мы получим следующий результат: scott@TKYTE816> exec p3 -PL/SQL Call Stack - object handle 2fl91e0 39f0a9c 3aae318 3a3461c line object number name 9 procedure SCOTT.P1 4 procedure SCOTT.P2 4 procedure SCOTT.P3 anonymous block PROCEDURE SCOTT.P2(4) SCOTT.Pl(16) BEGIN p3; END; ERROR at line 1: ORA-06501: PL/SQL: program error ORA-06512: at SCOTT.P2 , line 8 ORA-06512: at SCOTT.P3 , line 4 ORA-06512: at line 1 Итак, мы видим весь стек вызовов для процедуры P1. Показано, что процедура P1 б1ла вызвана процедурой P2, процедура P2 б1ла вызвана процедурой P3, которая, в свою очередь, б1ла вызвана из анонимного блока. Кроме того, в программном коде можно выяснить, что процедура P1 была вызвана в строке 4 процедуры SCO.P2. Наконец, можно вхяснить, что выполняется сейчас процедура SCO.Pl. Теперь, разобравшись, как выглядит стек вызовов и что мы хотим получить, можно представить код, позволяющий это сделать: replace function my caller return varchar2 tkyte@TKYTE816> create 2 3 as 4 5 owner name lineno caller t call stack varchar2(30); varchar2(30); number; varchar2(30); varchar2(4096) number; default dbms utility.format call stack; found stack BOOLEAN default FALSE;
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |