什么是触发器
触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。
触发器的特性
-
有begin end体,begin end;之间的语句可以写的简单或者复杂
-
什么条件会触发:insert、delete、update
-
什么时候触发:在增删改前或者后(before/after)
-
触发频率:针对每一行执行(每一行都会触发)
-
触发器定义在表上,附着在表上。
也就是由事件来触发某个操作,事件包括INSERT语句,UPDATE语句和DELETE语句;可以协助应用在数据库端确保数据的完整性。
注意:cannot associate a trigger with a TEMPORARY table or a view.(触发器不能关联在临时表和试图上)
如何创建触发器
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
-
BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后。
-
FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器,也就是说触发器的触发频率是针对每一行数据触发一次。
-
tigger_event详解:
-
INSERT型触发器:插入某一行时激活触发器,可能通过INSERT、LOAD DATA、REPLACE 语句触发(LOAD DAT语句用于将一个文件装入到一个数据表中,相当与一系列的INSERT操作);
-
UPDATE型触发器:更改某一行时激活触发器,可能通过UPDATE语句触发;
-
DELETE型触发器:删除某一行时激活触发器,可能通过DELETE、REPLACE语句触发。
-
-
trigger_order是MySQL5.7之后的一个功能,用于定义多个触发器,使用follows(尾随)或precedes(在…之先)来选择触发器执行的先后顺序。
触发器案例
创建只有一个执行语句的触发器
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件 ON 表名 FOR EACH ROW 执行语句;
例如:创建了一个名为trig1
的触发器,一旦在articles
表中有插入动作,就会自动往time
表里插入当前时间
mysql> CREATE TRIGGER trig1 AFTER INSERT
-> ON articles FOR EACH ROW
-> INSERT INTO time(time) VALUES(NOW());
创建有多个执行语句的触发器
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
执行语句列表
END;
例:定义一个触发器 trig2
,一旦删除 articles
表中的数据,就会执行BEGIN和END中的语句
mysql> DELIMITER ||
mysql> CREATE TRIGGER trig2 BEFORE DELETE
-> ON articles FOR EACH ROW
-> BEGIN
-> INSERT INTO time VALUES(NOW());
-> INSERT INTO time VALUES(NOW());
-> END||
mysql> DELIMITER ;
DELIMITER 的作用:定义遇到什么字符,才执行mysql语句
OLD
和 NEW
的作用
在触发器语句中使用出发该触发器的语句中的数据。
比如:想在触发器中对插入的数据做一些处理,然后再插入数据。
MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据,来引用触发器中发生变化的记录内容,具体地:
-
在INSERT型触发器中,NEW用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
-
在UPDATE型触发器中,OLD用来表示将要或已经被修改的原数据,NEW用来表示将要或已经修改为的新数据;
-
在DELETE型触发器中,OLD用来表示将要或已经被删除的原数据;
使用方法:
NEW.columnName (columnName为相应数据表某一列名)
例子:
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql> delimiter $$
mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
-> FOR EACH ROW
-> BEGIN
-> IF NEW.amount < 0 THEN
-> SET NEW.amount = 0;
-> ELSEIF NEW.amount > 100 THEN
-> SET NEW.amount = 100;
-> END IF;
-> END$$
mysql> delimiter ;
mysql> update account set amount=-10 where acct_num=137;
mysql> select * from account;
+----------+---------+
| acct_num | amount |
+----------+---------+
| 137 | 0.00 |
| 141 | 1937.50 |
| 97 | -100.00 |
+----------+---------+
mysql> update account set amount=200 where acct_num=137;
mysql> select * from account;
+----------+---------+
| acct_num | amount |
+----------+---------+
| 137 | 100.00 |
| 141 | 1937.50 |
| 97 | -100.00 |
+----------+---------+
查看触发器
查看触发器简单的信息
mysql> SHOW TRIGGERS;
查看触发器详细信息
SELECT * FROM information_schema.triggers;
查看指定触发器详细信息
mysql> select * from information_schema.triggers
-> where trigger_name='trig1';
所有触发器信息都存储在information_schema数据库下的triggers表中,可以使用SELECT语句查询,如果触发器信息过多,最好通过TRIGGER_NAME字段指定查询。
删除触发器
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name;
删除触发器之后最好使用上面的方法查看一遍;同时,也可以使用database.trig来指定某个数据库中的触发器。
如果不需要某个触发器时一定要将这个触发器删除,以免造成意外操作,这很关键。