一篇文带你零基础玩转mysql触发器 | 超级干货,建议收藏

1,778 阅读14分钟

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

       ​嗨,家人们,我是bug菌,我又来啦。今天我们来聊点什么咧,OK,接着为大家更Ubuntu系列文章吧。哈哈哈哈,说习惯了,最近有小伙伴私信我,老是Ubuntu都看腻了,没问题,今个儿一周就给大家换个口味,大家可得认真听好好学哈。

       具有很好的教学价值,希望小伙伴们根据这篇文章可以有所收获,建议小伙伴们先收藏后阅读哦。

小伙伴们如果觉得文章不错,点赞、收藏、评论,分享走一起呀,记得给bug菌来个一键三连~~

       特此呢,针对小白系列教学,bug菌专门开放了一个专栏,感兴趣的朋友可以关注《Ubuntu零基础教学》

       bug菌做这么多只为一件事就是想把你们都教会,教不会不收学费!对你们有所帮助的小伙伴们,还请不忘给bug菌一个赞,你们的鼓励就是对我最大的支持! 那么接下来,干正事啦!bug菌要开始上课了喔~

文章目录:

一、绪论:

二、前言:

三、本章内容:

1. MySQL触发器是什么?

#1基本概念:

#2作用:

#3版本:

2. 为什么要用MySQL触发器?

3. 如何创建MySQL触发器?

#1基本语法

#2触发时间

#3触发事件

#4注意事项

#5实例演示

#6触发器的执行顺序

4. MySQL触发器应用

5. MySQL触发器优缺点

#1优点

#2缺点

四、常用命令

五、个人建议

六、热文推荐

一、环境说明

系统要求:Ubuntu20.04

二、前言

       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官网址: MySQL ,MySQL社区版本下载地址: MySQL :: Download MySQL Community Server

三、前言:

       想必使用过mysql的小伙伴,都知道,mysql有事务、索引、触发器、存储过程等;那么今天,bug菌今天就来给大家聊一聊它

但是不会鸽太久啦,顶多鸽一两个礼拜...啊呸,一两天啦;此期也是为了允诺私聊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 触发器名字 触发时间 触发事件 onfor each row
begin
    -- 触发器内容主体,每行用分号结尾
end
自定义的结束符合

delimiter ;

on 表 for each:触发对象,触发器绑定的实质是表中的所有行,因此当每一行发生指定改变时,触发器就会发生;

其中:

  1. 触发器名称:标识触发器名称,用户自行指定;
  2. 触发时间:标识触发时间,取值为 BEFORE 或 AFTER;
  3. 触发事件:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
  4. 触发器表名:标识建立触发器的表名,即在哪张表上建立触发器;
  5. 触发器程序体:可以是一句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】;

❤鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);

❤版权声明:本文为博主原创文章,转载请附上原文出处链接和本文声明,版权所有,盗版必究!(*^▽^*).