系統觸發器的應用順序(一)

yangtingkun發表於2009-07-01

在寫一個AFTER SUSPEND觸發器的時候碰到了一個很有趣的現象。

首先描述一下系統級觸發器的觸發順序。

 

 

如果使用者級和系統級的觸發器全部存在的話,那麼Oracle是否會觸發兩個觸發器,還是隻觸發其中的一個呢,還是做一個簡單的例子來說明這個問題。

仍然使用AFTER SUSPEND觸發器的例子,不過將觸發器的內容變得簡單一點。

SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> SET PAGES 100 LINES 120
SQL> CREATE TABLE T_TRIGGER (INFO VARCHAR2(20));

表已建立。

SQL> CREATE OR REPLACE TRIGGER TRI_SCHEMA_SUSPEND
  2  AFTER SUSPEND ON SCHEMA
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO T_TRIGGER VALUES ('SCHEMA TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> SELECT SUM(BYTES)/1024/1024
  2  FROM DBA_FREE_SPACE
  3  WHERE TABLESPACE_NAME = 'YANGTK';

SUM(BYTES)/1024/1024
--------------------
             214.375

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-30032:
掛起的 (可恢復) 語句已超時
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
SCHEMA TRIGGER

可以看到,SCHEMA級的觸發器可以生效,下面看看DATABASE級的觸發器:

SQL> DROP TRIGGER TRI_SCHEMA_SUSPEND;

觸發器已刪除。

SQL> CONN / AS SYSDBA
已連線。
SQL> CREATE OR REPLACE TRIGGER TRI_DATABASE_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO YANGTK.T_TRIGGER VALUES ('DATABASE TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-30032:
掛起的 (可恢復) 語句已超時
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
DATABASE TRIGGER
SCHEMA TRIGGER

資料庫級的觸發器也是可以正常工作的,下面看看如果同時建立兩個觸發器,當觸發事件發生後,將會發生什麼情況:

SQL> TRUNCATE TABLE T_TRIGGER;

表被截斷。

SQL> CREATE OR REPLACE TRIGGER TRI_SCHEMA_SUSPEND
  2  AFTER SUSPEND ON SCHEMA
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO T_TRIGGER VALUES ('SCHEMA TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-30032:
掛起的 (可恢復) 語句已超時
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
SCHEMA TRIGGER
DATABASE TRIGGER

測試結果說明資料庫級觸發器和SCHEMA級觸發器沒有優先順序的關係,只要滿足觸發條件,都會觸發。

下面測試不同使用者下的同名觸發器的情況:

SQL> DROP TRIGGER TRI_SCHEMA_SUSPEND;

觸發器已刪除。

SQL> CONN / AS SYSDBA
已連線。
SQL> DROP TRIGGER TRI_DATABASE_SUSPEND;

觸發器已刪除。

SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO YANGTK.T_TRIGGER VALUES ('SYS TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> CONN YANGTK/YANGTK@YTK102
已連線。
SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6   INSERT INTO T_TRIGGER VALUES ('YANGTK TRIGGER');
  7   COMMIT;
  8  END;
  9  /

觸發器已建立

SQL> TRUNCATE TABLE T_TRIGGER;

表被截斷。

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 300;

會話已更改。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出現錯誤:
ORA-30032:
掛起的 (可恢復) 語句已超時
ORA-01659:
無法分配超出 27 MINEXTENTS (在表空間 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

INFO
--------------------
SYS TRIGGER
YANGTK TRIGGER

只要滿足觸發條件,無論觸發器在哪個SCHEMA下,都會被觸發。

 

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

相關文章