MySQL基础22 — 触发器

概述

本章,您将学习 MySQL 中的触发器。

由前文有关事件调度器的文章可知,事件调度器 是基于时间触发的定时任务,MySQL 中还是有一种基于 DML (updateinsertdelete)触发的自动任务,被称为 触发器(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 触发器名称;

生产环境下的使用建议

触发器的数量不宜过多且单个触发器的逻辑应该尽量简单(即单个触发器的行数不宜过多),这样维护起来会更加方便。

Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇