触发器

触发器语法:

1 CREATE OR REPLACE TRIGGER trigger_name
2 {BEFORE | AFTER }
3 {INSERT | DELETE | UPDATE [OF column [, column …]]}  --可跟update具体列
4 ON [schema.]table_name | [schema.]view_name   --表名或视图名
5 [FOR EACH ROW ] WHEN 条件  -- 有for each row 为行级触发器,没有则为语句触发器。when 后可跟条件,比如只针对某个部门号的员工做更新。

1. 触发器的类型

①语句级触发器

-- 在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行。

②行级触发器(有语句:for each row)

-- 触发语句作用的每一条记录都被触发。在行级触发器中使用:old和:new伪记录变量,识别值得状态。

两种类型举例,例如:

insert into emp2 select * from emp where dempno=10;

比如这条插入语句dempno=10有3条数据,即一次会插入3条语句。

对于语句级触发器只会调用一次。针对表,只对表有影响。

对于行级触发器则会调用3次。针对行,影响多少行调用几次。

2. 触发器的使用场景

①实施复杂的安全性检查。例如:禁止在非工作时间插入数据。周末或上班前下班后

 1 create or replace trigger intoemp
 2 before insert 
 3 on emp    --无for each row,说明创建的是语句级触发器。
 4 declare
 5 begin
 6 if to_char(sysdate,'day') in('星期六','星期日') or
 7 to_number(to_char(sysdate,'hh24')) not between 9 and 18
 8 then 
 9 RAISE_APPLICATION_ERROR(-20000, '非工作日禁止插入数据');--抛出一个系统应用异常。(-2000~-2999)
10 end if;
11 end;

②数据的确认。例如:涨工资不能越涨越少。

:old 和:new代表同一条记录。:old 表示操作该行之前,这一行的值。:new 表示操作该行之后,这一行的值

 1 create or replace TRIGGER checksal
 2 before update
 3 on emp
 4 for each row
 5 declare
 6 begin
 7 if :old.sal>:new.sal then   
 8 RAISE_APPLICATION_ERROR(-20001, '涨后工资不能少于涨前工资,'||'涨前工资'||:old.sal||'涨后工资:'||:new.sal);
 9 end if;
10 end;

③数据库的审计。例如:当员工工资大于6000时,把员工信息保存到另一张表里audit_info 。

 1 create or replace trigger do_audit_emp_salary
 2 after update
 3 on emp
 4 for each row
 5 declare
 6 begin
 7 if :new.sal>6000 then
 8 insert into audit_info values(:new.empno||','||:new.ename||','||:new.sal);
 9 end if;
10 end;

④数据的备份或同步。例如:给员工涨工资,然后备份到备份表。create table emp_back as select * from emp; --建一张和emp一样的一张表(相当于拷贝emp表,结构和数据)

1 create or replace trigger backup_emp
2 after update
3 on emp 
4 for each row
5 declare
6 begin
7 update emp_back set sal=:new.sal where empno=:new.empno;
8 end;
9 create table emp_back as select * from emp;
posted @ 2020-03-30 22:18  佐小白  阅读(289)  评论(0)    收藏  举报