打算写一系列的文章介绍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
Oracle11新特性——PLSQL新特性(五):http://yangtingkun.itpub.net/post/468/398314
11g中对于触发器部分有了一定的增强,主要表现在两个方面。一个是对触发器的触发顺序可以进行控制。另一个是可以定义一个复合触发器。
上一篇介绍了触发器的触发顺序,这一篇来介绍一下复合触发器。复合触发器中可以包括BEFORE STATEMENT、BEFORE EACH ROW、AFTER EACH ROW和AFTER STATEMENT四个部分,将四种类型的触发器集成在一个触发器中,如果需要多个类型的触发器配合使用,采用复合触发器会显得逻辑更加清晰,而且不容易出现错误。在复合触发器中定义的变量可以在不同类型的触发语句中使用,不再需要使用外部包存储中间结果。而且利用复合触发器的批量操作还可以提高触发器的性能。
下面先看一个简单的COMPOUND TRIGGER的语法:
SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> CREATE OR REPLACE TRIGGER TRI_COMPOUND FOR INSERT OR UPDATE OR DELETE ON T
2 COMPOUND TRIGGER
3 BEFORE STATEMENT IS
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE('BEFORE STATEMENT');
6 END BEFORE STATEMENT;
7
8 BEFORE EACH ROW IS
9 BEGIN
10 DBMS_OUTPUT.PUT_LINE('BEFORE EACH ROW');
11 END BEFORE EACH ROW;
12
13 AFTER EACH ROW IS
14 BEGIN
15 DBMS_OUTPUT.PUT_LINE('AFTER EACH ROW');
16 END AFTER EACH ROW;
17
18 AFTER STATEMENT IS
19 BEGIN
20 DBMS_OUTPUT.PUT_LINE('AFTER STATEMENT');
21 END AFTER STATEMENT;
22 END;
23 /
触发器已创建
SQL> SET SERVEROUT ON
IXDBA.NET社区论坛
SQL> INSERT INTO T SELECT ROWNUM, TNAME FROM TAB;
BEFORE STATEMENT
BEFORE EACH ROW
AFTER EACH ROW
BEFORE EACH ROW
AFTER EACH ROW
BEFORE EACH ROW
AFTER EACH ROW
AFTER STATEMENT
已创建3行。
了解了COMPOUND触发器的语法,下面看看如何利用COMPOUND TRIGGER来简化变异表的处理。在以前的一篇文章中,介绍了:通过触发器复制包含LONG类型的表:http://yangtingkun.itpub.net/post/468/41936
里面包括了变异表触发器的处理方法,下面用COMPOUND TRIGGER来解决这个问题:
SQL> CREATE TABLE T_LONG (ID NUMBER PRIMARY KEY, COMMENTS LONG);
表已创建。
SQL> CREATE TABLE T_LONG_LOG (ID NUMBER PRIMARY KEY, COMMENTS CLOB);
表已创建。
SQL> CREATE OR REPLACE TRIGGER TRI_T_LONG_COMPOUND FOR INSERT ON T_LONG
2 COMPOUND TRIGGER
3 TYPE T_NUMBER IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
4 V_ID T_NUMBER;
5 BEFORE EACH ROW IS
6 BEGIN
7 V_ID(V_ID.COUNT 1) := :NEW.ID;
8 END BEFORE EACH ROW;
9
10 AFTER STATEMENT IS
11 BEGIN
12 FORALL I IN 1..V_ID.COUNT
13 INSERT INTO T_LONG_LOG SELECT ID, TO_LOB(COMMENTS) FROM T_LONG WHERE ID = V_ID(I);
14 END AFTER STATEMENT;
15 END;
16 /
触发器已创建
SQL> INSERT INTO T_LONG SELECT ROWNUM, TNAME FROM TAB;
已创建5行。
SQL> COL COMMENTS FORMAT A40
SQL> SELECT * FROM T_LONG;
ID COMMENTS
---------- ----------------------------------------