MySQL触发器的使用

news2024/11/25 13:48:14

目录

  • 一、前言
  • 二、触发器分类
    • 1.插入触发器
    • 2.更新触发器
    • 3.删除触发器
  • 三、查看触发器
  • 四、异常处理
  • 五、小结

一、前言

     各种主流数据库,都集成了触发器的功能。触发器提供了一种机制,允许开发者在对数据库表的插入、更新、删除的前后捕获相应的数据行。从而针对数据行实现特定的逻辑。结合具体的例子来看,比如有多个应用系统都对数据库某张表进行了插入操作,现在需要对该表的某个字段进行修改。我们可以怎么做呢,如果是倾向于在应用系统中改变逻辑从而实现目标,那么我们就需要同时修改两套应用系统;而如果是倾向于使数据库的话我们只需要针对这个表的相应触发器进行操作即可。显然两者都能达到目的,但是实际的应用场景并不总是如我们所愿。比如应用系统是用c#开发的但是不擅长c#的话就不好轻易的去改动代码,这个时候刚好会数据库,那么触发器就可以派上用场了。还有一点就是我们不知道某个表会被哪些哪些应用系统操作的时候,我们也可以使用触发器来解决问题。总而言之,触发器守住了数据的入口,在某种程度上也提供了一定的便利。
     **触发器类似于事件,创建触发器就是注册事件回调过程的过程**。我们知道,一般事件是被动触发的,而且事件可以形成事件链,触发器也是如此。对于事件一般我们是通过"注册回调函数"这种方式来完成,触发器也是一种"回调函数",只不过这种"回调函数"使用的是数据库支持的语法。一般回调函数都会传入 上下文的变量,我们知道在触发器里有old和new变量,这两个变量就是上下文变量,用来指代更新前后的数据行。

二、触发器分类

    触发器分为插入触发器、更新触发器、删除触发器。这三个触发器都有前置和后置两个动作,也就是插入之前/之后,更新之前/之后,删除之前/之后,对应语法就是BEFORE 和AFTER。
    下面通过mysql触发器的示例来介绍它的使用方法。首先我们创建一张测试表,后面的插入触发器、更新触发器和删除触发器都围绕这张表来说明。
DROP TABLE app_user;
CREATE TABLE app_user(id int primary key AUTO_INCREMENT,username varchar(32),pwd varchar(32));

1.插入触发器

以下代码为表app_user创建了一个前置插入触发器,该触发器的作用将插入到app_user表的数据同步到app_user2表,app_user2表与app_user表具有相同的表结构

CREATE TABLE IF NOT EXISTS app_user2 like app_user;
DROP TRIGGER IF EXISTS trigger_before_insert_app_user;
CREATE TRIGGER trigger_before_insert_app_user BEFORE INSERT ON app_user FOR EACH ROW BEGIN
	insert into app_user2(`id`,`username`,`pwd`) values(new.`id`,new.`username`,new.`pwd`);
END;

使用INSERT INTO往app_user表插入一条数据后之后查看两表数据,可以看到app_user表数据行插入到了app_user2
在这里插入图片描述

2.更新触发器

以下代码为app_user表创建了一个前置更新触发器,该触发器的作用在更新app_user表的同时将app_user2表的记录同步更新

DROP TRIGGER IF EXISTS trigger_before_update_app_user;
CREATE TRIGGER trigger_before_update_app_user BEFORE UPDATE ON app_user FOR EACH ROW BEGIN
	UPDATE app_user2 set 
		`id` = new.`id`,
		`username` = new.`username`,
		`pwd` = new.`pwd`
 	WHERE id=old.id;
END;

**使用UPDATE语句更新app_user表中id=‘1’的记录中字段username值由’test’更新为’test1’ **
可以看到app_user2表记录数据得到了同步更新
在这里插入图片描述
字段username更新前的值是’test’,更新后变成了’test1’,更新之前的值可以通过old变量访问,更新之后的值通过new变量访问,
可以通过微调触发器代码来查看数据,将old和new变量中的username字段进行了拼接并更新到username字段
在这里插入图片描述

然后重新创建更新触发器

DROP TRIGGER IF EXISTS trigger_before_update_app_user;
CREATE TRIGGER trigger_before_update_app_user BEFORE UPDATE ON app_user FOR EACH ROW BEGIN
	UPDATE app_user2 set 
		`id` = new.`id`,
		`username` = concat('old.username:',old.username,' new.username:',new.`username`),
		`pwd` = new.`pwd`
 	WHERE id=old.id;
END;

执行UPDATE语句后可以对比查看old.username和new.username变量的值
在这里插入图片描述

3.删除触发器

以下代码为app_user表创建了一个前置删除触发器,删除app_user表记录的同时同步删除app_user2表记录

DROP TRIGGER IF EXISTS trigger_before_delete_app_user;
CREATE TRIGGER trigger_before_delete_app_user BEFORE DELETE ON app_user FOR EACH ROW BEGIN
	DELETE FROM app_user2 WHERE id=old.id;
END;

在这里插入图片描述

三、查看触发器

使用show triggers命令查看所有触发器
在这里插入图片描述
也可以指定关键字进行模糊查询
在这里插入图片描述

四、异常处理

触发器作为一种特定的"回调函数",它在执行的过程中也会抛出异常。一般编程语言中都有类似的try catch finally来进行异常捕获,
当然mysql也有对应的异常处理机制
出错继续

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @x = 0;

出错退出

DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @x = 0;

代码段中 SET @x = 0 是出错时的处理程序,这样判断程序是否出错就可以根据x变量的值来判断
我们知道 往主键唯一的表插入重复记录会抛出异常

app_user表 “前置插入触发器” 当前逻辑为

DROP TRIGGER IF EXISTS trigger_before_insert_app_user;
CREATE TRIGGER trigger_before_insert_app_user BEFORE INSERT ON app_user FOR EACH ROW BEGIN
	insert into app_user2(`id`,`username`,`pwd`) values(new.`id`,new.`username`,new.`pwd`);
END;

app_user表和app_user2表的数据分别为
在这里插入图片描述

在不改动逻辑的情况下,插入重复记录的时候,会出现报错
在这里插入图片描述
修改触发器模拟报错场景,比如将insert语句中的id写死为1 ,这样无论往app_user表中插入任何数据都会引发报错
在这里插入图片描述
在这里插入图片描述
那么如何使语句 INSERT INTO app_user(id,username,pwd) values(2,‘test’,‘123’); 成功执行呢
可以修改触发器如下

DROP TRIGGER IF EXISTS trigger_before_insert_app_user;
CREATE TRIGGER trigger_before_insert_app_user BEFORE INSERT ON app_user FOR EACH ROW BEGIN
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @x = 0;
	insert into app_user2(`id`,`username`,`pwd`) values(1,new.`username`,new.`pwd`);
END;

在这里插入图片描述

在这里插入图片描述
可以看到app_user表有2条记录,app_user表只有1条记录

五、小结

1.使用触发器可以实现表数据的同步,可以用来实现增量数据同步。
2.不管数据是否插入、更新、删除成功,前置触发器都会首先被调用。
3.触发器中有异常也是能够被捕获的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DebugView的使用

目录 一、前言二、本机调试1.DebugView程序文件说明2.OutputDebugString函数使用3.示例程序4.远程调试 三、问题与注意事项四、小结 一、前言 DebugView是windows下的一款调试工具,可以捕获程序输出的日志,分为64位和32位,支持应用层和内核层的日志捕获,利用它排除bug是个不错的…

chatgpt赋能python:Python开发手机软件的优势和挑战

Python开发手机软件的优势和挑战 随着智能手机的普及,移动应用开发已成为当前最热门的技术领域之一。随着越来越多的企业意识到移动应用的重要性,越来越多的开发者开始加入这个领域。 在移动应用的开发中,由于其高效性和易于学习的特点&…

【Flutter】Dart/Flutter SDK如何降低版本、回退到指定版本

因为dart3.0以后不再支持 no-sound-null-safety;但是有些项目不得以切换到dart3.0以前继续使用运行项目 方法1: 通过 $ flutter downgrade命令,将flutter降级为当前通道的上一个活动版本; 如果没有存在老版本则会提示 flutter …

从零手写操作系统之RVOS软件定时器实现-08

从零手写操作系统之RVOS软件定时器实现-08 定时器分类软件定时器的分类软件定时器设计与实现软件定时器调用流程增加对周期性定时任务支持测试优化点 本系列参考: 学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春 整理而来,主要作为xv6操作系统学习的一个前置基础。…

chatgpt赋能python:Python强制等待:如何优化你的Python技能

Python强制等待:如何优化你的Python技能 在Python编程中,强制等待是一种非常重要的程序设计方式。Python代码中的强制等待通常使用time.sleep()方法实现。在本文中,我们将详细介绍什么是Python强制等待,以及如何使用它来优化你的…

基于最近电平逼近的开环MMC逆变器MATLAB仿真模型

资源地址: 模型介绍: MATLAB21b版本 DC:12kV,N=12, 采用最近电平逼近调制,采用基于排序的均压方法,冒泡排序+桥臂电流方向判断。 连接负载,可以得到13电平相电压波形。…

Windows10下使用VS2019编译chromium

Windows10下使用VS2019编译chromium 工具设置代理cmd运行gclient配置VS的版本,环境变量设置下载源码生成编译工具 下载depot_tools,并配置环境变量,PATH下添加depot_tools的解压路径E:\src\depot_tools 设置代理 控制台管理员权限执行 git config --global http.proxy…

CenoOS连接 SQL Server

目录 1、问题:2、解决步骤3、拓展3.1 常用查询3.2 SQL Server 语句规则3.3 python调用 1、问题: 连接:ProviderSQLOLEDB.1;Persist Security InfoFalse;User IDXXX;passwordXXXXX;Initial CatalogXXXXX;Data SourceXXXXX; 解析:…

chatgpt赋能python:Python屏幕截图:完美的方法记录你的屏幕

Python屏幕截图:完美的方法记录你的屏幕 Python作为一种高级编程语言,被广泛用于开发各种应用程序和游戏,其中之一就是屏幕截图。 在本文中,我们将介绍使用Python进行屏幕截图的方法和技巧。 什么是屏幕截图? 屏幕截…

第六十八天学习记录:高等数学:导数(宋浩板书)

导数是微积分中的一个概念,描述了函数在某一个点上的变化率。具体地说,函数 f ( x ) f(x) f(x)在 x a xa xa处的导数为 f ′ ( a ) f(a) f′(a),表示当 x x x在 a a a处发生微小的变化 Δ x \Delta x Δx时, f ( x ) f(x) f(x)对…

Golang每日一练(leetDay0090) 运算优先级、有效字母异位词

目录 241. 为运算表达式设计优先级 Different Ways to Add Parentheses 🌟🌟 242. 有效的字母异位词 Valid Anagram 🌟 🌟 每日一练刷题专栏 🌟 Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 …

Vector源码

介绍 Vector是矢量队列,继承于AbstractList,实现了List, RandomAccess, Cloneable和Serializable接口Vector继承了AbstractList,实现了List接口,所以它是一个队列,支持相关的添加、删除、修改、遍历等功能Vector实现了…

chatgpt赋能python:Python的强制语句缩进解析

Python的强制语句缩进解析 什么是语句缩进 在其他编程语言中,我们通过使用花括号或者一些其他的符号来区分控制语句的范围。但在Python中,我们使用缩进来实现这个目的。这意味着任何控制结构的主体都必须按照要求正确缩进。 为什么Python强制要求使用…

【Java】JavaWEB核心要点总结:63

文章目录 1. JSP 和 Servlet 有什么区别2. JSP有哪些内置对象 分别是什么3. 详细讲解cookie session token4. 如果客户端禁止 了cookie ,session 还能用吗5. session 的工作原理 1. JSP 和 Servlet 有什么区别 JSP(Java Server Pages)和Servl…

读改变未来的九大算法笔记06_图形识别

1. 人工智能研究人员在过去几十年中学到的最重要的教训之一 1.1. 看似智能的行为有可能从看似随机的系统中浮现出来 1.2. 如果我们有能力进入人脑,研究神经元之间连接的强度,其中绝大部分连接都会表现得很随机 1.3. 当作为集合体行动时,这…

javaScript蓝桥杯-----全球新冠疫情数据统计

目录 一、介绍二、准备三、⽬标四、代码五、完成 一、介绍 新冠疫情席卷全球,在此期间有很多免费的 API 和⽹站为⼈们提供了各个国家疫情数据的查询功能,这些免费公开的数据体现出了互联⽹作为信息媒介的优越性,帮助全球⼈⺠更好的了解⼀线疫…

电路模型和电路定律(3)——“电路分析”

小雅兰期末加油冲冲冲!!! 复习之前的内容: 这样的连接方式是不可以的: 两个电压源,电压值不相同,是不能并联的 两个电流源,电流值不相同,是不能串联的 电流源也不能开…

浅谈Zuul、Gateway

一、Zuul Zuul是通过Servlet来实现的,Zuul通过自定义的ZuulServlet(类似于Spring MVC的DispatcherServlet)来对请求进行控制(一系列过滤器处理Http请求)。 所有的Request都要经过ZuulServlet的处理,三个核心的方法preRoute(),rou…

时钟频率的配置-DG32

时钟频率的配置-DG32 HXTAL:高速外部时钟,4到32MHz的外部振荡器,可为系统提供精确的主时钟。带有特定频率的晶体必须靠近两个HXTAL的引脚。和晶体连接的外部电阻和电容必须根据所选择的振荡器来调整; LXTAL:低速外部…

chatgpt赋能python:Python开发桌面应用全面介绍

Python开发桌面应用全面介绍 Python是一种非常万能的编程语言,也逐步发展成为一种适用于开发各种桌面应用程序的语言。Python开发桌面应用的优点是它可以快速开发,易于阅读和使用,同时具有很高的可扩展性和可维护性,因此越来越多…