一、触发器
版本要求:MySQL5+
触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句):
□ DELETE
□ UPDATE
□ INSERT
二、创建触发器
1. 创建触发器(4条信息)
- 唯一的触发器名
- 触发器关联的表
- 触发器应该响应的活动(DELETE、INSERT、UPDATE)
- 触发器何时执行(处理之前后之后)
注意:保持每个数据库的触发器名唯一。在MySQL 5中,触发器名必
须在每个表中唯一,但不是在每个数据库中唯一。
例1:创建一个简单的触发器
CREATE TRIGGER newproduct AFTER INSERT ON products
FOR EACH ROW SELECT 'Product added';
代码说明:
- CREATE TRIGGER用来创建名为newproduct的新触发器。
- 触发器可在一个操作发生之前或之后执行,这里给出了AFTER INSERT,所以此触发器将在INSERT语句成功执行后执行。
- 这个触发器还指定FOR EACH ROW,因此代码对每个插入行执行。
- 在这个例子中,文本Product added将对每个插入的行显示一次。
注意:
- 只有表才支持触发器,视图不支持,临时表也不支持。
- 每个表的每个事件只允许一个触发器
- 每个表最多支持6个触发器(每条INSERT、UPDATE
和DELETE的之前和之后)
- 单一触发器不能与多个事件或多个表关联,所以,如果你需要一个对INSERT和UPDATE操作执行的触发器,则应该定义两个触发器。
触发器失败
如果BEFORE触发器失败,则MySQL将不执行请求的操作。此外,如果BEFORE触发器或语句本身失败,MySQL将不执行AFTER触发器(如果有的话)。
三、删除触发器
DROP TRIGGER 触发器名字;
注意:触发器不能更新或覆盖。为了修改一个触发器,必须先删除它,然后再重新创建。
四、INSERT触发器
INSERT触发器在INSERT语句执行之前或之后执行 。
- 在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行
- 在BEFORE INSERT触发器中,NEW的值也可以被更新(允许更改被插入的值)
- 对于AUTO_INCREMENT列,NEW在INSERT执行前包含0,在INSERT被执行后包含新的自动生成值。
例1
CREATE TRIGGER neworder AFTER INSERT ON orders
FOR EACH ROW SELECT NEW.order_num;
- 此代码创建一个名为neworder的触发器,它按照AFTER INSERT
ON orders执行。 - 在插入一个新订单到orders表时,MySQL生成一个新订单号并保存到order_num中。
- 触发器从NEW. order_num取得这个值并返回它。
此触发器必须按照AFTER INSERT执行,因为在BEFORE INSERT语句执行之前,新order_num还没有生成。对于orders的每次插入使用这个触发器将总是返回新的订单号。
测试这个触发器,试着插入一下新行,如下所示

BEFORE或AFTER?
通常,将BEFORE用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据)。本提示也适用于UPDATE触发器。
五、DELETE触发器
DELETE触发器在DELETE语句执行之前或之后执行:
- 在DELETE触发器代码内,可以引用一个名为OLD的虚拟表,访问被删除的行
- OLD中的值全部都是只能读的,不能更新
例1
CREATE TRIGGER deleteorder BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
INSERT INTO archive_orders(order_num, order_date, cust_id)
VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
END;
在任意订单被删除前将执行此触发器。
- 它使用一条INSERT语句将OLD中的值(要被删除的订单)保存到一个名为archive_orders的存档表中(为实际使用这个例子,你需要用与orders相同的列创建一个名为archive_orders的表)。
使用BEFORE DELETE触发器的优点(相对于AFTER DELETE触发器
来说)为,如果由于某种原因,订单不能存档,DELETE本身将被放弃。(不太理解这句话。)
多语句触发器
正如所见,触发器deleteorder使用BEGIN和END语句标记触发器体。这在此例子中并不是必需的,不过也没有害处。
使用BEGIN END块的好处是触发器能容纳多条SQL语句(在BEGIN END块中一条挨着一条)。
六、UPDATE触发器
UPDATE触发器在UPDATE语句执行之前或之后执行
- 在UPDATE触发器代码中,你可以引用一个名为OLD的虚拟表访问
以前(UPDATE语句前)的值,引用一个名为NEW的虚拟表访问新
更新的值; - 在BEFORE UPDATE触发器中,NEW中的值可能也被更新(允许更改
将要用于UPDATE语句中的值) - OLD中的值全都是只读的,不能更新。
CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW SET NEW.vend_state = Upper(NEW.vend_state);
七、触发器进一步介绍
与其他DBMS相比,MySQL 5中支持的触发器相当初级。未来的
MySQL版本中有一些改进和增强触发器支持的计划。
创建触发器可能需要特殊的安全访问权限,但是,触发器的执行
是自动的。如果INSERT、UPDATE或DELETE语句能够执行,则相关
的触发器也能执行。
应该用触发器来保证数据的一致性(大小写、格式等)。在触发器
中执行这种类型的处理的优点是它总是进行这种处理,而且是透
明地进行,与客户机应用无关。
触发器的一种非常有意义的使用是创建审计跟踪。使用触发器,
把更改(如果需要,甚至还有之前和之后的状态)记录到另一个
表非常容易。
遗憾的是,MySQL触发器中不支持CALL语句。这表示不能从触发
器内调用存储过程。所需的存储过程代码需要复制到触发器内。
网友评论