触发器(Trigger) 是数据库中一种特殊的存储程序,它会在指定的表上发生特定事件(如 INSERT、UPDATE、DELETE)时自动执行

触发器是数据库中自动执行的存储程序,当关联表发生INSERT、UPDATE或DELETE操作时触发。


本文介绍了触发器的核心特点(自动触发、事件驱动)、语法结构(CREATE TRIGGER语句)以及BEFORE/AFTER两种触发时机的应用场景。


通过一个审计日志示例(在employees_test表插入数据后自动记录到audit表),演示了AFTER INSERT触发器的实现方法,包括使用NEW伪记录获取新数据。


文章还列举了触发器的常见应用场景(数据验证、同步、汇总等)及使用注意事项(性能影响、调试难度等)。


触发器(Trigger)


触发器是数据库中一种特殊的存储程序,它会在指定的表上发生特定事件(如 INSERTUPDATEDELETE)时自动执行


核心特点

特点 说明
自动触发 不需要手动调用,满足条件时自动执行
绑定表 必须关联到某个具体的数据表
事件驱动 INSERTUPDATEDELETE 操作触发
时机可选 可在事件之前(BEFORE) 或**之后(AFTER)**执行

语法结构

sql

复制代码
CREATE TRIGGER 触发器名称
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名
FOR EACH ROW
BEGIN
    -- 要执行的SQL语句
END;

触发时机说明

时机 说明 常见用途
BEFORE 在数据修改之前执行 数据验证、数据清洗、默认值填充
AFTER 在数据修改之后执行 日志记录、数据同步、审计追踪

可访问的伪记录

在触发器内部可以访问特殊的伪记录:

伪记录 说明 可用操作
NEW 操作后的新数据 INSERTUPDATE
OLD 操作前的旧数据 UPDATEDELETE

简单示例

sql

复制代码
-- 创建触发器:在插入员工后自动记录审计日志
CREATE TRIGGER audit_log
AFTER INSERT ON employees_test
FOR EACH ROW
INSERT INTO audit (EMP_no, NAME) 
VALUES (NEW.ID, NEW.NAME);

执行过程:

  1. 用户执行 INSERT INTO employees_test ...

  2. 数据插入成功后,触发器自动audit 表插入记录

  3. 用户无需单独操作 audit

常见应用场景

  • 📝 审计日志:记录谁在什么时间修改了什么数据

  • 🔒 数据验证:在插入/更新前检查数据合法性

  • 🔄 数据同步:主表变化时自动更新关联表

  • 📊 数据汇总:增删改时自动更新统计表

  • 🔗 级联操作:删除主表记录时自动删除子表关联记录

优点与注意事项

优点

  • 自动化业务逻辑,减少应用程序代码

  • 保证数据一致性和完整性

  • 强制实施数据规则

注意事项

  • 过度使用会影响性能

  • 调试相对困难(自动执行,不易追踪)

  • 嵌套触发器可能导致复杂度爆炸

  • 某些在线评测系统可能限制触发器语法


触发器和存储过程对比

对比维度 触发器 (Trigger) 存储过程 (Stored Procedure)
调用方式 自动触发(由DML事件触发) 手动调用(使用CALL命令)
参数 不支持参数 支持输入、输出参数
返回值 不返回值 可返回值或结果集
事务处理 与触发事务绑定 可独立控制
主要场景 审计、数据验证、级联更新 复杂业务逻辑封装
调试难度 较难调试 相对容易调试
性能影响 隐式执行,难以控制 显式调用,可优化

触发器在 MySQL 和 Oracle 中的异同

对比维度 MySQL 触发器 Oracle 触发器
语法结构 FOR EACH ROW 必须,不支持 FOR EACH STATEMENT 支持 FOR EACH ROWFOR EACH STATEMENT
触发时机 BEFORE / AFTER BEFORE / AFTER / INSTEAD OF(视图)
触发器内事务 不能包含事务语句(COMMIT/ROLLBACK) 可以包含事务语句(需谨慎使用)
错误处理 使用 SIGNAL/RESIGNAL 使用 RAISE_APPLICATION_ERROR
新旧数据访问 NEW / OLD(不加冒号) :NEW / :OLD(需加冒号)
行级限制 每个表每个事件最多6个触发器 无明确数量限制
存储过程调用 可调用 可调用

触发器示例


题目描述

构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中。

复制代码
CREATE TABLE employees_test(
   ID INT PRIMARY KEY NOT NULL,
   NAME TEXT NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR(50),
   SALARY REAL
);
CREATE TABLE audit(
   EMP_no INT NOT NULL,
   NAME TEXT NOT NULL
);

后台会往employees_test插入一条数据:

复制代码
INSERT INTO employees_test (ID,NAME,AGE,ADDRESS,SALARY)VALUES (1, 'Paul', 32, 'California', 20000.00 );

然后从audit里面使用查询语句:

复制代码
select * from audit;

按照题目要求,构造一个 INSERT 触发器 audit_log,实现在 employees_test 插入数据后,把对应的 IDNAME 写入 audit 表中。


sql

复制代码
DROP TRIGGER IF EXISTS audit_log;

DELIMITER $$

CREATE TRIGGER audit_log
AFTER INSERT ON employees_test
FOR EACH ROW
BEGIN
    INSERT INTO audit (EMP_no, NAME)
    VALUES (NEW.ID, NEW.NAME);
END $$

DELIMITER ;

说明:

  1. 触发器名称audit_log

  2. 触发时间AFTER INSERT --- 在插入操作完成后触发

  3. 触发事件 :在 employees_test 表上执行 INSERT 时触发

  4. 操作 :使用 NEW.IDNEW.NAME 获取刚刚插入的新数据,并插入到 audit 表中

  5. 字段对应

    • audit.EMP_noemployees_test.ID

    • audit.NAMEemployees_test.NAME

测试过程:

sql

复制代码
-- 清空数据(方便重复测试)
DELETE FROM audit;
DELETE FROM employees_test;

-- 插入员工数据
INSERT INTO employees_test (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00);

-- 查询 audit 表
SELECT * FROM audit;

输出结果:

text

复制代码
1|Paul
相关推荐
唐青枫1 小时前
别再误会 SELECT 1:MySQL 常量查询与存在性判断实战
sql·mysql
野生技术架构师1 小时前
MySQL / PostgreSQL DDL 审核自动化:从人工 review 到 CI 拦截
mysql·postgresql·自动化
24白菜头1 小时前
MySQL学习笔记
数据库·笔记·学习·mysql
shizhan_cloud2 小时前
MySQL 备份与恢复
数据库·mysql
思麟呀2 小时前
MySQL的内置函数
数据库·mysql
熏鱼的小迷弟Liu2 小时前
【MySQL】MySQL中的MVCC是什么?它与隔离级别有什么关系?
mysql·mvcc
NineData2 小时前
还在轮询 MySQL 吗?用 NineData 把业务变更直接送进 Kafka
数据库·mysql·kafka·ninedata·数据复制·玖章算术·数据迁移工具
重生之小比特3 小时前
【MySQL 数据库】索引特性
数据库·mysql
Andya_net3 小时前
MySQL | DBeaver Mac版下载、安装与使用指南
数据库·mysql·macos