概述
本章,您将学习 MySQL 中的触发器。
由前文有关事件调度器的文章可知,事件调度器 是基于时间触发的定时任务,MySQL 中还是有一种基于 DML (update、insert、delete)触发的自动任务,被称为 触发器(Trigger)。
两者对比如下:
| 项 | 作用 | 触发因素 |
|---|---|---|
| 事件调度器 | 周期性地运行数据库对象 | 时间 |
| 触发器 | 维护数据的一致性 | 数据的变更(DML) |
触发器的优缺点:
- 优点:能较好保证数据一致性
- 缺点:该数据库对象的位置比较隐蔽,这会导致当对一个表或多个表执行 DML 操作时容易出现逻辑错误
管理触发器
创建触发器
语法如下:
CREATE
[DEFINER = user]
TRIGGER [IF NOT EXISTS] 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
说明:
[ ]表示可选,{ }表示必需,|表示任选其中的一个- trigger_time - 触发器的时间,是在 DML 之前(
before关键字)还是 DML 之后(after关键字) - trigger_event - 指定触发器的触发事件
- tbl_name - 表名
- trigger_body - 触发器主体,可以是单条 SQL 语句,也可以是
begin…end包裹的的 SQL 语句块(代码块)。若使用begin...end语句块(代码块),则需要在 create trigger 语句之前使用delimiter关键字预先定义分隔符(标记符)
示例一:在向 users 表中插入新记录之前,自动将当前日期时间以值的方式插入到 created_at 字段中
use home;
# 创建用户的信息表
create table if not exists users (
id int auto_increment primary key,
username varchar(50) not null,
email varchar(100),
created_at datetime
);
delimiter //
# 这里 new 是特殊的关键字,now() 是 MySQL 中的函数,set 关键字是赋值操作
create trigger trigger_create_time
before insert
on users for each row
begin
set new.created_at = now();
end //
delimiter ;
# 测试触发器
insert into users(username,email) values('tom','[email protected]');
# 查看
select * from users;
+----+----------+-----------------+---------------------+
| id | username | email | created_at |
+----+----------+-----------------+---------------------+
| 1 | tom | [email protected] | 2025-10-29 13:10:16 |
+----+----------+-----------------+---------------------+
1 row in set (0.00 sec)
示例二:当班级有新学生加入时,自动更新当前班级的总人数
use home;
# 创建班级表
create table class(
id int primary key,
class_name varchar(50),
total_number int default 0
);
# 向班级表插入数据
insert into class(id,class_name) values(601,'六年级一班'),(602,'六年级二班'),(603,'六年级三班');
# 创建学生表
create table students(
id int primary key,
student_name varchar(20),
class_id int
);
delimiter //
# 通过 new.class_id 获取新学生的 class_id
create trigger total_student_nu
after insert
on students for each row
begin
update class set total_number = total_number + 1 where id = new.class_id;
end //
delimiter ;
# 测试触发器
insert into students values(1000, '张三', 601),(1001, '李四', 601),(2000,'汤姆',602),(3000, '王五', 603);
select * from class;
+-----+-----------------+--------------+
| id | class_name | total_number |
+-----+-----------------+--------------+
| 601 | 六年级一班 | 2 |
| 602 | 六年级二班 | 1 |
| 603 | 六年级三班 | 1 |
+-----+-----------------+--------------+
3 rows in set (0.00 sec)
修改已存在库中的触发器
一旦创建了符合语法规则的触发器之后,则不能对已有触发器的语法进行修改,通常的做法是先删除已存在的触发器并创建新的触发器。
查看触发器
# 查看当前库下的所有触发器
show triggers;
# 查看特定表下的触发器
show trigger from 表名;
# 查看特定触发器的创建语法
show create trigger 触发器名称;
# 查看当前数据库实例的所有触发器
select * from information_schema.triggers;
删除触发器
drop trigger if exists 触发器名称;
生产环境下的使用建议
触发器的数量不宜过多且单个触发器的逻辑应该尽量简单(即单个触发器的行数不宜过多),这样维护起来会更加方便。
版权声明:「自由转载-保持署名-非商业性使用-禁止演绎 3.0 国际」(CC BY-NC-ND 3.0)
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论










