“创建后”触发器中的未处理异常阻止创建
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“创建后”触发器中的未处理异常阻止创建相关的知识,希望对你有一定的参考价值。
我的架构上有一个AFTER CREATE触发器引发异常;我正在尝试创建一个表。我理解一个未处理的异常可能导致查询/操作/事务(我找不到适合这种情况的单词)来终止。但是,当在创建表之后引发异常时,那么表格是否应该已经创建呢?
成功触发后创建表时会抛出错误错误:
create table test(testcol number);
错误:
SQL Error: ORA-00604: error occurred at recursive SQL level 1
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at line 4
触发:
create or replace trigger ddl_trig_2812
after create
on schema
declare
eirit exception;
begin
raise eirit;
end;
/
从文档:
在大多数情况下,如果触发器运行引发异常的语句,并且异常不由异常处理程序处理,则数据库将回滚触发器及其触发语句的效果。
正如你的问题所暗示的那样,它不仅会导致它终止。您未处理的异常导致触发语句 - 即create table
- 被回滚。 When talking about DDL statements:
在数据库执行DDL语句之前立即发生隐式COMMIT,之后立即发生COMMIT或ROLLBACK。在前面的示例中,... [if] ALTER TABLE语句成功,然后数据库提交此语句;否则,数据库回滚此语句。 ...
所以这是预期的行为。
事务以CREATE TABLE开头;然后AFTER CREATE触发器触发并引发异常,即表定义不会“提交”到数据字典表(例如USER_TABLES,USER_TAB_COLUMNS,...)中,而是“回滚”。
所以 - 不,CREATE TABLE进程没有正确完成,你不能使用该表,因为它没有被创建,因为它的创建是由触发器阻止的。
验证这一点的一个好例子是检查表是否实际存在于触发器中。
让我们说你从qazxsw poi块找到qazxsw poi并查询RAISE
以查看对象是否存在。
EXCEPTION
触发器已创建。
现在,让我们创建表。
DBA_OBJECTS
虽然引发了异常,但是表格存在于数据字典中,如上面SQL> create or replace trigger ddl_trig_2812
2 after create
3 on schema
4 declare
5 v_table_name DBA_OBJECTS.OBJECT_NAME%TYPE;
6 eirit exception;
7 begin
8 select object_name into v_table_name from DBA_OBJECTS where object_name = 'ATEST';
9 raise eirit;
10 EXCEPTION
11 WHEN OTHERS THEN
12 DBMS_OUTPUT.PUT_LINE( 'TABLE CREATED '|| v_table_name );
13 RAISE;
14 END;
15
16 /
显示的消息所示。
现在,如果我们检查表是否存在,
SQL> set serveroutput on;
SQL> create table atest ( a number);
TABLE CREATED ATEST
create table atest ( a number)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at line 10
这意味着,Oracle会更改DDL触发器中的数据字典,但如果触发器中发生错误,则会回滚事务。
以上是关于“创建后”触发器中的未处理异常阻止创建的主要内容,如果未能解决你的问题,请参考以下文章