yangtingkun
===========================================================
系统触发器的应用顺序(一)
===========================================================

在写一个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下,都会被触发。

yangtingkun 发表于:2009.07.01 23:56 ::分类: ( ORACLE ) ::阅读:(1115次) :: 评论 (2)
re: 系统触发器的应用顺序(一) [回复]

最后一句话,写错一个字!
嘻嘻

kylin 评论于: 2009.07.02 09:00
re: 系统触发器的应用顺序(一) [回复]

已更正

yangtingkun 评论于: 2009.07.02 11:18

发表评论
标题

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

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


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