ITPub博客

首页 > Linux操作系统 > Linux操作系统 > COMPOUND TRIGGER学习

COMPOUND TRIGGER学习

原创 Linux操作系统 作者:wenhual43 时间:2013-06-22 13:38:00 0 删除 编辑
今天看Oracle® Database PL/SQL Language Reference 11g Release 2 (11.2),对Compound DML Triggers写了一些学习的测试脚本。
背景:如果在触发器里对触发器所在表进行DML,会报ORA-04091表变异的错误。
测试如下:
  建表:create table ABC_TEST
(
  zonecode    VARCHAR2(14),
  disease_id1 NUMBER(4) not null,
  intime      DATE,
  casetype    VARCHAR2(1),
  casetype2   VARCHAR2(1),
  dead        NUMBER
)

普通的DML触发器:CREATE OR REPLACE TRIGGER log_deletions_1
  AFTER insert ON abc_test
  FOR EACH ROW
DECLARE
  n INTEGER;
BEGIN
  SELECT COUNT(*) INTO n FROM abc_test; --这句是重点,报错就是这句引起的
  DBMS_OUTPUT.PUT_LINE('There are now ' || n || ' employees.');
END;

插入记录:
SQL> insert into ABC_TEST values('43012200',198,sysdate,1,1,2);
 
insert into ABC_TEST values('43012200',198,sysdate,1,1,2)
 
ORA-04091: table HR.ABC_TEST is mutating, trigger/function may not see it
ORA-06512: at "HR.LOG_DELETIONS_1", line 4
ORA-04088: error during execution of trigger 'HR.LOG_DELETIONS_1'

如果一定要在触发器查询自己,可以建成复合触发器,如下:
CREATE OR REPLACE TRIGGER log_deletions
FOR insert  ON abc_test
COMPOUND TRIGGER  --这个是关键字哦
  n INTEGER;
  BEFORE STATEMENT IS   --插入前查一遍表,这个会在insert之前执行
  begin  
      SELECT COUNT(1) INTO n FROM abc_test;
      DBMS_OUTPUT.PUT_LINE('There are now ' || n || ' employees.');
  END BEFORE STATEMENT;

  AFTER STATEMENT IS  --插入后执行,这个会在insert之后执行
  BEGIN
    SELECT COUNT(1) INTO n FROM abc_test;
    DBMS_OUTPUT.PUT_LINE('There are now ' || n || ' employees.');
  END AFTER STATEMENT;

END;


SQL> insert into ABC_TEST values('43012200',198,sysdate,1,1,2);
 
There are now 0 employees.
There are now 1 employees.
 
1 row inserted
 
SQL> commit;
 
Commit complete

看到效果了吧。复合触发器,能在触发器之前,先对表进行查询,在插入后,可以马上看到插入的行,神奇吧。

好了,今天就写到这,学习到compound trriger 的特性。

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

请登录后发表评论 登录
全部评论

注册时间:2011-08-03

  • 博文量
    32
  • 访问量
    130411