开发触发器的注意点
- 触发器不接收参数
- 触发器越多,DML操作性能越低
- 触发器最大为32k,若pl/sql语句太多,可以编写存储过程,在触发器中调用
- 在触发器的执行部分只能用DML语句(insert、select、update、delete),不能使用DDL语句(create、alter、drop)
- 触发器中不能包含事务控制语句(commit、rollback、savepoint),因为触发器是触发语句的一部分,触发语句提交、回退时,触发器也被提交、回退了;触发器主体中调用的过程、函数也不能使用事务控制语句
- 触发器主体中不能声明任何long和blog变量,:new和:old也不能是表中任何long或blog列
- 一张表最多只能有12个触发器,且同一时间、同一事件、同一类型的触发器只能有一个,各个触发器之间也不能有矛盾
1 --insert事件触发器
2 before insert/before insert for each row
3 after insert/after insert for each row
4 --update事件触发器
5 before update/before update for each row
6 after update/after update for each row
7 --delete事件触发器
8 before delete/before delete for each row
9 after delete/after delete for each row
触发器启用与禁用
1 --启用/禁用单个触发器
2 alter trigger trigger_name {enable/disable};
3 --启用/禁用与某张表相关的所有触发器
4 alter table table_name {enable/disable} all triggers;
触发器语法
1 create [or replace] trigger trigger_name
2 {before/after} --触发时间
3 {delete/insert/update [of column]}--触发事件
4 on table
5 [for each row [where(条件)]]
6 declare
7 --local variables here
8 begin
9 pl/sql语句
10 end;
例
1、插入一条数据打印一句话
1 create or replace trigger trg_test1
2 after insert on table
3 begin
4 dbms_output.put_line('insert successful!')
5 end [trg_test1];
2、不能在周末插入数据
1 create or replace trigger trg_test2
2 before insert on table
3 declare
4 t_day varchar2(10);
5 begin
6 select to_char(sysdate,'day') into t_day from dual;
7 if t_day in ('星期六','星期日') then
8 --抛出错误
9 raise_application_error(-20001,'不能在周末插入数据!');
10 end if;
11 end [trg_test2];
3、使用 :old 和 :new
触发语句 |
:old |
:new |
insert |
所有字段都为null |
将要插入的数据 |
update |
更新前的值 |
更新后的值 |
delete |
删除前的值 |
所有字段都为null |
1 --判断:更新的值要大于原来的值
2 create or replace trigger trg_test3
3 before update of col on table
4 for each row
5 begin
6 if :old.col > :new.col then
7 raise_application_error(-20002,'更新的值小于原来的值,不能更新!');
8 end if;
9 end [trg_test3];