理论

语法

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中的数据会相应地发生变化
  • mysql8 begin end 用法 mysql before_触发器

  • 触发器
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表示该用户所有的收件地址的个数

mysql8 begin end 用法 mysql before_数据库_02

现在要求,利用触发器实现当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。