MySQL触发器 trigger之after与before区分

本文探讨了在数据库中使用触发器对库存进行管理的方法,包括如何在订单插入后更新库存,以及如何限制订单数量以避免库存爆库问题。通过创建after和before触发器实例,实现了对库存的有效控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

after:是先完成数据的增删改,然后再触发,触发的语句晚于监视的增删改,无法影响前面的增删改动作;也就是说先插入订单记录,再更新商品数量。当商品数量少于订单数量时造成爆库。
before:先完成触发,在进行增删改,触发语句先于监视的增删改,我们就有机会判断,修改即将发生的操作。
案例操作:
触发器使用after
当某个订单的数量超过库存的数量时会出现库存为负数。造成所谓的爆库问题。
#创建触发器test4
CREATE TRIGGER test4
AFTER
INSERT
ON `ord`
FOR EACH ROW
BEGIN
UPDATE goods SET num= num - new.much WHERE goods_id = new.gid;
END$$


触发器使用before
先触发,在判断处理之后再进行增删改不会,根据库存修改了订单的最大数量。当然我这只是简单的固定了一个值,其实可以用语句获取到动态的库存值。
#创建触发器test5
CREATE TRIGGER test5
BEFORE
INSERT
ON `ord`
FOR EACH ROW
BEGIN
  IF new.much >26 THEN
     SET new.much = 26;
  END IF;
UPDATE goods SET num= num - new.much WHERE goods_id = new.gid;
END$$


### MySQL After触发器Before触发器的区别及使用场景 在MySQL中,触发器是一种特殊的存储过程,它会在指定的表上执行特定的操作,当发生某些数据修改事件(如`INSERT`、`UPDATE`或`DELETE`)时自动触发。根据触发时间的不同,触发器可以分为`BEFORE`和`AFTER`两种类型。 #### 区别 1. **触发顺序** - `BEFORE`触发器:在执行增删改操作之前触发,允许对即将插入或更新的数据进行修改[^2]。 - `AFTER`触发器:在执行增删改操作之后触发,无法对即将插入或更新的数据进行修改[^3]。 2. **对`NEW`和`OLD`的访问权限** - `BEFORE`触发器:可以访问并修改`NEW`值(对于`INSERT`和`UPDATE`操作),但不能修改`OLD`值(对于`UPDATE`和`DELETE`操作)。例如,在插入或更新记录前,可以通过设置`NEW`字段来调整最终写入数据库的数据[^2]。 - `AFTER`触发器:只能读取`NEW`和`OLD`值,但无法对其进行修改。这意味着`AFTER`触发器主要用于基于已发生的操作执行后续逻辑,而不是改变操作本身[^3]。 3. **适用场景** - `BEFORE`触发器:适用于需要在数据写入或修改之前验证或调整数据的情况。例如,限制插入的数量、格式化数据或计算派生字段的值[^2]。 - `AFTER`触发器:适用于需要在数据写入或修改后执行其他操作的情况。例如,维护关联表中的数据一致性,或者记录日志信息。 #### 示例代码 以下是一个简单的示例,展示了如何使用`BEFORE`和`AFTER`触发器: ```sql -- 创建测试表 CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, goods_id INT, num INT ); CREATE TABLE goods ( id INT PRIMARY KEY, num INT ); -- 插入初始数据 INSERT INTO goods (id, num) VALUES (1, 100); -- 创建BEFORE触发器:限制插入数量不超过10 DELIMITER $$ DROP TRIGGER IF EXISTS trigger_before; CREATE TRIGGER trigger_before BEFORE INSERT ON orders FOR EACH ROW BEGIN IF NEW.num > 10 THEN SET NEW.num = 10; END IF; END $$ DELIMITER ; -- 创建AFTER触发器:更新商品库存 DELIMITER $$ DROP TRIGGER IF EXISTS trigger_after; CREATE TRIGGER trigger_after AFTER INSERT ON orders FOR EACH ROW BEGIN UPDATE goods SET num = num - NEW.num WHERE id = NEW.goods_id; END $$ DELIMITER ; -- 测试触发器 INSERT INTO orders (goods_id, num) VALUES (1, 20); SELECT * FROM orders; SELECT * FROM goods; ``` #### 使用场景分析 - **BEFORE触发器** 在上述示例中,`trigger_before`用于在插入订单前检查并限制数量。如果插入的数量超过10,则将其调整为10。这种场景下,`BEFORE`触发器非常适合,因为它可以在实际插入数据之前对数据进行修改[^2]。 - **AFTER触发器** 在上述示例中,`trigger_after`用于在插入订单后更新商品库存。这种场景下,`AFTER`触发器非常适合,因为它确保了订单插入完成后才更新相关联的商品表[^3]。 #### 注意事项 - `BEFORE`触发器可以修改`NEW`值,但不能修改`OLD`值。 - `AFTER`触发器不能修改`NEW`或`OLD`值,仅能读取它们。 - 触发器的逻辑应尽量简单,避免因复杂逻辑导致性能问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值