『MySQL』使用触发器
触发器
需要MySQL 5:对触发器的支持是在MySQL 5中增加的。
触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句,
或位于
BEGIN
和END
语句之间的一组语句:DELETE
;INSERT
;UPDATE
。
其他MySQL语句不支持触发器。
创建触发器
在创建触发器时,需要给出4条信息:
- 唯一的触发器名;
- 触发器关联的表;
- 触发器应该响应的活动(
DELETE
、INSERT
或UPDATE
); - 触发器何时执行(处理之前或之后)。
保持每个数据库的触发器名唯一:在MySQL 5中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一。
这表示同一数据库中的两个表可具有相同名字的触发器。
这在其他每个数据库触发器名必须唯一的DBMS中是不允许的,而且以后的MySQL版本很可能会使命名规则更为严格。因此,现在最好是在数据库范围内使用唯一的触发器名。
1 | -- 创建名为newproduct的新触发器,对每个插入的行显示Product added |
仅支持表:只有表才支持触发器,视图不支持(临时表也不支持)。
触发器按每个表每个事件每次的定义,每个表每个事件每次只允许一个触发器;
因此每个表最多支持6个触发器(每条
INSERT
、UPDATE
和DELETE
的之前和之后)。单一触发器不能与多个事件多个表关联;
如果需要一个对
INSERT
和UPDATE
操作执行的触发器,则应该定义两个触发器。触发器失败:如果
BEFORE
触发器失败,则MySQL将不执行请求的操作。如果
BEFORE
触发器或语句本身失败,MySQL将不执行AFTER
触发器(如果有的话)。
删除触发器
触发器不能更新或覆盖。
为了修改一个触发器,必须先删除它,然后再重新创建。
1 | -- 删除一个触发器 |
使用触发器
INSERT触发器
INSERT
触发器在INSERT
语句执行之前或之后执行。需要注意以下几点:
- 在
INSERT
触发器代码内,可引用一个名为NEW
的虚拟表,访问被插入的行。 - 在
BEFORE INSERT
触发器中,NEW
中的值也可以被更新(允许更改被插入的值)。 - 对于
AUTO_INCREMENT
列,NEW
在INSERT
执行之前包含0,在INSERT
执行之后包含新的自动生成值。
- 在
1 | CREATE TRIGGER neworder AFTER INSERT ON orders |
BEFORE或AFTER?通常,将
BEFORE
用于数据验证和净化;目的是保证插入表中的数据确实是需要的数据。此也适用于
UPDATE
。
DELETE触发器
DELETE
触发器在DELETE
语句执行之前或之后执行。需要注意以下几点:
- 在
DELETE
触发器代码内,你可以引用一个名为OLD
的虚拟表,访问被删除的行。 OLD
中的值全都是只读的,不能更新。
- 在
1 | -- 使用OLD保存将要被删除的行到一个存档表中 |
使用
BEFORE DELETE
触发器的优点,相对于AFTER DELETE
触发器来说,如果由于某种原因,订单不能存档,
DELETE
本身将被放弃。多语句触发器:使用
BEGIN END
块的好处是触发器能容纳多条SQL语句(在BEGIN END
块中一条挨着一条)。
UPDATE触发器
UPDATE
触发器在UPDATE
语句执行之前或之后执行。需要注意以下几点:
- 在
UPDATE
触发器代码中,可以引用一个名为OLD
的虚拟表访问以前(UPDATE
语句前),引用一个名为NEW
的虚拟表访问新更新的值。 - 在
BEFORE UPDATE
触发器中,NEW
中的值可能也被更新(允许更改将要用于UPDATE
语句中的值)。 OLD
中的值全都是只读的,不能更新。
- 在
1 | -- 保证州名缩写总是大写(不管UPDATE语句中给出的是大写还是小写) |
关于触发器的进一步介绍
结束之前,再介绍一些使用触发器时需要记住的重点:
与其他DBMS相比,MySQL 5中支持的触发器相当初级。
未来的MySQL版本中有一些改进和增强触发器支持的计划。
创建触发器可能需要特殊的安全访问权限,但是,触发器的执行是自动的。
如果
INSERT
、UPDATE
或DELETE
语句能够执行,则相关的触发器也能执行。应该用触发器来保证数据的一致性(大小写、格式等)。
在触发器中执行这种类型的处理的优点是它总是进行这种处理,而且是透明的进行,与客户机应用无关。
触发器的一种非常有意义的使用是创建审计跟踪。
使用触发器,把更改(如果需要,甚至还有之前和之后的状态)记录到另一个表非常容易。
遗憾的是,MySQL触发器中不支持
CALL
语句。这表示不能从触发器内调用存储过程。所需的存储过程代码需要复制到触发器内。