问题描述
嗨,汤姆,
我想知道是否有任何方法来编码异常处理程序,以捕获特定的PLSQL或SQL语句,这些语句将导致在编写异常处理程序的同一个PLSQL块内的异常。
例如,在PLSQL块中说下面的语句,
这将导致明显的异常,并且此特定语句应与解析值 (此语句右侧负责异常的实际值) 一起捕获,并从异常处理程序中记录。
同样,在下一次运行期间,同一块中的另一个SQL语句将导致某些异常,并且该SQL语句的解析版本将从异常处理程序中捕获并记录。
我知道我要问的是类似于正式的调试机制,但这是不可能实现的吗?
问候,
马诺哈尔·米什拉。
我想知道是否有任何方法来编码异常处理程序,以捕获特定的PLSQL或SQL语句,这些语句将导致在编写异常处理程序的同一个PLSQL块内的异常。
例如,在PLSQL块中说下面的语句,
v_num (a number datatype variable) :=;
这将导致明显的异常,并且此特定语句应与解析值 (此语句右侧负责异常的实际值) 一起捕获,并从异常处理程序中记录。
同样,在下一次运行期间,同一块中的另一个SQL语句将导致某些异常,并且该SQL语句的解析版本将从异常处理程序中捕获并记录。
我知道我要问的是类似于正式的调试机制,但这是不可能实现的吗?
问候,
马诺哈尔·米什拉。
专家解答
使用UTL_CALL_STACK,您可以深入了解错误 (和当前调用堆栈) 的位置,例如
因此,如果你想得到错误的语句,你可以得到深度 = 1的错误回溯,并使用行/单元名称在ALL_SOURCE中查找适当的源代码。
关于UTL_CALL_STACK的更多详细信息
https://blogs.oracle.com/oraclemagazine/sophisticated-call-stack-analysis
SQL> CREATE OR REPLACE PROCEDURE output_call_stack
2 IS
3 BEGIN
4 DBMS_OUTPUT.put_line('LexDepth Depth LineNo Name');
5 DBMS_OUTPUT.put_line(
6 '-------- ----- ------ ----');
7
8 FOR the_depth IN REVERSE 1 .. utl_call_stack.dynamic_depth()
9 LOOP
10 DBMS_OUTPUT.put_line(
11 RPAD(utl_call_stack.lexical_depth(the_depth),9)
12 || RPAD(the_depth, 5)
13 || RPAD(TO_CHAR(utl_call_stack.unit_line(the_depth),'99'),8)
14 || utl_call_stack.concatenate_subprogram(utl_call_stack.subprogram(the_depth)));
15 END LOOP;
16 END;
17 /
Procedure created.
SQL>
SQL> CREATE OR REPLACE PROCEDURE output_err_stack
2 IS
3 BEGIN
4 DBMS_OUTPUT.put_line('BakDepth Depth LineNo Name');
5 DBMS_OUTPUT.put_line(
6 '-------- ----- ------ ----');
7
8 FOR the_depth IN REVERSE 1 .. utl_call_stack.backtrace_depth()
9 LOOP
10 DBMS_OUTPUT.put_line(
11 RPAD(the_depth, 5)
12 || RPAD(TO_CHAR(utl_call_stack.backtrace_line(the_depth),'99'),8)
13 || utl_call_stack.backtrace_unit(the_depth));
14 END LOOP;
15 END;
16 /
Procedure created.
SQL>
SQL>
SQL> CREATE OR REPLACE PACKAGE pkg
2 IS
3 PROCEDURE do_stuff;
4 END;
5 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE BODY pkg
2 IS
3 PROCEDURE do_stuff
4 IS
5 PROCEDURE np1
6 IS
7 PROCEDURE np2
8 IS
9 PROCEDURE np3
10 IS x int;
11 BEGIN
12 output_call_stack;
13 x := 1/0;
14 END;
15 BEGIN
16 np3;
17 END;
18 BEGIN
19 np2;
20 END;
21 BEGIN
22 np1;
23 exception
24 when others then
25 output_err_stack;
26 END;
27 END;
28 /
Package body created.
SQL> set serverout on
SQL> BEGIN
2 pkg.do_stuff;
3 END;
4 /
LexDepth Depth LineNo Name
-------- ----- ------ ----
0 6 2 __anonymous_block
1 5 22 PKG.DO_STUFF
2 4 19 PKG.DO_STUFF.NP1
3 3 16 PKG.DO_STUFF.NP1.NP2
4 2 12 PKG.DO_STUFF.NP1.NP2.NP3
0 1 10 OUTPUT_CALL_STACK
BakDepth Depth LineNo Name
-------- ----- ------ ----
4 22 MCDONAC.PKG
3 19 MCDONAC.PKG
2 16 MCDONAC.PKG
1 13 MCDONAC.PKG
PL/SQL procedure successfully completed.
SQL>
SQL>
因此,如果你想得到错误的语句,你可以得到深度 = 1的错误回溯,并使用行/单元名称在ALL_SOURCE中查找适当的源代码。
关于UTL_CALL_STACK的更多详细信息
https://blogs.oracle.com/oraclemagazine/sophisticated-call-stack-analysis
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




