发表于: 2009.07.01 23:56
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/486884
---------------------------------------------------------------
在写一个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下,都会被触发。











