暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 导致PLSQL异常处理程序中的PSLQL或SQL语句的日志记录异常

ASKTOM 2020-10-27
655

问题描述

嗨,汤姆,

我想知道是否有任何方法来编码异常处理程序,以捕获特定的PLSQL或SQL语句,这些语句将导致在编写异常处理程序的同一个PLSQL块内的异常。

例如,在PLSQL块中说下面的语句,

v_num (a number datatype variable) := ;


这将导致明显的异常,并且此特定语句应与解析值 (此语句右侧负责异常的实际值) 一起捕获,并从异常处理程序中记录。

同样,在下一次运行期间,同一块中的另一个SQL语句将导致某些异常,并且该SQL语句的解析版本将从异常处理程序中捕获并记录。

我知道我要问的是类似于正式的调试机制,但这是不可能实现的吗?

问候,
马诺哈尔·米什拉。

专家解答

使用UTL_CALL_STACK,您可以深入了解错误 (和当前调用堆栈) 的位置,例如

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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论