如何通过立即执行来传播全局定义的异常?
How to propagate globally defined exception through execute immediate?
这是一个最小的测试用例,由于某种原因失败
ORA-06510: PL/SQL: unhandled user-defined exception
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
如果您使用 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. You can catch it with execute immediate
if you associate an error number with the exception 在你的包裹里:
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
您现在也可以在匿名块中静态引发异常,尽管这不是很有用;如果没有 pragma,这也会得到 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
包处理它的方式似乎略有不同。
这是一个最小的测试用例,由于某种原因失败
ORA-06510: PL/SQL: unhandled user-defined exception
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
如果您使用 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. You can catch it with execute immediate
if you associate an error number with the exception 在你的包裹里:
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
您现在也可以在匿名块中静态引发异常,尽管这不是很有用;如果没有 pragma,这也会得到 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
包处理它的方式似乎略有不同。