create or replace trigger trigger_before
before insert or update or delete on cip_tmps
begin
if to_char(sysdate,'DY','nls_date_language=AMERICAN')
IN ('STA','SUN','THU','WED') then
raise_application_error(-20001,'不能在周末修改数据');
end if;
end;
create or replace trigger forbidden_update_comtype
before insert or update or delete on communitytype
begin
case
when inserting then
raise_application_error(-20091,'不能执行增操作');
when deleting then
raise_application_error(-20092,'不能执行删操作');
when updating then
raise_application_error(-20093,'不能执行改操作');
end case;
end;
update communitytype com
set com.english_name = 'test'
where com.community_type_id = 'ebook'
create or replace trigger trigger_after
after insert on cip_temp
begin
insert into cip_temps (select * from(select * from cip_temp order by id) where rownum=1);
end;
create or replace trigger trigger_name
timing event1[or event2 or event3]
on table_name
[REFERENCING NEW AS NEW | OLD AS OLD]
for each row
pl/sql block;
如上所示:trigger_name用于指定触发器名称,timing用于指定触发时机(before和after),event1用于指定指定触发事件(insert、update、delete),table_name用于指定DML操作对应的表名。REFERENCING 子句用于指定引用新、旧、数据方式,默认情况下使用old修饰符引用旧数据,使用new修饰符是引用新数据。for each row表示建立行触发器。
1、建立before行触发器
确保员工工资不能涨价,示例如下:
Oracle代码
create or replace trigger trigger_before_row
before update of english_name on communitytype
for each row
begin
if(:new.english_name =:old.english_name) then
raise_application_error(-20001,'资源库名称没有变化');
end if;
end;
update communitytype com
set com.english_name = com.english_name
where com.community_type_id = 'ebook'
create or replace trigger trigger_after_row
after insert or update or delete on cip_test
for each row
declare
v_update int;
v_delete int;
begin
case
when inserting then
insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
when updating then
select count(1) into v_update from cip_temps where id=:old.id;
if(v_update=0) then
insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
else
update cip_temps set name=:new.name,age=:new.age,address=:new.address
where id=:old.id;
end if;
when deleting then
select count(*) into v_delete from cip_temps where id=:old.id;
if(v_delete<>0)then
delete from cip_temps where id=:old.id;
end if;
end case;
end;
create or replace trigger trigger_after_row_when
after update or delete on cip_test
for each row
when (old.name='aa8')
declare
v_update int;
begin
case
when updating then
select count(*) into v_update from cip_temps where id=:old.id;
if(v_update=0) then
insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);
else
update cip_temps set name=:new.name,age=:new.age,address=:new.address where id=:old.id;
end if;
end case;
end;
4、DML触发器使用注意事项
当编写DML触发器时,触发器代码不能从触发器所对应的表中读取数据。
5、实现参照完整性
参照完整性是指两个表具有主从关系(主外健关系),当删除主表数据时,必须确保相应的从表的数据也被删除,可以在定义外键约束时指定on delete cascade。
五、行触发器和语句触发器区别
1、行触发器有 for each row子句。语句触发器没有for each row 子句。
2、行触发器,可以有 when 作为触发限制,可以使用new/old。语句触发器不能有when 作为触发限制。
3、行触发器:对应DML语句所影响到的表中的每一行,触发器都要执行一遍。
4、语句触发:对应DML语句所影响到的表中的所有行,触发器只执行一遍。
对表进行行级触发的,则该表暂时不能操作(即该表已经成为变异表)表 级触发器与此不同