SQL触发器是数据库系统中与表关联的特殊对象,当表上发生指定的数据操作事件时,触发器会自动执行预设的逻辑,不需要手动调用,能有效减少重复的业务逻辑代码,提升数据处理的自动化程度。

SQL触发器的核心概念
SQL触发器基于事件驱动,常见的触发事件包括INSERT、UPDATE、DELETE三种,按照触发时机可以分为事件执行前触发(BEFORE)和事件执行后触发(AFTER)。不同数据库对触发器的支持略有差异,但核心逻辑一致。
触发器的基本语法结构
以MySQL为例,创建触发器的基础语法如下:
-- 创建触发器语法
CREATE TRIGGER 触发器名称
触发时机 触发事件 ON 表名
FOR EACH ROW
BEGIN
-- 触发器执行的逻辑
END;
SQL触发器的常见应用场景
1. 数据完整性校验
当插入或更新数据时,可以通过触发器校验数据是否符合业务规则,避免非法数据进入数据库。比如用户表的年龄字段不能小于0,也不能大于150。
-- 创建用户表年龄校验触发器
CREATE TRIGGER check_user_age
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
-- 如果插入的年龄不符合规则,抛出错误
IF NEW.age < 0 OR NEW.age > 150 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '年龄必须在0到150之间';
END IF;
END;
2. 操作日志记录
很多业务需要记录表的数据变更历史,比如订单表的修改记录、用户信息的更新记录,使用触发器可以自动将变更信息写入日志表,不需要在业务代码中手动插入日志。
首先创建操作日志表:
-- 创建操作日志表
CREATE TABLE user_operate_log (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
operate_type VARCHAR(20),
old_data TEXT,
new_data TEXT,
operate_time DATETIME
);
再创建更新用户表时的日志触发器:
-- 创建用户更新日志触发器
CREATE TRIGGER log_user_update
AFTER UPDATE ON user
FOR EACH ROW
BEGIN
INSERT INTO user_operate_log (user_id, operate_type, old_data, new_data, operate_time)
VALUES (OLD.id, 'UPDATE', CONCAT('姓名:', OLD.name, ',年龄:', OLD.age), CONCAT('姓名:', NEW.name, ',年龄:', NEW.age), NOW());
END;
3. 数据同步
当主表数据发生变更时,需要同步更新关联表的统计信息,比如订单表新增订单后,自动更新用户表的订单总数。假设用户表有order_count字段记录订单数量:
-- 创建订单插入后同步更新用户订单数的触发器
CREATE TRIGGER sync_user_order_count
AFTER INSERT ON order_table
FOR EACH ROW
BEGIN
UPDATE user SET order_count = order_count + 1 WHERE id = NEW.user_id;
END;
4. 自动填充字段
部分字段不需要手动插入,比如创建时间、更新时间,可以通过触发器自动填充。比如用户表插入数据时自动填充create_time字段:
-- 创建自动填充创建时间的触发器
CREATE TRIGGER fill_create_time
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
SET NEW.create_time = NOW();
END;
使用SQL触发器的注意事项
- 触发器是隐式执行的,过度使用会导致业务逻辑分散,后期维护困难,建议只用在通用性强、和业务耦合度低的场景。
- 触发器中的逻辑如果执行时间过长,会阻塞对应的数据操作,影响数据库性能,尽量避免在触发器中写复杂的查询或计算逻辑。
- 不同数据库的触发器语法存在差异,迁移数据库时需要同步调整触发器的代码。
- 触发器的错误会导致对应的数据操作失败,编写触发器时需要考虑异常处理逻辑。
触发器与存储过程的区别
很多开发者会混淆触发器和存储过程,二者核心区别如下:
| 对比项 | SQL触发器 | 存储过程 |
|---|---|---|
| 调用方式 | 事件触发,自动执行 | 手动调用 |
| 参数支持 | 不支持自定义参数 | 支持输入、输出参数 |
| 返回值 | 没有返回值 | 可以有返回值 |
| 适用场景 | 数据操作关联的自动逻辑 | 复杂的业务处理逻辑 |