“创建后”触发器中的未处理异常阻止创建

问题描述 投票:1回答:3

我的架构上有一个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;
/
oracle oracle11g triggers
3个回答
2
投票

从文档:

在大多数情况下,如果触发器运行引发异常的语句,并且异常不由异常处理程序处理,则数据库将回滚触发器及其触发语句的效果。

正如你的问题所暗示的那样,它不仅会导致它终止。您未处理的异常导致触发语句 - 即create table - 被回滚。 When talking about DDL statements

在数据库执行DDL语句之前立即发生隐式COMMIT,之后立即发生COMMIT或ROLLBACK。在前面的示例中,... [if] ALTER TABLE语句成功,然后数据库提交此语句;否则,数据库回滚此语句。 ...

所以这是预期的行为。


2
投票

事务以CREATE TABLE开头;然后AFTER CREATE触发器触发并引发异常,即表定义不会“提交”到数据字典表(例如USER_TABLES,USER_TAB_COLUMNS,...)中,而是“回滚”。

所以 - 不,CREATE TABLE进程没有正确完成,你不能使用该表,因为它没有被创建,因为它的创建是由触发器阻止的。


1
投票

验证这一点的一个好例子是检查表是否实际存在于触发器中。

让我们说你从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触发器中的数据字典,但如果触发器中发生错误,则会回滚事务。

© www.soinside.com 2019 - 2024. All rights reserved.