MySQL 触发器怎么用,举几个例子让你大概明白下原理和操作
- 问答
- 2025-12-27 15:43:05
- 1
MySQL触发器就像是安插在数据库表里的一个“自动监视器”加“小帮手”,它的核心思想很简单:当你在某个表上执行特定的操作(比如增加一条记录、修改一条记录、删除一条记录)之前或之后,让数据库自动地去执行一段你预先设定好的SQL代码,你不需要在应用程序里手动调用,数据库自己就会默默完成。
触发器的核心要素
要理解触发器,你得先明白它是由哪几个关键部分拧在一起的:
-
触发时机: 这件事是发生在之前还是之后?主要有两种:
BEFORE:在主要操作执行之前,先运行你的触发器代码,在插入新数据前,先检查一下数据是否合法。AFTER:在主要操作执行之后,再运行你的触发器代码,在成功插入一条新订单后,自动去减少库存数量。
-
触发事件: 是什么操作触发了它?主要有三种:
INSERT:当有新的数据行被插入时。UPDATE:当已有的数据行被修改时。DELETE:当已有的数据行被删除时。
-
关联表: 这个触发器是绑在哪张表上的?每个触发器都只属于一张表。
一个完整的触发器定义听起来就像是:“在某张表上,发生某种操作(INSERT/UPDATE/DELETE)之前或之后,请执行以下SQL代码。”
触发器里的“临时变量”:NEW 和 OLD
这是理解触发器原理非常关键的一步,当触发器被激活时,数据库会给你两个临时的、虚拟的表,叫做 NEW 和 OLD,你可以把它们想象成“快照”。
NEW:它存放着即将要发生或刚刚发生的数据。- 在
INSERT触发器中,NEW表示你想要插入的那条新记录,你可以通过NEW.字段名来访问新数据的值。 - 在
UPDATE触发器中,NEW表示修改之后的新数据。
- 在
OLD:它存放着变化之前的数据。- 在
UPDATE触发器中,OLD表示修改之前的旧数据。 - 在
DELETE触发器中,OLD表示即将被删除的那条旧记录。
- 在
需要注意的是:
- 在
INSERT触发器中,没有OLD,因为插入前这条记录不存在。 - 在
DELETE触发器中,没有NEW,因为删除后这条记录就没了。
动手操作:几个例子让你明白

假设我们有一个简单的电商数据库,有orders(订单表)和products(商品表)两张表。
products表有:product_id(商品ID),product_name(商品名),stock_quantity(库存数量)。orders表有:order_id(订单ID),product_id(商品ID),quantity(订购数量)。
例子1:AFTER INSERT 触发器 —— 自动扣减库存
场景:用户下单成功后,我们希望能自动减少相应商品的库存,而不是手动去写两条SQL语句。
DELIMITER // -- 临时改变语句结束符,因为触发器代码里有分号
CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW -- 表示每影响一行数据就触发一次
BEGIN
-- 当有新订单插入后,更新商品表,将库存减去新订单的数量
UPDATE products
SET stock_quantity = stock_quantity - NEW.quantity -- 这里的 NEW.quantity 就是刚插入的订单中的数量
WHERE product_id = NEW.product_id; -- 通过商品ID找到对应的商品
END//
DELIMITER ; -- 把语句结束符改回分号
原理:当你执行 INSERT INTO orders ... 语句时,这个触发器会自动启动,它利用 NEW.quantity 和 NEW.product_id 这两个新插入的值,去products表里完成库存的更新,你只做了一次“下单”操作,但数据库自动帮你做了两件事。
例子2:BEFORE UPDATE 触发器 —— 数据合法性检查
场景:在修改商品价格之前,我们想检查一下新价格是否合理,比如不允许把价格改成负数。

DELIMITER //
CREATE TRIGGER before_product_update
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
-- 如果试图将价格或库存设置为负数,则强制将其设为0
IF NEW.price < 0 THEN
SET NEW.price = 0; -- 注意这里直接修改了 NEW 中的值!
END IF;
IF NEW.stock_quantity < 0 THEN
SET NEW.stock_quantity = 0;
END IF;
END//
DELIMITER ;
原理:当你执行 UPDATE products SET price = -10 WHERE ... 时,这个触发器会在真正更新数据之前被触发,它检查 NEW.price(即-10)是否小于0,因为是小于0的,所以触发器内部的代码 SET NEW.price = 0; 执行了,这相当于把你要更新的值从-10改成了0,数据库才拿着这个已经被触发器修改过的 NEW 值(price=0)去执行最终的UPDATE操作,这是一种数据安全的保障。
例子3:AFTER DELETE 触发器 —— 创建审计日志
场景:当有订单被删除时,我们希望记录一条日志,记下谁在什么时候删除了哪条订单。
我们先创建一个日志表order_delete_log:id(日志ID), order_id(被删订单ID), deleted_at(删除时间)。
DELIMITER //
CREATE TRIGGER after_order_delete
AFTER DELETE ON orders
FOR EACH ROW
BEGIN
-- 向日志表插入一条记录,记录被删除的订单信息
INSERT INTO order_delete_log (order_id, deleted_at)
VALUES (OLD.order_id, NOW()); -- 这里的 OLD.order_id 就是被删除订单的ID
END//
DELIMITER ;
原理:当你执行 DELETE FROM orders WHERE ... 时,触发器在删除操作之后启动,它利用 OLD.order_id 来获取那条已经被删除的记录的订单号,然后将其与当前时间一起插入到日志表中,留下痕迹。
总结一下
触发器就是把一些自动化的、有依赖关系的数据库操作捆绑在一起,它的好处是保证了业务逻辑的原子性和一致性(相关操作一定会一起发生),减少了应用程序的代码量,但也要小心使用,因为过多的、复杂的触发器会让数据库的逻辑变得不透明,难以调试和维护,它就像一把双刃剑,用好了是自动化利器,用不好就是调试噩梦。
本文由度秀梅于2025-12-27发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/69492.html
