触发器中raise_application_error的细节

时间:2014-06-05 09:56:28

标签: sql oracle plsql

与plsql程序相比,我在insert trigger中有raise_application_error函数的奇怪行为。 sqlerrm 字段仅在plsql错误中获取错误消息,但错误文本包含来自触发器的堆栈跟踪。是什么原因?
(Oracle 10.2.0.4)

这是测试示例。

第一种情况:从plsql执行程序:

declare
  procedure p_e as
  begin
    raise_application_error(-20110, 'error from procedure');
  end;
 begin
  p_e;
exception
  when others then
    dbms_output.put_line(sqlerrm);
    dbms_output.put_line('========================================');
    dbms_output.put_line(dbms_utility.format_error_backtrace);
end; 

并查看

ORA-20110: error from procedure
========================================
ORA-06512: at line 4
ORA-06512: at line 7 

确定。这就是我的预期。

第二种情况:
简单的表

create table TT
(
  r NUMBER
);

并触发

create or replace trigger t_tt
  before insert on tt  
  for each row
begin
  raise_application_error(-20110, 'error from trigger');
end t_tt;

执行:

begin
  insert into TT
  values
    (0);
exception
  when others then
    dbms_output.put_line(sqlerrm);
    dbms_output.put_line('========================================');
    dbms_output.put_line(dbms_utility.format_error_backtrace);
end;

结束了这样的文字:

ORA-20110: error from trigger
ORA-06512: at "GFU_PARUS.T_TT", line 2
ORA-04088: error during execution of trigger 'GFU_PARUS.T_TT'
========================================
ORA-06512: at "GFU_PARUS.T_TT", line 2
ORA-06512: at line 2

1 个答案:

答案 0 :(得分:1)

异常处理程序中的

SQLERRM将返回错误堆栈的error code and nested messages(最多512个字节)。

因此,在您的问题的两种情况下,SQLERRM都会返回错误堆栈:第一种情况仅限于一个错误。

如果要检索完整的错误堆栈,Oracle建议使用DBMS_UTILITY.FORMAT_ERROR_STACK