有没有办法获得抛出异常的行号?

时间:2009-10-19 15:10:28

标签: logging plsql

我正在处理一个pl-sql脚本,其中我有大约10次TO_CHAR转换。

其中一人正在投掷

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

异常。

目前,我使用这段代码记录消息

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line('Exception message is '||SQLERRM(sqlcode));
    ROLLBACK;

我想添加(主要用于调试目的)引发异常的行,以便以

的形式接收消息
ORA-06502: PL/SQL: numeric or value error: character string buffer too small (at line x)

有一种简单的方法吗?

5 个答案:

答案 0 :(得分:17)

您需要使用10g

DBMS_OUTPUT.put_line('Error in '|| $$plsql_unit || ' at ' || $$plsql_line);

也考虑使用

DBMS_UTILITY.format_error_backtrace

2005年4月,Steven Feuerstein在Oracle杂志上发表了一篇文章:

http://www.oracle.com/technetwork/issue-archive/2005/05-mar/o25plsql-093886.html

干杯,niels

答案 1 :(得分:13)

答案提到了$$PLSQL_LINE & DBMS_UTILITY.FORMAT_ERROR_BACKTRACE。但我想补充一下它们之间的区别:

  1. Predefined Inquiry Directives $$PLSQL_LINE & $$PLSQL_UNIT
    PLSQL_LINE预定义查询指令是一个PLS_INTEGER文字值,表示当前程序单元中对$$ PLSQL_LINE的行号引用。
    根据其定义,PLSQL_LINE不适用于异常日志记录,因为它将提供异常的行号,而不是自身发生的错误的行号。这使得很难检测错误位置,特别是对于大程序单元,除非你用例外处理程序包装每个语句,如Jeffrey的答案所述。
    但是,关于PLSQL_LINE的好处是,它提供的数字无需任何提取或字符串解析。因此,它可能更适合其他日志记录目的。
  2. DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
    此过程在引发异常的位置显示调用堆栈,即使从外部作用域中的异常处理程序调用过程也是如此。 使用此过程的优点是,它使用发生错误的位置提供程序中的确切行号,而不是出现过程调用的位置 但是,该过程返回类似ORA-XXXXX: at "<program_unit_name>", line xx的字符串。因此,如果您有兴趣提取行号本身,无论您想要什么日志记录目的,您都需要解析字符串。
  3. 最后,为了明确区别,下面是两个程序,内容相同。您可以运行它们并注意输出差异

    CREATE OR REPLACE PROCEDURE proc_plsql_line
        IS
        BEGIN
           RAISE VALUE_ERROR;
        EXCEPTION
           WHEN VALUE_ERROR
           THEN
              DBMS_OUTPUT.put_line ( 'Error raised in: '|| $$plsql_unit ||' at line ' || $$plsql_line || ' - '||sqlerrm);
       END;
    /
    

    CREATE OR REPLACE PROCEDURE proc_backtrace
        IS
        BEGIN
           RAISE VALUE_ERROR;
        EXCEPTION
           WHEN VALUE_ERROR
           THEN
              DBMS_OUTPUT.put_line ( 'Error raised: '|| DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ' - '||sqlerrm);
       END;
    /
    

    执行:

    exec proc_plsql_line;
    
    Error raised in: PROC_PLSQL_LINE at line 8 - ORA-06502: PL/SQL: numeric or value error
    
    
    exec proc_backtrace;
    
    Error raised: ORA-06512: at "PROC_BACKTRACE", line 4 - ORA-06502: PL/SQL: numeric or value error
    

答案 2 :(得分:4)

DBMS_UTILITY.format_error_backtrace 语句会为您提供行号

begin
select 1/0 from dual;
exception 
  when others then 
  dbms_output.put_line('ERROR_STACK: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
  dbms_output.put_line('ERROR_BACKTRACE: ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
end;

答案 3 :(得分:2)

你需要10克或以上。检查DBMS_UTILITY.FORMAT_ERROR_BACKTRACE。

http://www.oracle.com/technetwork/issue-archive/2005/05-mar/o25plsql-093886.html

答案 4 :(得分:0)

你可以把你的异常处理程序放在每个语句周围。