Alex_McAvoy

想要成为渔夫的猎手

SQL 触发器

【触发器定义】

基本语法

触发器又称事件-条件-动作规则,当特定的系统事件发生时,对规则的条件进行检查,如果条件成立则执行规则中的动作,否则不执行该动作

规则中的动作体可以很复杂,可以涉及其他表和其他数据库对象,通常是一段 SQL 存储过程

SQL 中,使用 CREATE TRIGGER 命令建立触发器,其语法如下

1
2
3
4
5
CREATE TRIGGER <触发器名>           /*每当触发事件发生时,该触发器被激活*/
{BEFORE|AFTER} <触发事件> ON <表名> /*指明触发器激活的时间*/
REFERENCING NEW|OLD ROW AS <变量> /*指出引用的变量*/
FOR EACH {ROW|STATEMENT} /*定义触发器的类型,指明动作体执行的频率*/
[WHEN <触发条件>] <触发动作体>; /*触发动作体*/

语句说明

1.创建者

表的拥有者才可创建触发器,一个表上允许有多个触发器,具体数量由具体的 RDBMS 在设计时确定

2.触发器名

触发器名可以包含模式名,也可不包含模式名

同一模式向下,触发器名必须唯一,且触发器名与表名必须在同一模式下

3.触发事件

触发事件有 INSERTDELETEUPDATE 等,也可是他们的组合

触发的时机由 BEFOREAFTER 决定,代表触发事件之前或之后触发触发器

4.表名

触发器只能定义在基本表上,不能定义在视图上

当基本表变化时,将激活定义在该表上相应触发事件的触发器

5.触发器类型

根据触发动作的间隔尺寸区分,触发器分为行级触发器 FOR EACH ROW语句级触发器 FOR EACH STATEMENT

假设表有 1000 行,如果是行级触发器,则执行 1000 次,如果是语句级触发器,则执行 1 次

6.触发条件

触发器被激活时,只有当触发条件为真时,触发动作体才被执行

如果省略 WHEN 触发条件,则触发动作体在触发器激活后立刻执行

7.触发动作体

触发动作体既可以是一个匿名 PL/SQL 数据块,也可以是对已创建存储过程的调用

8.引用变量

如果是行级触发器,用户可以在出触发动作体中,使用 NEW 引用 UPDATEINSERT 事件之后的新值,或使用 OLD 引用 UPDATEDELETE 事件前的旧值

如果是语句级触发器,则不能在触发动作体中使用 NEWOLD 进行引用

实例

当表 sc 的 Grade 属性进行修改时,若分数增加了 10%,则将此次操作记录到另一个表 sc_u(Sno, Cno, OldGrade, NewGrade) 中

1
2
3
4
5
6
7
8
9
10
CREATE TRIGGER sc_t        /*触发器名*/
AFTER UPDATE 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, NewTuple.Grade);

【触发器激活】

触发器的执行,是由触发事件激活的,并由数据库服务器自动执行

一个数据表上可能定义了多个触发器,同一个表上的多个触发器激活时遵循如下的执行顺序:

  1. 执行该表上的 BEFORE 触发器
  2. 激活触发器的 SQL 语句
  3. 执行该表上的 AFTER 触发器

对于同一个表上的多个 BEFOREALTER 触发器,遵循谁先创建谁执行的原则,即按照触发器创建的时间先后顺序执行

【触发器删除】

删除触发器时,要求触发器必须是已创建的触发器,且具有相应权限

删除触发器的语法如下

1
DROP TRIGGER <触发器名> ON <表名>;
感谢您对我的支持,让我继续努力分享有用的技术与知识点!