yangtingkun
===========================================================
Oracle11g触发器重用OBJECT_ID
===========================================================

在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

yangtingkun 发表于:2008.04.06 23:28 ::分类: ( ORACLE ) ::阅读:(818次) :: 评论 (0)

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...