理论
语法
CREATE TRIGGER <触发器名称>
BEFORE|AFTER <触发事件>
ON <表名> FOR EACH ROW
<触发器激活后执行的操作>
其中:
- after:在记录操纵之后触发,是先完成数据的增删改,再触发,触发的语句晚于监视的增删改操作,无法影响前面的增删改动作
- before:是在记录操纵之前触发,是先完成触发,再增删改,触发的语句先于监视的增删改,我们就有机会判断,修改即将发生的操作,如:我们在触发之前需要判断new值和old值的大小或关系,如果满足要求就触发,不通过就修改再触发;如:表之间定义的有外键,在删除主键时,必须要先删除外键表,这时就有先后之分,这里before相当于设置了断点,我们可以处理删除外键。
- 触发事件:指明了激活触发程序的语句的类型,可以是下述值之一:
- INSERT:将新行插入表时激活触发程序,例如,通过INSERT、LOAD DATA和REPLACE语句。
- UPDATE:更改某一行时激活触发程序,例如,通过UPDATE语句。
- DELETE:从表中删除某一行时激活触发程序,例如,通过DELETE和REPLACE语句。
- 触发器激活后执行的操作:是当触发程序激活时执行的语句。如果你打算执行多个语句,可使用BEGIN … END复合语句结构。
普通示例
- 要求,每向emp表中插入一条数据,表temp中的数据会相应地发生变化
- 触发器
CREATE TRIGGER tri_insert
AFTER INSERT
ON emp FOR EACH ROW
UPDATE temp SET amount = amount+1;
OLD和NEW关键字
OLD和NEW关键字,能够访问受触发程序影响的行中的列。其中:old表示旧行,new表示新行。
- 在insert触发程序中,仅能使用NEW.col_name,没有旧行。
- 在delete触发程序中,仅能使用OLD.col_name,没有新行。
- 在update触发程序中,可以使用OLD.col_name来引用更新前的某一行的列,也能使用NEW.col_name来引用更新后的行中的列。
高级示例
需求
假设存在以下两个表,其中:
- tb_receive_addr为用户收件地址表
- tb_user为用户表,其中receive_addrs表示该用户所有的收件地址的个数
现在要求,利用触发器实现当tb_receive_addr表中增加or删除记录时,对应的tb_user表中的receive_addrs的个数也要发生相应的变化
添加数据触发器
- 触发器
create TRIGGER user_receive_addrs_insert
AFTER INSERT
ON tb_receive_addr FOR EACH ROW
UPDATE tb_user,tb_receive_addr SET receive_addrs = receive_addrs +1
where tb_user.id = new.user_id
-测试语句
insert into tb_receive_addr (receiver,addr,user_id) values ('bbbbb','bbbbb',192);
结果:tb_receive_addr中插入数据,tb_user表的receive_addrs的值加1。
删除数据触发器
- 触发器
create TRIGGER user_receive_addrs_delete
AFTER DELETE
ON tb_receive_addr FOR EACH ROW
UPDATE tb_user,tb_receive_addr SET receive_addrs = receive_addrs -1
where tb_user.id = old.user_id
-测试语句
DELETE FROM tb_receive_addr WHERE id= 20
结果:从tb_receive_addr中删除数据,tb_user表的receive_addrs的值减1。