ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 系统触发器的应用顺序(三)

系统触发器的应用顺序(三)

原创 Linux操作系统 作者:yangtingkun 时间:2009-07-03 23:28:04 0 删除 编辑

在写一个AFTER SUSPEND触发器的时候碰到了一个很有趣的现象。

寻找导致问题的原因。

系统触发器的应用顺序(一):http://yangtingkun.itpub.net/post/468/486884

系统触发器的应用顺序(二):http://yangtingkun.itpub.net/post/468/486915

 

 

上一篇文章介绍了,如果当前用户下的触发器出现了编译错误,则会导致其他触发器也无法触发,即使当前触发器被删除。

是什么原因导致了这种情况的产生,怀疑可能与触发器的运行顺序有关,由于触发器的运行是根据触发器的建立顺序,具体描述可以参考:http://yangtingkun.itpub.net/post/468/398314

下面将SYS用户下的触发器和当前用户下的触发器建立顺序倒置,看看是否出现同样的问题:

SQL> DROP TABLE T_TRIGGER PURGE;

表已删除。

SQL> CREATE TABLE T_TRIGGER (INFO VARCHAR2(20));

表已创建。

SQL> CONN / AS SYSDBA
已连接。
SQL> DROP TRIGGER TRI_SUSPEND;

触发器已删除。

SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5   V_RESULT BOOLEAN;
  6   V_ERROR_TYPE VARCHAR2(32767);
  7   V_OBJECT_TYPE VARCHAR2(32767);
  8   V_OBJECT_OWNER VARCHAR2(30);
  9   V_TABLESPACE_NAME VARCHAR2(30);
 10   V_OBJECT_NAME VARCHAR2(128);
 11   V_SUB_OBJECT_NAME VARCHAR2(128);
 12  BEGIN
 13   V_RESULT := DBMS_RESUMABLE.SPACE_ERROR_INFO(
 14    V_ERROR_TYPE,
 15    V_OBJECT_TYPE,
 16    V_OBJECT_OWNER,
 17    V_TABLESPACE_NAME,
 18    V_OBJECT_NAME,
 19    V_SUB_OBJECT_NAME);
 20   INSERT INTO YANGTK.T_TRIGGER VALUES ('SYS TRIGGER');
 21   COMMIT;
 22  END;
 23  /

触发器已创建

SQL> CONN YANGTK/YANGTK
已连接。
SQL> DROP TRIGGER TRI_SUSPEND;
DROP TRIGGER TRI_SUSPEND
*
1 行出现错误:
ORA-04080:
触发器 'TRI_SUSPEND' 不存在


SQL> CREATE OR REPLACE TRIGGER TRI_SUSPEND
  2  AFTER SUSPEND ON DATABASE
  3  DECLARE
  4   PRAGMA AUTONOMOUS_TRANSACTION;
  5   V_RESULT BOOLEAN;
  6   V_ERROR_TYPE VARCHAR2(32767);
  7   V_OBJECT_TYPE VARCHAR2(32767);
  8   V_OBJECT_OWNER VARCHAR2(30);
  9   V_TABLESPACE_NAME VARCHAR2(30);
 10   V_OBJECT_NAME VARCHAR2(128);
 11   V_SUB_OBJECT_NAME VARCHAR2(128);
 12  BEGIN
 13   V_RESULT := DBMS_RESUMABLE.SPACE_ERROR_INFO(
 14    V_ERROR_TYPE,
 15    V_OBJECT_TYPE,
 16    V_OBJECT_OWNER,
 17    V_TABLESPACE_NAME,
 18    V_OBJECT_NAME,
 19    V_SUB_OBJECT_NAME);
 20   INSERT INTO T_TRIGGER VALUES ('YANGTK TRIGGER');
 21   COMMIT;
 22  END;
 23  /

警告: 创建的触发器带有编译错误。

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-04098:
触发器 'YANGTK.TRI_SUSPEND' 无效且未通过重新验证
ORA-01659:
无法分配超出 27 MINEXTENTS (在表空间 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

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

SQL> SELECT OBJECT_ID, OWNER
  2  FROM DBA_OBJECTS
  3  WHERE OBJECT_NAME = 'TRI_SUSPEND';

 OBJECT_ID OWNER
---------- ------------------------------
     92651 SYS
     92652 YANGTK

虽然错误信息一样,但是可以看到,这次T_TRIGGER表中包含一条记录,说明SYS触发器已经执行成功了。是在尝试调用第二个触发器YANGTK用户下的触发器时出现的错误。

SQL> DROP TRIGGER TRI_SUSPEND;

触发器已删除。

SQL> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出现错误:
ORA-01659:
无法分配超出 27 MINEXTENTS (在表空间 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

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

可以看到,就是由于触发器状态的不正确,导致当前会话调用触发器出现了问题。即使删除了问题触发器,发生了SUSPEND事件后,SYS用户下的AFTER SYSPEND也没有再次被触发。

尝试在当前会话再次添加一个正确的触发器:

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> CREATE TABLE T_BIG (ID NUMBER)
  2  TABLESPACE YANGTK
  3  STORAGE (INITIAL 250M);
CREATE TABLE T_BIG (ID NUMBER)
*
1 行出现错误:
ORA-01659:
无法分配超出 27 MINEXTENTS (在表空间 YANGTK )


SQL> SELECT * FROM T_TRIGGER;

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

即使重建当前用户下的触发器,使其状态正确,在当前的会话中,Oracle也不会再次调用触发器了。

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-608305/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10407259