5.7 触发器
♥ 触发器(Trigger)
◾ 使用户定义在关系表上的一类由事件驱动的特殊过程
◾ 任何用户用表的增、删、改操作均由服务器自动激活相应的触发器
◾ 触发器可以实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力
5.7.1 定义触发器
5.7.2 激活触发器
5.7.3 删除触发器
♥ create trigger语法格式
-- 只有表的拥有者才可以用create trigger创建触发器
create trigger<触发器名> -- 1. 触发器名可以包含模式名,也可以不包含模式名 2.同一模式下,触发器名必须是唯一的; 3.触发器名和表名必须在同一模式下
{before | after}<触发事件> on <表名>
-- before/after是触发的时机:after表示在触发器时间的操作执行之后激活触发器;before表示在触发器时间的操作执行之前激活触发器
-- 触发事件:1.insert、delete或update 2.几个事件的组合 3.update of<触发列,...>
-- <表名>(触发器的目标表名)意味着:1.触发器只能定义在基本表上,不能定义在视图上 2.当基本表的数据发生变化时,将激活定义在该表上相应触发事件的触发器
referencing NEW|OLD ROW AS <变量>
for each {row | statement}
-- 触发器类型:1.行级触发器(for each row) 2.语句级触发器(for each statement)
[when <触发条件>]<触发动作体>
-- 触发器被激活时,只有当触发条件为真是触发动作才执行;否则触发动作不执行
-- 如果省略when触发条件,则触发动作在触发器激活后立即执行
-- <触发动作体>:
-- ● 触发动作体可以是一个匿名PL/SQL过程块,也可以是对已有创建存储过程的调用
-- ● 如果是行级触发器,用户都可以在过程体中使用new和old引用事件之后的新值和事件之前的旧值
-- ● 如果是语句级触发器,则不能在触发动作体中使用new或old进行引用
-- ● 如果触发动作体执行失败,激活触发器的事件就会终止执行,触发器的目标表或触发器肯呢个影响的其他对象不发生任何变化
当指定的系统事件发生时,对规则的条件进行检查,如果条件成立则执行规则中的动作,否则不执行该动作。规则中的动作体可以很复杂,通常是一段SQL存储过程。
触发器又叫作事件-条件-动作(event-condition-action)规则。
在之前的例子 的TEACHER表上创建一个after update触发器,触发事件是update语句:
update TEACHER set Deptno = 5;
假设表TEACHER有1000行
● 如果是语句级触发器,那么执行完该语句后,触发动作只发生一次
● 如果是行级触发器,触发动作将执行1000次
[例 5.1] 在对表SC的Grade属性进行修改时,若分数增加10%则将此次操作记录到下面表中:
SC_U(Sno, Cno, Oldgrade, Newgrade) --Oldgrade:修改前的分数,Newgrade:修改后的分数
create trigger SC_T
after update of Grade on SC
referencing
old row as OldTuple,
new row as NewTuple
for each row
when(NewTuple.Grade >= 1.1 * OldTuple.Grade)
insert into SC_U(Sno, Cno, OldGrade, NewGrade)
values(OldTuple.Sno, OldTuple.Cno, OldTuple.Grade, NewGrade.Grade)
[例 5.2] 每次对Student的插入操作所增加的学生个数记录到表StudentInsertLog中
create trigger Student_Count
after insert on Student
referencing
new table as delta
for each statement
insert into StudentInsertLog(Numbers)
select count(*) from delta
[例 5.3] 定义一个before行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”
create trigger Insert_Or_Update_Sal
before insert or update on Teacher
for each row
begin
if(new.Job='教授') and (new.Sal < 4000)
then new.Sal := 4000;
end if;
end;
5.7.1 定义触发器
5.7.2 激活触发器
5.7.3 删除触发器
♥ 触发器的执行,是由触发时间激活的,并由数据库服务器自动执行
♥ 一个数据库上可能定义了多个触发器,遵循如下执行顺序:
(1)执行该表上的before触发器;
(2)激活触发器的SQL语句;
(3)执行该表上的after触发器。
当有多个before或after触发器时,通常按照触发器创建时间的先后执行 或 触发器名字的字母排序执行
5.7.1 定义触发器
5.7.2 激活触发器
5.7.3 删除触发器
♥ 删除触发器SQL语法:
◾ drop trigger <触发器名> on <表名>;
♥ 触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除