创建触发器

CREATE [or REPLACE] TRIGGER 触发器名

{BEFORE | AFTER}

{DELETE | INSERT | UPDATE [OF 列明]}

ON 表名

[FOR EACH ROW [WHEN(条件)]]    --指明触发器类型,有这个语句就指明是行级触发器,否则就是语句级触发器

PLSQL块

==================================================================

语句级触发器

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

行级触发器

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

=================================================================

select * from emp where deptno = 10; --查询出3条记录

eg: insert into emp10 seleect * from emp where depton=10;

语句级触发器:针对是表,针对的是emp10表,尽管插入了3条数据,但是语句级触发器只操作了一次。

行级触发器:   针对是行,行级触发器会被调用三次。

=================================================================

--应用场景一、实施复杂的安全性检查

--禁止在非工作时间插入新员工

/*

周末:to_char(sysdate,'day') in ('星期六','星期日')

上班前,下班后:to_number(to_char(sysdate,'hh24')) not between 9 and 18 

raise:抛出数据库错误

*/

create or replace trigger securityemp

befor insert  --在插入操作之前出发

on emp    --针对emp这张表

--declare      由于程序中不需要使用变量所以可以不用写declare

begin

  if to_char(sysdate,'day') in ('星期六','星期日') or

  to_number(to_char(sysdate,'hh24')) not between 9 and 18 

  --禁止insert员工,可以通过抛出例外

  raise_application_error(-20001,'禁止在非工作时间插入新员工');  --抛出一个应用程序错误,这个函数接收两个参数,第一参数是错误代码(在oracle程序中自己定义的错误代码必须在

                                   --区间(-20000,-20999)),第二个是错误信息

  end if;

end;

/

=================================================================

--应用场景二,数据的确认

--涨后的薪水不能少于涨前的薪水

/*

1、:old和:new 代表的是同一条记录

2、:old 表示操作该行之前,这一行的值

   :new 表示操作该行之后,这一行的值

  ||链接符

*/

create or replace triggger checksalary

before update 

on emp

for each row

begin

  --if 涨后的薪水 < 涨前的薪水 then

  if:new.sal < :old.sal then

  raise_application_error(-20002,'涨后的薪水不能少于涨前的薪水.涨后的薪水:'||:new.sal||'涨前的薪水:'||:old.sal||);

  end if;

end;

/

================================================================

/*

应用场景三: 数据库审计-->基于值的审计功能

给员工涨工资,当涨后的薪水超过6000块钱的时候,审计该员工的信息

*/

--创建表,用于保存审计信息

create table audit_info

(

information varchar2(200)

);

create or replace trigger do_audit_emp_salary

after update 

on emp

for each row

begin

  --当涨后的薪水>6000,插入审计信息

  if :new.sal>6000 then 

  insert into audit_info values(:new.empno||'     '||:new.ename||'     '||:new.sal);

  end if;

end;

/

================================================================

/*

应用场景四、数据的备份和同步

当给员工涨完工资后 ,自动备份新的员工工资到备份表中

*/

--创建员工表的备份

create table emp_back as select * from emp;

create or replace trigger sync_salary

after update 

on emp 

for each row

begin

  --当主表更新后,自动更新备份表

  update emp_back set sal=:new.sal where empno=:new.empno;

end;

/