Программирование >>  Oracle 

1 ... 431 432 433 [ 434 ] 435 436 437 ... 469


Пакет 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;



1 ... 431 432 433 [ 434 ] 435 436 437 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика