当前位置: 首页 > news >正文

MySQL—触发器详解

基本介绍

触发器是与表有关的数据库对象,在 INSERT、UPDATE、DELETE 操作之前或之后触发并执行触发器中定义的 SQL 语句。

触发器的这种特性可以协助应用在数据库端确保数据的完整性、日志记录、数据校验等操作。

使用别名 NEW 和 OLD 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。

现在触发器还只支持行级触发,不支持语句级触发。

触发器类型OLD的含义NEW的含义
INSERT 型触发器无 (因为插入前状态无数据)NEW 表示将要或者已经新增的数据
UPDATE 型触发器OLD 表示修改之前的数据NEW 表示将要或已经修改后的数据
DELETE 型触发器OLD 表示将要或者已经删除的数据无 (因为删除后状态无数据)

基本操作

创建触发器

DELIMITER $CREATE TRIGGER 触发器名称
BEFORE|AFTER  INSERT|UPDATE|DELETE
ON 表名
FOR EACH ROW  -- 行级触发器
BEGIN触发器要执行的功能;
END$DELIMITER ;

查看触发器的状态、语法等信息

SHOW TRIGGERS;

 删除触发器,如果没有指定 schema_name,默认为当前数据库

DROP TRIGGER [schema_name.]trigger_name;

注意事项

  • 确保触发器中的逻辑不影响性能,尤其是在高频操作的表上。
  • 避免在触发器中出现无限循环的情况,例如更新触发器又触发了同一操作。

代码示例

通过触发器记录账户表的数据变更日志。包含:增加、修改、删除。

数据准备

CREATE TABLE accounts
(id         INT AUTO_INCREMENT PRIMARY KEY,                                 -- 账户IDusername   VARCHAR(50)  NOT NULL UNIQUE,                                   -- 用户名,必须唯一password   VARCHAR(255) NOT NULL,                                          -- 密码,建议加密存储email      VARCHAR(100) NOT NULL UNIQUE,                                   -- 邮箱,必须唯一created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,                            -- 创建时间,默认当前时间updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间,自动更新
);
CREATE TABLE account_change_log
(log_id         INT AUTO_INCREMENT PRIMARY KEY,      -- 日志IDaccount_id     INT,                                 -- 被更改的账户IDoperation_type VARCHAR(10),                         -- 操作类型:INSERT, UPDATE, DELETEold_value      VARCHAR(255),                        -- 更新前的值new_value      VARCHAR(255),                        -- 更新后的值changed_at     TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 变更时间,默认当前时间FOREIGN KEY (account_id) REFERENCES accounts (id)   -- 外键约束,引用账户表
);
# 创建 INSERT 型触发器
-- 更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表插入数据后触发
CREATE TRIGGER after_account_insertAFTER INSERTON accountsFOR EACH ROW
BEGIN-- 将插入操作记录到account_change_log表中INSERT INTO account_change_log (account_id, operation_type, new_value)VALUES (NEW.id, 'INSERT', NEW.username); -- 记录新增账户的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;# 创建 UPDATE 型触发器
-- 再次更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表更新数据后触发
CREATE TRIGGER after_account_updateAFTER UPDATEON accountsFOR EACH ROW
BEGIN-- 将更新操作记录到account_change_log表中INSERT INTO account_change_log (account_id, operation_type, old_value, new_value)VALUES (OLD.id, 'UPDATE', OLD.username, NEW.username); -- 记录更新前后的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;-- 创建 DELETE 型触发器
-- 再次更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表删除数据后触发
CREATE TRIGGER after_account_deleteAFTER DELETEON accountsFOR EACH ROW
BEGIN-- 将删除操作记录到account_change_log表中INSERT INTO account_change_log (account_id, operation_type, old_value)VALUES (OLD.id, 'DELETE', OLD.username); -- 记录删除账户的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;
# 插入测试:执行上述插入操作后,可以查看 account_change_log 表,确认新用户的插入记录是否正确。
INSERT INTO accounts (username, password, email) VALUES
('user1', 'password1', 'user1@example.com'),
('user2', 'password2', 'user2@example.com'),
('user3', 'password3', 'user3@example.com');

# 更新测试:更新某个用户的信息,查看 account_change_log 表,确认更新的记录是否正确。
UPDATE accounts SET username = 'updated_user1' WHERE id = 1;

 

# 删除测试:删除某个用户,查看 account_change_log 表,确认删除的记录是否正确。
DELETE FROM accounts WHERE id = 2;

 参考资料

  • MySQL 官方文档 - 触发器

相关文章:

  • rabbitMQ 简单使用
  • 9.29总结
  • Sqlserver 死锁指南
  • mysql事务详解
  • hive-拉链表
  • 【源码+文档+调试讲解】无人超市系统python
  • 安卓 shape 的使用
  • 【记录】Excel|不允许的操作:合并或隐藏单元格出现的问题列表及解决方案
  • MySQL InnoDB MVCC数据结构分析
  • smb文件夹共享设置
  • Linux学习之路 -- 线程 -- 条件变量与生产消费模型
  • 【含文档】基于Springboot+微信小程序 的高校二手商品交易平台(含源码+数据库+lw)
  • 物联网系统中OLED屏主流驱动方案详解
  • 构建高效房屋租赁系统:Spring Boot应用
  • Springboot中基于注解实现公共字段自动填充
  • JS 中的深拷贝与浅拷贝
  • CSS 提示工具(Tooltip)
  • Java 内存分配及垃圾回收机制初探
  • JavaScript 奇技淫巧
  • JavaScript类型识别
  • MySQL用户中的%到底包不包括localhost?
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • STAR法则
  • uni-app项目数字滚动
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • Vue实战(四)登录/注册页的实现
  • 阿里云应用高可用服务公测发布
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 前端js -- this指向总结。
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 使用API自动生成工具优化前端工作流
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 提醒我喝水chrome插件开发指南
  • 网页视频流m3u8/ts视频下载
  • 微信小程序开发问题汇总
  • 延迟脚本的方式
  • 走向全栈之MongoDB的使用
  • # Redis 入门到精通(七)-- redis 删除策略
  • #QT(智能家居界面-界面切换)
  • $.ajax()
  • (C++)八皇后问题
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (备份) esp32 GPIO
  • (二)PySpark3:SparkSQL编程
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (每日一问)基础知识:堆与栈的区别
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • *算法训练(leetcode)第三十九天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .net core 6 集成和使用 mongodb