发表于: 2008.04.06 23:28
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/459132
---------------------------------------------------------------
在11g以前,重用OBJECT_ID只是对过程、函数、包和对象而言,而对于触发器是不会重用OBJECT_ID的,从11g开始,Oracle针对触发器也可以重用OBJECT_ID了。
OBJECT_ID的重用:http://yangtingkun.itpub.net/post/468/457962
OBJECT_ID的重用(二):http://yangtingkun.itpub.net/post/468/458030
前一段时间在介绍Oracle PL/SQL新特性的时候,提到了触发器的新功能,可以指定触发器的触发顺序。为了说明这个问题,举了一个例子: http://yangtingkun.itpub.net/post/468/398314
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> 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 行。
SQL> SELECT OBJECT_ID, OBJECT_NAME FROM USER_OBJECTS
2 WHERE OBJECT_NAME LIKE 'TRI_T__';
OBJECT_ID OBJECT_NAME
---------- ------------------------------
55637 TRI_T_1
55640 TRI_T_2
55639 TRI_T_3
这个例子是为了说明相同类型的触发器的触发顺序于触发器的OBJECT_ID顺序有关。但是这个测试只是在11g之前版本有有效,因为11g以前的触发器不会重用OBJECT_ID,如果在11g中,这个测试就会得到不同的结果:
SQL> CONN YANGTK/yangtk@ORA11G已连接。
SQL> SELECT * FROM V$VERSION;
BANNER
--------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for Linux: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
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> 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');
3
2
1
已创建 1 行。
SQL> SELECT OBJECT_ID, OBJECT_NAME FROM USER_OBJECTS
2 WHERE OBJECT_NAME LIKE 'TRI_T__';
OBJECT_ID OBJECT_NAME
---------- ------------------------------
72619 TRI_T_1
72620 TRI_T_2
72621 TRI_T_3
导致11g和以前版本测试结果不同的原因就是11g对于触发器也开始重用OBJECT_ID了。
如果想在11g中得到和以前版本一样的结果,需要在删除和重建之间重启数据库:
SQL> DROP TRIGGER TRI_T_2;
触发器已删除。
SQL> CONN SYS/test@ORA11G AS SYSDBA已连接。
SQL> SHUTDOWN IMMEDIATE数据库已经关闭。已经卸载数据库。
ORACLE 例程已经关闭。
SQL> STARTUP
ORACLE 例程已经启动。
Total System Global Area 129732608 bytes
Fixed Size 1298360 bytes
Variable Size 109051976 bytes
Database Buffers 16777216 bytes
Redo Buffers 2605056 bytes数据库装载完毕。数据库已经打开。
SQL> CONN YANGTK/yangtk@ORA11G已连接。
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> SET SERVEROUT ON
SQL> INSERT INTO T VALUES (3, 'C');
2
3
1
已创建 1 行。
SQL> COL OBJECT_NAME FORMAT A30
SQL> SELECT OBJECT_ID, OBJECT_NAME FROM USER_OBJECTS
2 WHERE OBJECT_NAME LIKE 'TRI_T__';
OBJECT_ID OBJECT_NAME
---------- ------------------------------
72619 TRI_T_1
72628 TRI_T_2
72621 TRI_T_3











