Oracle11g觸發器重用OBJECT_ID

yangtingkun發表於2008-04-06

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

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-230951/,如需轉載,請註明出處,否則將追究法律責任。

相關文章