触发器类型:
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;