PLSQL基于语法七-触发器

触发器类型:
  • DML触发器:对表或视图进行DML操作时触发;

  • INSTEAD OF 触发器:只定义在视图上,用来替换实际的操作语句。

  • 系统触发器:对数据库系统进行操作(如DDL语句、启动或关闭数据库等系统事件)时触发。

触发事件:

引起触发器被触发的事件,如DML语句(如INSERT、UPDATE、DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登陆或退出数据库)。

触发条件:

触发条件是由WHERE子句指定的一个逻辑表达式。只有当该表达式的值为true时,遇到触发事件才会自动执行触发器,使其进行触发操作,否则遇到触发事件也不会执行触发器。

触发对象:

触发器所要执行的PL/SQL程序,即执行部分。

触发时机:

触发时机指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作之前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AFTER,则表示在DML操作之后触发,以便记录该操作或某些事后处理。

条件谓词:

当在触发器中包含了多个触发事件(INSERT、UPDATE、DELETE)的组合时,为了分别针对不同的事件进行不同的处理,需要使用Oracle提供的如下条件谓词。

INSERTING:当触发事件为INSERT时,取值为TRUE,否则为FALSE.

UPDATING[(column_1,column_2...column_n)]:当触发事件为UPDATE时,如果修改了column_x列,则取值为true,否则为false,其中column_x是可选的。

DELETING:当触发事件是DELETE时,取值为TRUE,否则为FALSE。

触发子类型:

触发子类型分为行触发(row)和语句触发(statement),行触发即对每一行操作都要触发,而语句触发只对这种操作执行一次,一般执行sql语句操作时都应是行触发,只有对整个表作安全检查(即防止非法操作)时才用语句触发。如果省略此项,默认为行触发。

此外,触发器中还有两个相关值,分别对应触发的行中的旧值和新值,用old和new来表示。

创建触发器:
/*CREATE [OR REPLACE] TRIGGER <触发器名>
   触发条件
   触发体*/

例1:

--触发器
--练习1:简单的行级触发器,在删除某个表的每一条数据的时候执行
create or replace trigger t_back_grade
  after delete
  on grade 
  referencing new as new old as old -- 可以获取新的数据和老的数据
  for each row
declare
  r_grade grade%rowtype;
begin
  --获取删除的数据
  r_grade.id := :old.id;
  r_grade.name :=:old.name;
  
  --可以执行一些操作...
  
  --触发器不需要commit;
end t_back_grade;






一个复杂的触发器:

CREATE OR REPLACE TRIGGER "BIZBENIFITRATELOG_TR"
  BEFORE INSERT OR UPDATE OR DELETE ON BIZBENIFITRATELOG
  referencing new as new old as old
  FOR EACH ROW
declare
  i        number(10);
  ii       number(10);
  opttype  CHAR(1);
  dataid   varchar2(32);
  parentid varchar2(32);
  icount   number(10);
  iflag    number(1);
  state    varchar2(2);

begin
  iflag  := 0;
  icount := 0;
  if inserting then
    if :new.id is null then
      select BIZBENIFITRATELOG_S.nextval into :new.id from dual;
    else
      select BIZBENIFITRATELOG_S.nextval into ii from dual;
      select BIZBENIFITRATELOG_S.currval into ii from dual;
      while (:new.id > ii) loop
        select BIZBENIFITRATELOG_S.nextval into ii from dual;
      end loop;
    end if;
  end if;
  parentid := :new.ALLOTID;
  if inserting then
    opttype := 'A';
    dataid  := :new.ID;
  elsif updating then
    select count(1)
      into icount
      from msgsend
     where BIZTABLE = 'Bizbenifitratelog'
       and BIZID = :new.ID
       and BIZSTATE in ('0', '3');
    if icount > 0 then
      iflag := 1;
    else
      opttype  := 'M';
      dataid   := :new.ID;
      parentid := :old.ALLOTID;
    end if;
  else
    opttype  := 'D';
    dataid   := :old.ID;
    parentid := :old.ALLOTID;
  end if;
  if iflag = 0 then
    select msgsend_s.nextval into i from dual;
    if opttype = 'D' then
      state := '5';
    else
      state := '0';
    end if;
    insert into msgsend
      (ID,
       BIZTYPE,
       BIZID,
       PARENTID,
       BIZTABLE,
       OPERATETYPE,
       BIZSTATE,
       BIZDATE,
       NUM)
    values
      (i,
       'Bizallot',
       dataid,
       parentid,
       'Bizbenifitratelog',
       opttype,
       state,
       to_char(sysdate, 'YYYY-MM-DD'),
       0);
  end if;
end BIZBENIFITRATELOG_TR;


转载于:https://my.oschina.net/kkrgwbj/blog/470308

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值