3

这是一个最小的测试用例,由于某种原因失败了

ORA-06510: PL/SQL: 未处理的用户定义异常

CREATE PACKAGE my_test
AS
  global_exception EXCEPTION;
END;
/

set serveroutput on;

BEGIN
  execute immediate 'BEGIN RAISE my_test.global_exception; END;';
EXCEPTION
  WHEN my_test.global_exception THEN 
    dbms_output.put_line('global_exception');
END;
/

这是一个有效的测试用例:

BEGIN
  RAISE my_test.global_exception;
EXCEPTION
  WHEN my_test.global_exception THEN 
    dbms_output.put_line('global_exception');
END;
/

有没有办法通过立即执行来引发全局异常?数据库版本 12c 或 11g

4

1 回答 1

4

如果您使用dbms_sql而不是execute immediate(在 11gR2 中),则可以捕获它:

DECLARE
  l_cur pls_integer;
  l_rc pls_integer;
BEGIN
  l_cur := dbms_sql.open_cursor;
  dbms_sql.parse (l_cur, 'BEGIN RAISE my_test.global_exception; END;', dbms_sql.native);
  l_rc := dbms_sql.execute(l_cur);
EXCEPTION
  WHEN my_test.global_exception THEN 
    dbms_output.put_line('global_exception');
END;
/

PL/SQL procedure successfully completed.

global_exception

不完全确定为什么会这样,但你的却不行。

啊,调查不同的行为提出了一个提示execute immediate如果您将错误号与包中的异常相关联,则可以捕获它:

CREATE PACKAGE my_test
AS
  global_exception EXCEPTION;
  PRAGMA exception_init(global_exception, -20001);
END;
/

BEGIN
  execute immediate 'BEGIN RAISE my_test.global_exception; END;';
EXCEPTION
  WHEN my_test.global_exception THEN 
    dbms_output.put_line('global_exception');
END;
/

PL/SQL procedure successfully completed.

global_exception

您现在也可以在匿名块中静态地引发异常,尽管这不是很有用;如果没有编译指示,这也会得到 ORA-06510,因为这是您在其中所做的execute immediate

BEGIN
  RAISE my_test.global_exception;
END;
/

Error report -
ORA-20001: 
ORA-06512: at line 2

现在可以将 ORA-20001 扔到内部,execute immediate并且 pragma 允许通过上下文切换识别它。或类似的东西。dbms_sql看起来,包裹的处理方式略有不同。

于 2016-06-10T15:46:14.637 回答