打算写一系列的文章介绍11g的新特性和变化。
11g中PL/SQL新增了很多特性,在性能和易用性方面做了不少的提升,还有一些功能性的增强。
这篇介绍一下PLSQL的新增的控制触发器的触发顺序功能。
Oracle11新特性——PLSQL新特性(一):http://yangtingkun.itpub.net/post/468/395965
Oracle11新特性——PLSQL新特性(二):http://yangtingkun.itpub.net/post/468/396571
Oracle11新特性——PLSQL新特性(三):http://yangtingkun.itpub.net/post/468/396994
Oracle11新特性——PLSQL新特性(四):http://yangtingkun.itpub.net/post/468/397350
11g中对于触发器部分有了一定的增强,主要表现在两个方面。一个是对触发器的触发顺序可以进行控制。另一个是可以定义一个复合触发器。
这一篇首先介绍一下触发器的顺序控制。
在11g以前,Oracle的文档上一直是这样描述的:Oracle是不会保证同种类型的触发器的触发先后顺序。不过在测试中发现,Oracle似乎是根据触发器建立时间的先后决定触发顺序的:
SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> CREATE OR REPLACE TRIGGER TRI_T_1 AFTER INSERT ON T
2 FOR EACH ROW
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(1);
5 END;
6 /
触发器已创建
SQL> CREATE OR REPLACE TRIGGER TRI_T_2 AFTER INSERT ON T
2 FOR EACH ROW
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(2);
5 END;
6 /
触发器已创建
SQL> CREATE OR REPLACE TRIGGER TRI_T_3 AFTER INSERT ON T
2 FOR EACH ROW
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(3);
5 END;
6 /
触发器已创建
SQL> SET SERVEROUT ON
SQL> INSERT INTO T VALUES (1, 'A');
3
2
1
已创建 1 行。
SQL> INSERT INTO T SELECT ROWNUM, OBJECT_NAME FROM USER_OBJECTS;
IXDBA.NET社区论坛
3
2
1
3
2
1
3
2
1
3
2
1
已创建4行。
如果将TRI_T_2删除,并重写建立,则这个触发器会最先触发:
SQL> DROP TRIGGER TRI_T_2;
触发器已删除。
SQL> CREATE OR REPLACE TRIGGER TRI_T_2 AFTER INSERT ON T
2 FOR EACH ROW
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(2);
5 END;
6 /
触发器已创建
SQL> INSERT INTO T VALUES (2, 'B');
2
3
1
已创建 1 行。
如果同一类的触发器在触发的时候需要按照某种顺序触发,那么仅靠触发器创建时间先后这个条件是无法确保顺序不会发生变化的。
11g触发器新增了FOLLOWS语句,使得触发器建立的过程中可以指定顺序:
SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> CREATE OR REPLACE TRIGGER TRI_T_1 AFTER INSERT ON T
2 FOR EACH ROW
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(1);
5 END;
6 /
触发器已创建
SQL> CREATE OR REPLACE TRIGGER TRI_T_2 AFTER INSERT ON T
2 FOR EACH ROW FOLLOWS TRI_T_1
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(2);
5 END;
6 /
触发器已创建
SQL> CREATE OR REPLACE TRIGGER TRI_T_3 AFTER INSERT ON T
2 FOR EACH ROW FOLLOWS TRI_T_2
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(3);
5 END;
6 /
触发器已创建
SQL> SET SERVEROUT ON
SQL> INSERT INTO T VALUES (1, 'A');
1
2
3
已创建 1 行。
Oracle除了增加了FOLLOWS语法,还可以在创建触发器的时候指定DISABLE/ENABLE。这对于没有把握触发器是否会成功编译的情况很有帮助:
SQL> CREATE OR REPLACE TRIGGER TRI_T_3 AFTER INSERT ON T
2 FOR EACH ROW FOLLOWS TRI_T_2
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(3)
5 END;
6 /
警告: 创建的触发器带有编译错误。
SQL> INSERT INTO T VALUES (2, 'B');
INSERT INTO T VALUES (2, 'B')
*第 1 行出现错误:
ORA-04098: 触发器 'YANGTK.TRI_T_3' 无效且未通过重新验证
如果触发器建立的时候报错,那么这个基表相应的操作都会由于触发器的错误是失败。11g可以在建立触发器的时候就指定