内容简介:本文主要介绍MySQL存储过程参数与返回值的相关知识,包括参数类型、使用方法和最佳实践等内容。风哥教程参考MySQL官方文档MySQL Triggers、MySQL Server Administration。 01 更多视频教程www.fgedu.net.cn 02 学习交流加群风哥微信: itpux-com 03 学习交流加群风哥QQ113257174
Part01-基础概念与理论知识
1.1 触发时机类型
MySQL触发器支持两种触发时机:BEFORE和AFTER。BEFORE触发器在操作执行前触发,AFTER触发器在操作执行后触发。 04 风哥提示: 05更多学习教程公众号风哥教程itpux_com 06 from mysql视频:www.itpux.com
1. BEFORE触发器
– 在INSERT、UPDATE、DELETE操作执行前触发
– 可以修改NEW值(INSERT和UPDATE)
– 不能修改OLD值
– 常用于数据验证和预处理
2. AFTER触发器
– 在INSERT、UPDATE、DELETE操作执行后触发
– 不能修改NEW或OLD值
– 数据已经写入表
– 常用于审计和日志记录
Part02-生产环境规划与建议
2.1 BEFORE触发器使用
1. 数据验证触发器
DELIMITER //
CREATE TRIGGER before_order_insert_validate
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
DECLARE user_status INT;
SELECT status INTO user_status
FROM users
WHERE id = NEW.user_id;
IF user_status IS NULL THEN
SIGNAL SQLSTATE ‘45000’
SET MESSAGE_TEXT = ‘用户不存在’;
END IF;
IF user_status = 0 THEN
SIGNAL SQLSTATE ‘45000’
SET MESSAGE_TEXT = ‘用户已被禁用,不能下单’;
END IF;
IF NEW.amount <= 0 THEN
SIGNAL SQLSTATE ‘45000’
SET MESSAGE_TEXT = ‘订单金额必须大于0’;
END IF;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 测试验证触发器
INSERT INTO orders (user_id, amount) VALUES (1, 100.00);
输出示例:
Query OK, 1 row affected (0.01 sec)
3. 测试禁用用户下单
INSERT INTO orders (user_id, amount) VALUES (2, 100.00);
输出示例:
ERROR 1644 (45000): 用户已被禁用,不能下单
4. 数据预处理触发器
DELIMITER //
CREATE TRIGGER before_user_insert_preprocess
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
NEW.user_name = TRIM(NEW.user_name);
NEW.email = LOWER(TRIM(NEW.email));
IF NEW.status IS NULL THEN
SET NEW.status = 1;
END IF;
IF NEW.created_at IS NULL THEN
SET NEW.created_at = NOW();
END IF;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 测试预处理触发器
INSERT INTO users (user_name, email)
VALUES (‘ TestUser ‘, ‘ TEST@EXAMPLE.COM ‘);
输出示例:
Query OK, 1 row affected (0.01 sec)
6. 查看预处理结果
SELECT user_name, email, status, created_at FROM users WHERE user_name = ‘TestUser’;
输出示例:
+———–+——————-+——–+———————+
| user_name | email | status | created_at |
+———–+——————-+——–+———————+
| TestUser | test@fgedu.net.cn | 1 | 2026-04-04 10:30:00 |
+———–+——————-+——–+———————+
1 row in set (0.00 sec)
Part03-生产环境项目实施方案
3.1 AFTER触发器使用
1. 审计日志触发器
DELIMITER //
CREATE TRIGGER after_user_audit
AFTER INSERT ON users
FOR EACH ROW
BEGIN
INSERT INTO user_audit_log (user_id, action, action_time, ip_address, user_agent)
VALUES (NEW.id, ‘CREATE’, NOW(), CONNECTION_ID(), ‘SYSTEM’);
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 测试审计触发器
INSERT INTO users (user_name, email, status, created_at)
VALUES (‘audit_user’, ‘audit@test.com’, 1, NOW());
输出示例:
Query OK, 1 row affected (0.01 sec)
3. 查看审计日志
SELECT * FROM user_audit_log ORDER BY action_time DESC LIMIT 1;
输出示例:
+—-+———+———+———————+————-+————+
| id | user_id | action | action_time | ip_address | user_agent |
+—-+———+———+———————+————-+————+
| 1 | 1502 | CREATE | 2026-04-04 10:35:00 | 123 | SYSTEM |
+—-+———+———+———————+————-+————+
1 row in set (0.00 sec)
4. 级联更新触发器
DELIMITER //
CREATE TRIGGER after_order_status_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
IF OLD.status != NEW.status AND NEW.status = 3 THEN
UPDATE user_statistics
SET completed_orders = completed_orders + 1,
total_amount = total_amount + NEW.amount
WHERE user_id = NEW.user_id;
END IF;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 测试级联更新
UPDATE orders SET status = 3 WHERE id = 1;
输出示例:
Query OK, 1 row affected (0.01 sec)
6. 查看用户统计
SELECT * FROM user_statistics WHERE user_id = 1;
输出示例:
+—-+———+——————+————–+
| id | user_id | completed_orders | total_amount |
+—-+———+——————+————–+
| 1 | 1 | 51 | 5100.00 |
+—-+———+——————+————–+
1 row in set (0.00 sec)
Part04-生产案例与实战讲解
4.1 BEFORE vs AFTER
1. BEFORE触发器特点
– 可以修改数据
– 在约束检查前执行
– 可以阻止操作
– 适合数据验证
2. AFTER触发器特点
– 不能修改数据
– 在约束检查后执行
– 操作已提交
– 适合审计日志
3. 使用场景对比
BEFORE触发器适用场景:
– 数据验证
– 数据预处理
– 自动填充字段
– 业务规则检查
AFTER触发器适用场景:
– 审计日志
– 数据同步
– 统计更新
– 通知发送
Part05-风哥经验总结与分享
5.1 触发器执行顺序
1. 同一表上的触发器
– 按创建时间顺序执行
– 同一类型触发器按创建顺序
– BEFORE触发器在AFTER触发器之前
2. 创建测试触发器
DELIMITER //
CREATE TRIGGER test_order_1
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
INSERT INTO trigger_test (trigger_name, execution_time)
VALUES (‘test_order_1’, NOW());
END //
CREATE TRIGGER test_order_2
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
INSERT INTO trigger_test (trigger_name, execution_time)
VALUES (‘test_order_2’, NOW());
END //
CREATE TRIGGER test_order_3
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
INSERT INTO trigger_test (trigger_name, execution_time)
VALUES (‘test_order_3’, NOW());
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
3. 测试执行顺序
INSERT INTO orders (user_id, amount) VALUES (1, 100.00);
输出示例:
Query OK, 1 row affected (0.01 sec)
4. 查看执行顺序
SELECT trigger_name, execution_time
FROM trigger_test
ORDER BY execution_time;
输出示例:
+—————+———————+
| trigger_name | execution_time |
+—————+———————+
| test_order_1 | 2026-04-04 10:40:00 |
| test_order_2 | 2026-04-04 10:40:00 |
| test_order_3 | 2026-04-04 10:40:00 |
+—————+———————+
3 rows in set (0.00 sec)
6. 最佳实践
6.1 触发时机选择
1. 选择BEFORE时机
– 需要修改数据时
– 需要验证数据时
– 需要阻止操作时
– 需要预处理数据时
2. 选择AFTER时机
– 需要记录日志时
– 需要同步数据时
– 需要更新统计时
– 需要发送通知时
3. 避免的问题
– 避免触发器相互调用
– 避免触发器嵌套过深
– 避免在触发器中执行耗时操作
– 避免触发器逻辑过于复杂
4. 性能考虑
– 触发器会增加操作延迟
– 批量操作时影响更大
– 考虑使用应用层逻辑替代
– 定期评估触发器必要性
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
