MySQL 触发器

介绍

对表进行「增删改」 之前(或之后)被触发,自动执行一段事先写好的 SQL 代码

创建语法

delimiter $$ # 告诉程序使用 $$ 作为结束分隔符

CREATE TRIGGER [触发器的名字]
[触发器执行时机] [触发器监测的操作]
ON [表名]
FOR EACH ROW [触发器主体代码]//

$$ # 表示创建存储过程结束

解释:

  • [触发器执行时机]:

    • before:设置触发器是在关键动作执行之前触发
    • after:设置触发器是在关键动作执行之后触发
  • [触发器监测的操作]:触发器可以监测 INSERT、UPDATE、DELETE 操作,当监测的命令对触发器关联的表进行操作时,触发器就被激活了

  • [表名]:表示对改变进行操作。如果这个表被删除了,那么这个触发器也随之被删除。

  • FOR EACH ROW:这句表示只要满足触发器触发条件,触发器都会被执行,也就是说带上这个参数后,触发器将监测每一行对关联表操作的代码,一旦符合条件,触发器就会被触发。

  • [触发器主体代码]:这里是当满足触发条件后,被触发执行的代码主体。这里可以是一句 SQL 语句,也可以是多行命令。如果是多行命令,那么这些命令要写在 BEGIN…END 之间。

举例说明

BEFORE INSERT ON emp: 对 emp 表执行 insert 后,执行触发器。

AFTER INSERT ON emp: 对 emp 表执行 insert 后,执行触发器。可以通过 new 虚拟表获取新插入的字段值

BEFORE UPDATE ON emp :对 emp 表执行 UPDATE 前,执行触发器。

AFTER UPDATE ON emp:对 emp 表执行 UPDATE 后,执行触发器。可以通过 old 虚拟表获取更新前的字段值,通过 new 获取更新后的字段值

BEFORE DELETE ON emp:对 emp 表执行 DELETE 前,执行触发器。

AFTER DELETE ON emp:对 emp 表执行 DELETE 后,执行触发器。可以通过 old 虚拟表获取删除的字段值

例子

在 dept 表中增加 count 字段,int 类型,表示该部门的员工数量,那么添加员工、删除员工、员工从一个部门调入另一个部门时,要更新 dept 表的 count 字段,分以下情况:

  1. 每次向 emp 表中添加员工时,要同步让该部门的 count 字段加1

  2. 每次向 emp 表中删除员工时,要同步让该部门的 count 字段减1

  3. 如果员工从一个部门调到另一个部门,即 emp 表中的 deptno 修改了,那么 dept 表调出部门的 count 字段减1,调入部门的 count 字段加1

第一种情况的触发器:

CREATE TRIGGER tri_emp_insert AFTER INSERT ON emp FOR EACH ROW
UPDATE dept SET COUNT = COUNT+1 WHERE deptno = new.deptno

第二种情况的触发器:

CREATE TRIGGER tri_emp_delete AFTER DELETE ON emp FOR EACH ROW
UPDATE dept SET COUNT = COUNT-1 WHERE deptno = new.deptno

第三种情况的触发器:

delimiter $$ # 告诉程序使用 $$ 作为结束分隔符
CREATE TRIGGER tri_emp_af_update_deptno AFTER update ON emp FOR EACH ROW
BEGIN
UPDATE dept SET COUNT = COUNT + 1 WHERE deptno = new.deptno;
UPDATE dept SET COUNT = COUNT - 1 WHERE deptno = old.deptno;
END
$$

例子

有 t_account 账户表,记录姓名、余额
每次开户后、余额变动后、注销后,都将姓名、余额记录到 t_account_log 表中

目的:将每一次的重要操作,记录起来, 方便后面查看,当对方不认账时,也能拿出证据

准备工作

创建 t_account 账户表:

create taboe t_account(
    aid int primary key auto_inrement,
    aname varchar(30),
    amoney decimal(9,2)
)

创建 t_account_log 账户操作记录表:

create table t_account_log (
    lid int  PRIMARY key auto_increment,
    aid int ,
    l_name varchar(20),
    l_money DECIMAL(9,2),
    l_datetime datetime,
    l_action varchar(20)
)

创建开户触发器

drop TRIGGER tri_account_aft_ins
create TRIGGER tri_account_aft_ins
AFTER INSERT 
on t_account for each row
BEGIN

insert into t_account_log(aid,l_name,l_money,l_datetime,l_action) values (new.aid,new.name,new.money,now(),'insert');

END

执行开户:

insert into t_account(name,money) values ('马云',100)

查看 t_acount_log 表:

select * from t_acount_log

创建修改金额触发器

drop TRIGGER tri_account_aft_upd
create TRIGGER tri_account_aft_upd
AFTER update 
on t_account for each row
BEGIN

insert into t_account_log(aid,l_name,l_money,l_datetime,l_action) values (old.aid,old.name,old.money,now(),'before_update');
insert into t_account_log(aid,l_name,l_money,l_datetime,l_action) values (new.aid,new.name,new.money,now(),'after_update');

END

执行修改金额:

update t_account set money = money + 1 where aid = '11'

查看 t_acount_log 表:

select * from t_account_log

创建注销账户触发器

drop TRIGGER tri_account_aft_del
create TRIGGER tri_account_aft_del
AFTER DELETE 
on t_account for each row
BEGIN

insert into t_account_log(aid,l_name,l_money,l_datetime,l_action) values (old.aid,old.name,old.money,now(),'delete');

END

执行注销账户:

delete from t_account where aid = '11'

查看 t_acount_log 表:

select * from t_account_log

参考:
https://blog.csdn.net/qq_54169998/article/details/122720159
https://zhuanlan.zhihu.com/p/439273702


原文出处:/show_1IX64k91INts.html