【Mysql知识】从零开始开发一个mysql触发器

文章目录

      • **MySQL 触发器开发说明**
      • **1. 触发器的基本概念**
        • **(1) 触发时机**
        • **(2) 触发事件**
        • **(3) 触发对象**
      • **2. 触发器的语法**
        • **关键点说明**
      • **3. 触发器中的特殊变量**
      • **4. 触发器的开发示例**
        • **(1) 插入触发器**
        • **(2) 更新触发器**
        • **(3) 删除触发器**
      • **5. 触发器的管理**
        • **(1) 查看触发器**
        • **(2) 删除触发器**
        • **(3) 修改触发器**
      • **6. 触发器的应用场景**
        • **(1) 数据验证**
        • **(2) 审计日志**
        • **(3) 自动化任务**
      • **7. 注意事项**
        • **(1) 性能影响**
        • **(2) 递归触发**
        • **(3) 错误处理**
        • **(4) 权限要求**
      • **8. 示例:完整的触发器开发流程**
        • **(1) 创建表结构**
        • **(2) 创建触发器**
        • **(3) 测试触发器**

MySQL 触发器开发说明

触发器(Trigger)是 MySQL 中一种特殊的存储程序,它会在指定的表上发生特定事件(如 INSERTUPDATEDELETE)时自动执行。触发器可以用于数据验证、审计日志记录、复杂业务逻辑处理等场景。

1. 触发器的基本概念

(1) 触发时机

触发器可以在以下两种时机执行:

  • BEFORE:在触发事件(如插入、更新或删除)发生之前执行。
  • AFTER:在触发事件完成之后执行。
(2) 触发事件

触发器可以响应以下三种事件:

  • INSERT:当新记录插入到表中时触发。
  • UPDATE:当表中的记录被更新时触发。
  • DELETE:当表中的记录被删除时触发。
(3) 触发对象

触发器只能定义在表上,并且每个触发器只能针对一个表。

2. 触发器的语法

创建触发器的语法如下:

CREATE TRIGGER trigger_name
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON table_name
FOR EACH ROW
BEGIN
    -- 触发器逻辑代码
END;
关键点说明
  • trigger_name:触发器的名称,必须唯一。
  • { BEFORE | AFTER }:指定触发时机。
  • { INSERT | UPDATE | DELETE }:指定触发事件。
  • table_name:触发器关联的表。
  • FOR EACH ROW:表示触发器会对每一行受影响的数据执行一次。
  • BEGIN ... END:触发器的逻辑代码块。

3. 触发器中的特殊变量

在触发器中,可以通过以下两个特殊变量访问当前操作的行数据:

  • NEW:表示即将插入或更新的新行数据(仅适用于 INSERTUPDATE 事件)。
  • OLD:表示即将被更新或删除的旧行数据(仅适用于 UPDATEDELETE 事件)。

示例:

  • INSERT 触发器中,NEW.column_name 表示新插入的列值。
  • UPDATE 触发器中,OLD.column_name 表示更新前的列值,NEW.column_name 表示更新后的列值。
  • DELETE 触发器中,OLD.column_name 表示被删除的列值。

4. 触发器的开发示例

(1) 插入触发器

在插入新记录时,自动为某列生成默认值:

DELIMITER $$

CREATE TRIGGER before_insert_example
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
    IF NEW.salary IS NULL THEN
        SET NEW.salary = 5000; -- 如果 salary 为空,则设置默认值为 5000
    END IF;
END$$

DELIMITER ;
(2) 更新触发器

在更新记录时,记录变更日志:

DELIMITER $$

CREATE TRIGGER after_update_example
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
    INSERT INTO employee_logs (employee_id, old_salary, new_salary, updated_at)
    VALUES (OLD.id, OLD.salary, NEW.salary, NOW());
END$$

DELIMITER ;
(3) 删除触发器

在删除记录时,将数据备份到另一个表中:

DELIMITER $$

CREATE TRIGGER before_delete_example
BEFORE DELETE ON employees
FOR EACH ROW
BEGIN
    INSERT INTO employees_backup (id, name, salary, deleted_at)
    VALUES (OLD.id, OLD.name, OLD.salary, NOW());
END$$

DELIMITER ;

5. 触发器的管理

(1) 查看触发器

查看某个数据库中的所有触发器:

SHOW TRIGGERS \G
(2) 删除触发器

删除指定的触发器:

DROP TRIGGER trigger_name;
(3) 修改触发器

MySQL 不支持直接修改触发器,需要先删除再重新创建:

DROP TRIGGER trigger_name;

-- 然后重新创建触发器
CREATE TRIGGER trigger_name ...

6. 触发器的应用场景

(1) 数据验证

在插入或更新数据时,确保数据符合某些规则。例如:

  • 验证字段值是否在合理范围内。
  • 检查外键约束。
(2) 审计日志

记录对表的操作历史,便于后续审计。例如:

  • 记录谁在何时修改了哪些数据。
  • 记录删除的数据以备恢复。
(3) 自动化任务

在某些操作发生时,自动执行相关任务。例如:

  • 自动生成主键值。
  • 同步更新其他表的数据。

7. 注意事项

(1) 性能影响
  • 触发器会增加数据库操作的开销,尤其是在高并发场景下。
  • 尽量避免在触发器中执行复杂的逻辑或耗时操作。
(2) 递归触发
  • MySQL 默认不允许触发器递归调用(即触发器不能再次触发自身)。
  • 如果需要递归触发,可以通过设置系统变量 log_slow_filter 来控制。
(3) 错误处理
  • 如果触发器中的代码抛出错误,整个事务可能会回滚。
  • 可以通过 DECLARE CONTINUE HANDLER 捕获异常并继续执行。
(4) 权限要求
  • 创建触发器需要 TRIGGER 权限。
  • 触发器中使用的表需要相应的操作权限。

8. 示例:完整的触发器开发流程

假设有一个 orders 表和一个 order_logs 表,我们希望在每次更新订单状态时记录日志。

(1) 创建表结构
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_status VARCHAR(50),
    amount DECIMAL(10, 2)
);

CREATE TABLE order_logs (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT,
    old_status VARCHAR(50),
    new_status VARCHAR(50),
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
(2) 创建触发器
DELIMITER $$

CREATE TRIGGER after_order_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
    IF OLD.order_status != NEW.order_status THEN
        INSERT INTO order_logs (order_id, old_status, new_status, updated_at)
        VALUES (OLD.id, OLD.order_status, NEW.order_status, NOW());
    END IF;
END$$

DELIMITER ;
(3) 测试触发器
-- 插入一条订单记录
INSERT INTO orders (order_status, amount) VALUES ('Pending', 100.00);

-- 更新订单状态
UPDATE orders SET order_status = 'Shipped' WHERE id = 1;

-- 查看日志表
SELECT * FROM order_logs;

通过以上步骤,你可以熟练掌握 MySQL 触发器的开发与使用。如果有任何问题或需要进一步优化,请随时提问!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/977464.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计SpringBoot+Vue.js墙绘产品展示交易平台(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

springboot005学生心理咨询评估系统(源码+数据库+文档)

源码地址:学生心理咨询评估系统 文章目录 1.项目简介2.部分数据库结构与测试用例3.系统功能结构4.包含的文件列表(含论文)后台运行截图 1.项目简介 ​ 使用旧方法对学生心理咨询评估信息进行系统化管理已经不再让人们信赖了,把现…

Linux红帽:RHCSA认证知识讲解(二)配置网络与登录本地远程Linux主机

Linux红帽:RHCSA认证知识讲解(二)配置网络与登录本地远程Linux主机 前言一、使用命令行(nmcli 命令)配置网络,配置主机名第一步第二步修改主机名称 二、使用图形化界面(nmtui 命令)配…

【运维】内网服务器借助通过某台可上外网的服务器实现公网访问

背景: 内网服务器无法连接公网,但是办公电脑可以连接内网服务器又可以连接公网。 安装软件 1、frp 2、ccproxy 配置 1、内网服务器 # 内网服务器启动frp服务配置文件参考vi frps.ini# frps.ini [common] bind_port 7000# 备注: bind_port端口可以随意配置。配置完…

Pytorch实现论文:基于多尺度融合生成对抗网络的水下图像增强

简介 简介:提出了一种新型的水下图像增强算法,基于多尺度融合生成对抗网络,名为UMSGAN,以解决低对比度和颜色失真的问题。首先经过亮度的处理,将处理后的图像输入设计的MFFEM模块和RM模块生成图像。该算法旨在适应各种水下场景,提供颜色校正和细节增强。 论文题目:Und…

基于 DeepSeek LLM 本地知识库搭建开源方案(AnythingLLM、Cherry、Ragflow、Dify)认知

写在前面 博文内容涉及 基于 Deepseek LLM 的本地知识库搭建使用 ollama 部署 Deepseek-R1 LLM知识库能力通过 Ragflow、Dify 、AnythingLLM、Cherry 提供理解不足小伙伴帮忙指正 😃,生活加油 我站在人潮中央,思考这日日重复的生活。我突然想&#xff0c…

ShenNiusModularity项目源码学习(12:ShenNius.Common项目分析)

ShenNius.Common项目中主要定义功能性的辅助函数类及通用类,供MVC模式、前后端分离模式下的后台服务使用,以提高编程效率。   ApiResult文件内的ApiResult和ApiResult类定义了通用的数据返回格式,包括状态码、返回消息、返回数据等&#x…

【Python量化金融实战】-第1章:Python量化金融概述:1.1量化金融的定义与发展历程

本小节学习建议:掌握Python编程、统计学(时间序列分析)、金融学基础(资产定价理论)三者结合,是进入量化领域的核心路径。 👉 点击关注不迷路 👉 点击关注不迷路 文章目录 1.1 量化金…

STM32的HAL库开发---单通道ADC采集(DMA读取)实验

一、实验简介 正常单通道ADC采集顺序是先开启ADC采集,然后等待ADC转换完成,也就是判断EOC位置1,然后再读取数据寄存器的值。 如果配置了DMA功能,在EOC位被硬件置1后,自动产生DMA请求,然后DMA进行数据搬运…

eclogy后台运维笔记(写的很乱,只限个人观看)

组织权限: 矩阵管理 这个很重要,比如进行流程操作者的选择时,我们进行需要选择财务部的出纳,会计,总经理。我们不能去直接选定一个人,万一这个人离职了,那所有的流程都要手动修改,…

【网络编程】几个常用命令:ping / netstat / xargs / pidof / watch

ping:检测网络联通 1. ping 的基本功能2. ping 的工作原理3. ping 的常见用法4. ping 的输出解释5. ping 的应用场景6. 注意事项 netstat:查看网络状态 1. netstat 的基本功能2. 常见用法3. 示例4. 输出字段解释5. netstat 的替代工具6. 注意事项 xargs&…

自定义Spring Boot Starter(官网文档解读)

摘要 本文将详细介绍自定义 Spring Boot Starter 的完整过程。要构建自定义 Starter,首先需掌握 Spring Boot 中 Auto-configuration 以及相关注解的工作原理,同时了解 Spring Boot 提供的一系列条件注解。在具备这些知识基础后,再按照特定步…

C++和OpenGL实现3D游戏编程【连载23】——几何着色器和法线可视化

欢迎来到zhooyu的C++和OpenGL游戏专栏,专栏连载的所有精彩内容目录详见下边链接: 🔥C++和OpenGL实现3D游戏编程【总览】 1、本节实现的内容 上一节课,我们在Blend软件中导出经纬球模型时,遇到了经纬球法线导致我们在游戏中模型光照显示问题,我们在Blender软件中可以通过…

我的技术十年

前言 十年一瞬,2014 年毕业至今,刚好十年。《异类》一书曾提到“一万小时定律”,要成为某个领域的专家,需要 10000 小时,按比例计算就是:如果你每天工作八小时,一周工作五天,那么成…

kotlin 知识点一 变量和函数

在Kotlin中定义变量的方式和Java 区别很大,在Java 中如果想要定义一个变 量,需要在变量前面声明这个变量的类型,比如说int a表示a是一个整型变量,String b表 示b是一个字符串变量。而Kotlin中定义一个变量,只允许在变量…

链表-基础训练(二)链表 day14

两两交换链表中的节点 题目示意: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 原先我的思路是图像上的思路,但是我感觉还是很复杂…

智能交通系统(Intelligent Transportation Systems):智慧城市中的交通革新

智能交通系统(Intelligent Transportation Systems, ITS)是利用先进的信息技术、通信技术、传感技术、计算机技术以及自动化技术等,来提升交通系统效率和安全性的一种交通管理方式。ITS通过收集和分析交通数据,智能化地调度、控制…

数据结构:Map set - 习题(三)

一、只出现一次的数字 题目链接https://leetcode.cn/problems/single-number/description/ 描述: 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性…

【射频仿真学习笔记】Cadence的Layout EXL与ADS dynamic link联动后仿

一、EXL仿真 1. 绘制教程 当我们使用EMX仿真提取的时候,会遇到各种各样的问题,很不方便。这里我们介绍一种新的方法——EXL。可以更灵活的跑仿真。我们以带有中和电容的差分电路为例进行介绍 在使用EMX的是偶,port是连不到晶体管外围金属上…

C++——list模拟实现

目录 前言 一、list的结构 二、默认成员函数 构造函数 析构函数 clear 拷贝构造 赋值重载 swap 三、容量相关 empty size 四、数据访问 front/back 五、普通迭代器 begin/end 六、const迭代器 begin/end 七、插入数据 insert push_back push_front 八、…