【问题标题】:How to propagate globally defined exception through execute immediate?如何通过立即执行传播全局定义的异常?
【发布时间】:2016-10-11 14:09:47
【问题描述】:

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

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;
/

有没有办法通过 EXECUTE IMMEDIATE 引发全局异常? 数据库版本 12c 或 11g

【问题讨论】:

    标签: oracle plsql exception-handling dynamic-sql execute-immediate


    【解决方案1】:

    如果您使用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
    

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

    啊,investigating the different behaviour threw up a hint。如果您的包裹中有associate an error number with the 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 中,并且编译指示允许通过上下文切换识别它。或类似的东西。 dbms_sql 包的处理方式似乎略有不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-26
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多