一篇文带你零基础玩转mysql触发器 | 超级干货,建议收藏
Posted bug菌√
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文带你零基础玩转mysql触发器 | 超级干货,建议收藏相关的知识,希望对你有一定的参考价值。
文章目录:
一、绪论:
mysql 作为当今最流行的关系型数据库管理系统之一,由瑞典MySQL AB 公司开发,属于 Oracle 旗下的产品。由于 MySQL已源码,因此大大降低了成本,但也可以从Oracle购买商业许可证版本,以获得高级支持服务(特殊企业用户需要)。
与其他数据库软件(如Oracle数据库或Microsoft SQL Server)相比,MySQL已经非常容易学习和掌握。MySQL可以在各种平台上运行UNIX,Linux,Windows等;也可以将其安装在服务器甚至桌面系统上。 此外,MySQL是可靠,可扩展和快速的。如果您开发网站或Web应用程序,MySQL是一个不错的选择(强烈建议使用)。MySQL是LAMP堆栈的重要组成部分,包括Linux,Apache,MySQL和php。更多mysql介绍使用请上官网学习,此处就不多言阐述啦。
奉上MySQL官网址: http://www.mysql.com/ ,MySQL社区版本下载地址: http://dev.mysql.com/downloads/mysql/
二、前言:
想必使用过mysql的小伙伴,都知道,mysql有事务、索引、触发器、存储过程等;那么今天,bug菌今天就来给大家聊一聊它,暂时此期就不更《Ubuntu零基础教学》,但是不会鸽太久啦,顶多鸽一两个礼拜...啊呸,一两天啦;此期也是为了允诺私聊bug菌的小伙伴啦,单独更一期mysql触发器的相关基础教学;还请小伙伴们细品~
阅读文章的同时若是发现途中有讲述的不对或者理解有偏差的地方,还请小伙伴们多多谅解,毕竟bug菌也经验水平有限啦,但非常欢迎小伙伴们能留下观点、提出宝贵建议和意见,下方留言评论,找出我的不足,bug菌的成长同时也是见证你的成长!万事尽力!尽力而为。
如果最后觉得该文章对你有所帮助,还请不要吝啬你的赞哦,直接pia的点亮就完事了啦 up up up!!!你们的鼓励就是对bug菌写作最大的支持!
那么接下来,干正事啦!bug菌要开始上课了喔~
三、本章内容:
1. MySQL触发器是什么?
#1基本概念:
- 触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的,即不是主动调用而执行的;而存储过程则需要主动调用其名字执行。
- 触发器:trigger,是指事先为某张表绑定一段代码,当表中的某些内容发生改变(增、删、改)的时候,系统会自动触发代码并执行。
#2作用:
- 可在写入数据前,强制检验或者转换数据(保证护数据安全)。触发器发生错误时,前面用户已经执行成功的操作会被撤销,类似事务的回滚。
#3版本:
- MySQL 5.0开始才支持存储过程、触发器
2. 为什么要用MySQL触发器?
- 触发器可以检查或修改新数据值,这意味着我们可以利用触发器强制实现数据完整性,比如检查某个百分比数值是否在0-100之间,还可以用来对输入数据进行必要的过滤;
- 触发器可以将表达式的结果赋值给数据列作为默认值。因此我们可以绕开数据列定义里的默认值必须为常数的限制;
- 触发器可以在删除或修改数据行之前先检查它的当前内容。利用这种能力可以实现许多功能,比如把对现有数据的修改记载到一个日志里。
3. 如何创建MySQL触发器?
#1基本语法
delimiter 自定义结束符号
create trigger 触发器名字 触发时间 触发事件 on 表 for each row
begin
-- 触发器内容主体,每行用分号结尾
end
自定义的结束符合
delimiter ;
on 表 for each:触发对象,触发器绑定的实质是表中的所有行,因此当每一行发生指定改变时,触发器就会发生;
其中:
- 触发器名称:标识触发器名称,用户自行指定;
- 触发时间:标识触发时间,取值为 BEFORE 或 AFTER;
- 触发事件:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
- 触发器表名:标识建立触发器的表名,即在哪张表上建立触发器;
- 触发器程序体:可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。
由此可见,可以建立6种触发器,即:BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE。
#2触发时间
当 SQL 指令发生时,会令行中数据发生变化,而每张表中对应的行有两种状态:数据操作前和操作后
- before:表中数据发生改变前的状态
- after:表中数据发生改变后的状态
PS:如果 before 触发器失败或者语句本身失败,将不执行 after 触发器(如果有的话)
#3触发事件
触发器是针对数据发送改变才会被触发,对应的操作只有
- INSERT
- DELETE
- UPDATE
#4注意事项
在 MySQL 5 中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一,即同一数据库中的两个表可能具有相同名字的触发器
每个表的每个事件每次只允许一个触发器,因此,每个表最多支持 6 个触发器
before/after insert、before/after delete、before/after update
另外有一个限制是不能同时在一个表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。
#5实例演示
1、创建完整触发器示例:
我先来先来创建一个名为 trigger_demo 的完整触发器;
目的:当user表发生update 操作后,自动往 log_info表中插入一条日志记录,具体记录 操作时间、更新前的那条数据用户名称、用户id;
delimiter ||
create trigger trigger_demo AFTER UPDATE ON user for each row
BEGIN
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name);
END ||
delimiter;
a、变量详解
MySQL 中使用 delimiter 来定义一局部变量,该变量只能在 BEGIN … END 复合语句中使用,并且应该定义在复合语句的开头,
默认情况下,delimiter是分号 ; ,在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。
delimiter ||
其中DELIMITER 定好结束符为"|| ", 然后最后又定义为";", MYSQL的默认结束符为";"。
b、NEW 与 OLD 详解
上述示例中使用了NEW关键字,和 MS SQL Server 中的 INSERTED 和 DELETED 类似,MySQL 中定义了 NEW 和 OLD,用来表示
触发器的所在表中,触发了触发器的那一行数据。
具体地:
- 在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
- 在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
- 在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名)
另外,old是只读的,而 new 则可以在触发器中使用 set赋值,这样不会再次触发 触发器,造成循环调用(比如每插入一个用户前,都在其用户code前拼接“20210617”),这就可以使用set 定义一个临时变量了。
如下:定义一个临时变量,一般都以@前缀命名,比如 @new_user_id ;然后在你要执行的事件sql中直接拿来用即可!
delimiter ||
create trigger trigger_demo_update AFTER update ON sys_user for each row
BEGIN
SET @new_user_id = CONCAT('20210617',new.id);
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), @new_user_id,new.user_name);
END ||
delimiter;
演示:
- 测试update获取更新前更新后数据
UPDATE user SET user_name= '改名字',user_id='999' where user_id = '30' #对user表执行update操作
delimiter ||
create trigger trigger_demo_update AFTER UPDATE ON user for each row
BEGIN
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name);
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), new.user_id,new.user_name);
END ||
delimiter;
经测试,更新user后立马执行触发器,可以看到log_info表操作日志插入进去了! 如下是log_info表数据截图。
- 测试insert获取更新后数据
INSERT into user (user_name,user_account) VALUES('张三','zhangsan'); #对user表执行insert操作
delimiter ||
create trigger trigger_demo_insert AFTER Insert ON user for each row
BEGIN
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), new.user_id,new.user_name);
END ||
delimiter;
经测试,新增user后立马执行触发器,成功将插入后的数据写入log_info表中,如下是log_info表数据截图。
- 测试delete获取更新后数据
DELETE FROM user where user_old = '999' #对user表执行delete操作
delimiter ||
create trigger trigger_demo_delete AFTER delete ON user for each row
BEGIN
INSERT into log_info ( create_time,user_id,user_name )VALUES (now(), old.user_id,old.user_name);
END ||
delimiter;
经测试,删除后立马执行触发器,成功将删除前的数据写入log_info表中,如下是log_info表数据截图。
2、查看触发器
和查看数据库(show databases;)查看表格(show tables;)一样,查看触发器的语法如下:
show triggers; #查看全部触发器
show create trigger trigger_demo_delete; #查看触发器的创建语句
3、删除触发器
和删除数据库、删除表格一样,删除触发器的语法如下:切记:触发器不能修改,只能删除。
drop trigger + 触发器名
演示:直接命令删除;
DROP trigger trigger_demo_delete; #删除触发器
也可以通过navicat 选择要删除的触发器,点击【删除触发器】摁钮,会弹出二次确认,点击【删除】即可。
提问:触发器可以批量删除吗?
回答:经测试,不可以。
验证下方删除多个,结果执行失败了!
显而易见,不支持批量删除。
单删成功。
切记:如果某个触发器不需要用了,一定要立即把这个触发器给删掉,以免造成意外操作,这很关键。切记切记!!!
#6触发器的执行顺序
我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL 会回滚事务,有:
①如果 BEFORE 触发器执行失败,SQL 无法正确执行。
②SQL 执行失败时,AFTER 型触发器不会触发。
③AFTER 类型的触发器执行失败,SQL 会回滚。
4. MySQL触发器应用
触发器针对的是数据库中的每一行记录,每行数据在操作前后都会有一个对应的状态,触发器将没有操作之前的状态保存到 old 关键字中,将操作后的状态保存到 new 中;
因此说明:MySQL 的触发器中不能对本表进行 insert、update 和 delete 操作,否则会报错;
5. MySQL触发器优缺点
#1优点
- SQL触发器提供了检查数据完整性的替代方法。
- SQL触发器可以捕获数据库层中业务逻辑中的错误。
- SQL触发器提供了运行计划任务的另一种方法。通过使用SQL触发器,您不必等待运行计划的任务,因为在对表中的数据进行更改之前或之后自动调用触发器。
- SQL触发器对于审核表中数据的更改非常有用。
#2缺点
- SQL触发器只能提供扩展验证,并且无法替换所有验证。一些简单的验证必须在应用层完成。 例如,您可以使用javascript或服务器端使用服务器端脚本语言(如JSP,PHP,ASP.NET,Perl等)来验证客户端的用户输入。
- 从客户端应用程序调用和执行SQL触发器不可见,因此很难弄清数据库层中发生的情况。
- SQL触发器可能会增加数据库服务器的开销。
四、常用命令
show triggers; #查看全部触发器
show create trigger [触发器名字]; 查看触发器的创建语句
DROP trigger [触发器名字]; #删除触发器
五、个人建议
只有在并发不高的项目,管理系统中用。如果是面向用户的高并发应用,都不要使用。触发器和存储过程本身难以开发和维护,不能高效移植。触发器完全可以用事务替代。存储过程可以用后端脚本替代。
六、热文推荐
如果觉得这篇文章对你有所帮助,还请不忘在文章的左下角,直接pia的一下点亮它 up up up!!!若是我,不用犹豫直接进我的收藏夹吃灰去吧!不管以后用不用的上,先吃上灰再说,哈哈哈哈哈嗝~~
❤如果文章对您有所帮助,就请在文章末尾的左下角把大拇指点亮吧!(#^.^#);
❤如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(๑′ᴗ‵๑)づ╭❤~;
❤对文章有任何问题欢迎小伙伴们下方留言或者入群探讨【群号:708072830】;
❤鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);
❤版权声明:本文为博主原创文章,转载请附上原文出处链接和本文声明,版权所有,盗版必究!(*^▽^*).
以上是关于一篇文带你零基础玩转mysql触发器 | 超级干货,建议收藏的主要内容,如果未能解决你的问题,请参考以下文章