一起聊聊MySQL基础之触发器和事件

本篇文章给大家带来了关于mysql中触发器和事件的相关知识,其中包括触发器使用注意事项、查看和删除事件、事件使用注意事项等等,希望对大家有帮助。

一起聊聊MySQL基础之触发器和事件

触发器

我们使用MySQL的过程中可能会有下边这些需求:

在向t1表插入或更新数据之前对自动对数据进行校验,要求m1列的值必须在1~10之间,校验规则如下:

如果插入的记录的m1列的值小于1,则按1插入。如果m1列的值大于10,则按10插入。

在向t1表中插入记录之后自动把这条记录插入到t2表。

也就是我们在对表中的记录做增、删、改操作前和后都可能需要让MySQL服务器自动执行一些额外的语句,这个就是所谓的触发器的应用场景。

创建触发器

我们看一下定义触发器的语句:

CREATE TRIGGER 触发器名{BEFORE|AFTER}{INSERT|DELETE|UPDATE}ON 表名FOR EACH ROWBEGIN    触发器内容END

小贴士:由大括号`{}`包裹并且内部用竖线`|`分隔的语句表示必须在给定的选项中选取一个值,比如`{BEFORE|AFTER}`表示必须在`BEFORE`、`AFTER`这两个之间选取一个。

其中{BEFORE|AFTER}表示触发器内容执行的时机,它们的含义如下:

名称 描述

BEFORE表示在具体的语句执行之前就开始执行触发器的内容AFTER表示在具体的语句执行之后才开始执行触发器的内容

{INSERT|DELETE|UPDATE}表示具体的语句,MySQL中目前只支持对INSERT、DELETE、UPDATE这三种类型的语句设置触发器。

FOR EACH ROW BEGIN ... END表示对具体语句影响的每一条记录都执行我们自定义的触发器内容:

对于INSERT语句来说,FOR EACH ROW影响的记录就是我们准备插入的那些新记录。

对于DELETE语句和UPDATE语句来说,FOR EACH ROW影响的记录就是符合WHERE条件的那些记录(如果语句中没有WHERE条件,那就是代表全部的记录)。

小贴士: 如果触发器内容只包含一条语句,那也可以省略BEGN、END这两个词儿。

因为MySQL服务器会对某条语句影响的所有记录依次调用我们自定义的触发器内容,所以针对每一条受影响的记录,我们需要一种访问该记录中的内容的方式,MySQL提供了NEW和OLD两个单词来分别代表新记录和旧记录,它们在不同语句中的含义不同:

对于INSERT语句设置的触发器来说,NEW代表准备插入的记录,OLD无效。对于DELETE语句设置的触发器来说,OLD代表删除前的记录,NEW无效。对于UPDATE语句设置的触发器来说,NEW代表修改后的记录,OLD代表修改前的记录。

现在我们可以正式定义一个触发器了:

mysql> delimiter $mysql> CREATE TRIGGER bi_t1    -> BEFORE INSERT ON t1    -> FOR EACH ROW    -> BEGIN    ->     IF NEW.m1          SET NEW.m1 = 1;    ->     ELSEIF NEW.m1 > 10 THEN    ->         SET NEW.m1 = 10;    ->     END IF;    -> END $Query OK, 0 rows affected (0.02 sec)mysql> delimiter ;mysql>

我们对t1表定义了一个名叫bi_t1的触发器,它的意思就是在对t1表插入新记录之前,对准备插入的每一条记录都会执行BEGIN ... END之间的语句,NEW.列名表示当前待插入记录指定列的值。现在t1表中一共有4条记录:

mysql> SELECT * FROM t1;+------+------+| m1   | n1   |+------+------+|    1 | a    ||    2 | b    ||    3 | c    ||    4 | d    |+------+------+4 rows in set (0.00 sec)mysql>

我们现在执行一下插入语句并再次查看一下t1表的内容:

mysql> INSERT INTO t1(m1, n1) VALUES(5, 'e'), (100, 'z');Query OK, 2 rows affected (0.00 sec)Records: 2  Duplicates: 0  Warnings: 0mysql> SELECT * FROM t1;+------+------+| m1   | n1   |+------+------+|    1 | a    ||    2 | b    ||    3 | c    ||    4 | d    ||    5 | e    ||   10 | z    |+------+------+6 rows in set (0.00 sec)mysql>

这个INSERT语句影响的记录有两条,分别是(5, 'e')和(100, 'z'),这两条记录将分别执行我们自定义的触发器内容。很显然(5, 'e')被成功的插入到了t1表中,而(100, 'z')插入到表中后却变成了(10, 'z'),这个就说明我们的bi_t1触发器生效了!

小贴士: 我们上边定义的触发器名`bi_t1`的`bi`是`before insert`的首字母缩写,`t1`是表名。虽然对于触发器的命名并没有什么特殊的要求,但是习惯上还是建议大家把它定义我上边例子中的形式,也就是`bi_表名`、`bd_表名`、`bu_表名`、`ai_表名`、`ad_表名`、`au_表名`的形式。

上边只是举了一个对INSERT语句设置BEFORE触发器的例子,对DELETE和UPDATE操作设置BEFORE或者AFTER触发器的过程是类似的,就不赘述了。

查看和删除触发器

查看当前数据库中定义的所有触发器的语句:

SHOW TRIGGERS;

查看某个具体的触发器的定义:

SHOW CREATE TRIGGER 触发器名;

删除触发器:

DROP TRIGGER 触发器名;

这几个命令太简单了,就不举例子了啊~

触发器使用注意事项

触发器内容中不能有输出结果集的语句。

比方说:

mysql> delimiter $mysql> CREATE TRIGGER ai_t1    -> AFTER INSERT ON t1    -> FOR EACH ROW    -> BEGIN    ->     SELECT NEW.m1, NEW.n1;    -> END $ERROR 1415 (0A000): Not allowed to return a result set from a triggermysql>

显示的ERROR的意思就是不允许在触发器内容中返回结果集!

触发器内容中NEW代表记录的列的值可以被更改,OLD代表记录的列的值无法更改。

NEW代表新插入或着即将修改后的记录,修改它的列的值将影响INSERT和UPDATE语句执行后的结果,而OLD代表修改或删除之前的值,我们无法修改它。比方说如果我们非要这么写那就会报错的:

文心一言 文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

文心一言 1008 查看详情 文心一言

mysql> delimiter $mysql> CREATE TRIGGER bu_t1    -> BEFORE UPDATE ON t1    -> FOR EACH ROW    -> BEGIN    ->     SET OLD.m1 = 1;    -> END $ERROR 1362 (HY000): Updating of OLD row is not allowed in triggermysql>

可以看到提示的错误中显示在触发器中OLD代表的记录是不可被更改的。

在BEFORE触发器中,我们可以使用SET NEW.列名 = 某个值的形式来更改待插入记录或者待更新记录的某个列的值,但是这种操作不能在AFTER触发器中使用,因为在执行AFTER触发器的内容时记录已经被插入完成或者更新完成了。

比方说如果我们非要这么写那就会报错的:

mysql> delimiter $mysql>     CREATE TRIGGER ai_t1    ->     AFTER INSERT ON t1    ->     FOR EACH ROW    ->     BEGIN    ->         SET NEW.m1 = 1;    ->     END $ERROR 1362 (HY000): Updating of NEW row is not allowed in after triggermysql>

可以看到提示的错误中显示在AFTER触发器中是不允许更改NEW代表的记录的。

如果我们的BEFORE触发器内容执行过程中遇到了错误,那这个触发器对应的具体语句将无法执行;如果具体的操作语句执行过程中遇到了错误,那与它对应的AFTER触发器的内容将无法执行。

小贴士: 对于支持事务的表,不论是执行触发器内容还是具体操作语句过程中出现了错误,会把这个过程中所有的语句都回滚。当然,作为小白的我们并不知道啥是个事务,啥是个回滚,这些进阶内容都在《MySQL是怎样运行的:从根儿上理解MySQL》中呢~

事件

有时候我们想让MySQL服务器在某个时间点或者每隔一段时间自动地执行一些语句,这时候就需要去创建一个事件。

创建事件

创建事件的语法如下:

CREATE EVENT 事件名ON SCHEDULE{    AT 某个确定的时间点|     EVERY 期望的时间间隔 [STARTS datetime][END datetime]}DOBEGIN    具体的语句END

事件支持两种类型的自动执行方式:

在某个确定的时间点执行。

比方说:

CREATE EVENT insert_t1_eventON SCHEDULEAT '2019-09-04 15:48:54'DOBEGIN    INSERT INTO t1(m1, n1) VALUES(6, 'f');END

我们在这个事件中指定了执行时间是'2019-09-04 15:48:54',除了直接填某个时间常量,我们也可以填写一些表达式:

CREATE EVENT insert_t1ON SCHEDULEAT DATE_ADD(NOW(), INTERVAL 2 DAY)DOBEGIN    INSERT INTO t1(m1, n1) VALUES(6, 'f');END

其中的DATE_ADD(NOW(), INTERVAL 2 DAY)表示该事件将在当前时间的两天后执行。

每隔一段时间执行一次。

比方说:

CREATE EVENT insert_t1ON SCHEDULEEVERY 1 HOURDOBEGIN    INSERT INTO t1(m1, n1) VALUES(6, 'f');END

其中的EVERY 1 HOUR表示该事件将每隔1个小时执行一次。默认情况下,采用这种每隔一段时间执行一次的方式将从创建事件的事件开始,无限制的执行下去。我们也可以指定该事件开始执行时间和截止时间:

CREATE EVENT insert_t1ON SCHEDULEEVERY 1 HOUR STARTS '2019-09-04 15:48:54' ENDS '2019-09-16 15:48:54'DOBEGIN    INSERT INTO t1(m1, n1) VALUES(6, 'f');END

如上所示,该事件将从’2019-09-04 15:48:54’开始直到’2019-09-16 15:48:54’为止,中间每隔1个小时执行一次。

小贴士: 表示事件间隔的单位除了HOUR,还可以用YEAR、QUARTER、MONTH、DAY、HOUR、 MINUTE、WEEK、SECOND、YEAR_MONTH、DAY_HOUR、DAY_MINUTE、DAY_SECOND、HOUR_MINUTE、HOUR_SECOND、MINUTE_SECOND这些单位,根据具体需求选用我们需要的时间间隔单位。

在创建好事件之后我们就不用管了,到了指定时间,MySQL服务器会帮我们自动执行的。

查看和删除事件

查看当前数据库中定义的所有事件的语句:

SHOW EVENTS;

查看某个具体的事件的定义:

SHOW CREATE EVENT 事件名;

删除事件:

DROP EVENT 事件名;

这几个命令太简单了,就不举例子了啊~

事件使用注意事项

默认情况下,MySQL服务器并不会帮助我们执行事件,除非我们使用下边的语句手动开启该功能:

mysql> SET GLOBAL event_scheduler = ON;Query OK, 0 rows affected (0.00 sec)mysql>

小贴士: event_scheduler其实是一个系统变量,它的值也可以在MySQL服务器启动的时候通过启动参数或者通过配置文件来设置event_scheduler的值。这些所谓的系统变量、启动参数、配置文件的各种东东并不是我们小白现在需要掌握的,大家忽略它们就好了~

推荐学习:mysql视频教程

以上就是一起聊聊MySQL基础之触发器和事件的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/284965.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
laravel6实战视频
上一篇 2026年10月19日 05:56:12
荣耀Magic6怎么设置通讯录黑名单?
下一篇 2025年11月28日 17:18:31

相关推荐

  • mysql存储过程中怎么给变量赋值

    mysql存储过程中怎么给变量赋值mysql存储过程中怎么给变量赋值mysql存储过程中怎么给变量赋值mysql存储过程中怎么给变量赋值

    mysql存储过程中给变量赋值的方法:1、利用DECLARE关键字,语法“DECLARE 变量名 类型 DEFAULT 默认值;”;2、利用SET关键字,语法“SET 变量名 = 赋值表达式;”。 本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 在mysql的存储过程和…

    2026年10月19日 • 用户投稿
    000
  • mysql存储过程的游标是什么

    mysql存储过程的游标是什么mysql存储过程的游标是什么mysql存储过程的游标是什么mysql存储过程的游标是什么

    在mysql存储过程中,游标也称为光标,是一个存储在DBMS服务器上的数据库查询,是检索操作返回一组结果集,一般用于对检索出来的数据进行前进或者后退操作。 本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 在 MySQL 中,存储过程或函数中的查询有时会返回多条记录,而使…

    2026年10月19日 • 用户投稿
    100
  • thinkphp如何使用

    thinkphp如何使用thinkphp如何使用thinkphp如何使用thinkphp如何使用

    ThinkPHP 是一款 PHP MVC 框架,用于开发 Web 应用。使用步骤包括:安装 ThinkPHP、配置数据库、定义模型、定义控制器、定义视图、设置路由和运行。具体步骤为:1. 安装 ThinkPHP;2. 配置数据库;3. 定义模型;4. 定义控制器;5. 定义视图;6. 设置路由;7.…

    2026年10月19日 • 用户投稿
    100
  • 怎么查询mysql的字符集

    怎么查询mysql的字符集怎么查询mysql的字符集怎么查询mysql的字符集怎么查询mysql的字符集

    方法:1、“show charset”语句,查看MYSQL所支持的字符集;2、“show create database 库名G”语句,查看库的字符集;3、“show full columns from 表名”,查看表中所有列的字符集。 本教程操作环境:windows7系统、mysql8版本、Del…

    2026年10月19日 • 用户投稿
    100
  • mysql查询结果怎么合并

    mysql查询结果怎么合并mysql查询结果怎么合并mysql查询结果怎么合并mysql查询结果怎么合并

    在mysql中,可以利用UNION操作符来合并查询结果,该操作符用于将两个以上的SELECT语句的查询结果合并到一起,然后去除掉相同的记录;语法“查询语句1 union 查询语句2 union ….”。 本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 在my…

    2026年10月19日 • 用户投稿
    100
  • mysql怎么将查询结果赋给变量

    mysql怎么将查询结果赋给变量mysql怎么将查询结果赋给变量mysql怎么将查询结果赋给变量mysql怎么将查询结果赋给变量

    mysql将查询结果赋给变量的方法:1、使用“DECLARE 变量名 类型 [DEFAULT 默认值];”语句创建变量;2、使用“SELECT 字段名 INTO 变量名 FROM 表名 WEHRE 查询条件;”语句将查询结果赋值给变量。 本教程操作环境:windows7系统、mysql8版本、Del…

    2026年10月19日 • 用户投稿
    100
  • 读完搞懂MySQL持久化和回滚(图文详解)

    读完搞懂MySQL持久化和回滚(图文详解)读完搞懂MySQL持久化和回滚(图文详解)读完搞懂MySQL持久化和回滚(图文详解)读完搞懂MySQL持久化和回滚(图文详解)

    本篇文章给大家带来了mysql中关于持久化和回滚的相关知识,希望对大家有帮助。 redo log 事务的支持是数据库区分文件系统的重要特征之一,事务的四大特性: 原子性:所有的操作要么都做,要么都不做,不可分割。一致性:数据库从一种状态变成另一种状态的的结果最终是一致的,比如A给B转账500,A最终…

    2026年10月19日 • 用户投稿
    200
  • mysql中的事务是什么

    mysql中的事务是什么mysql中的事务是什么mysql中的事务是什么mysql中的事务是什么

    在mysql中,事务是一种机制、一个操作序列,是访问和更新数据库的程序执行单元。事务中包含一个或多个数据库操作命令,会把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。 本教程操作环境:windows7系统、mysql5.6版本、Dell G3电脑。 …

    2026年10月19日 • 用户投稿
    300
  • workerman手册

    workerman手册workerman手册workerman手册workerman手册

    Workerman是一个异步事件驱动框架,用于开发高性能网络应用。其特点包括高性能、低内存消耗、易于使用和可扩展。它广泛应用于即时通讯、WebSocket服务、高并发HTTP服务等场景。使用时可创建Worker类,并调用run()函数运行Worker。Workerman提供了丰富的API,包括Wor…

    2026年10月19日 • 用户投稿
    000
  • mysql怎么修改事务隔离级别

    mysql怎么修改事务隔离级别mysql怎么修改事务隔离级别mysql怎么修改事务隔离级别mysql怎么修改事务隔离级别

    修改方法:1、在命令窗口中执行“set session transaction isolation level 事务级别;”语句即可;2、打开“mysql.ini”文件,添加“transaction-isolation=事务级别”语句即可。 本教程操作环境:windows7系统、mysql8版本、D…

    2026年10月19日 • 用户投稿
    100
  • mysql怎么查询事务隔离级别

    mysql怎么查询事务隔离级别mysql怎么查询事务隔离级别mysql怎么查询事务隔离级别mysql怎么查询事务隔离级别

    mysql查询事务隔离级别的方法:1、启动命令行窗口,连接MySQL数据库;2、在命令窗口中执行“show variables like ‘tx_isolation’;”或“SELECT @@tx_isolation;”命令即可查询。 本教程操作环境:windows7系统、m…

    2026年10月19日 • 用户投稿
    400
  • mysql where关键字怎么用

    mysql where关键字怎么用mysql where关键字怎么用mysql where关键字怎么用mysql where关键字怎么用

    在mysql中,where关键字需要和SELECT语句一起使用,用于指定查询条件,即有条件的从数据表中查询并返回数据;语法“SELECT {*|字段列名} FROM 数据表名 WHERE 查询条件;”。 本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 MySQL WHE…

    2026年10月19日 • 用户投稿
    100
  • nagios使用y流览

    nagios使用y流览nagios使用y流览nagios使用y流览nagios使用y流览

    Nagios 使用 YAML 配置文件,包括全局设置、命令定义、事件处理程序、宏、主机组、联系人、主机和服务配置。要配置 YAML 文件,需按照规定结构添加或修改配置部分,使用缩进和注释提高可读性,最后保存并重新加载 Nagios 配置。 Nagios 使用 YAML 配置文件 Nagios 是一款…

    2026年10月19日 • 用户投稿
    600
  • mysql having关键字怎么用

    mysql having关键字怎么用mysql having关键字怎么用mysql having关键字怎么用mysql having关键字怎么用

    在mysql中,having关键字需要和SELECT语句一起使用,用于对分组后的数据进行过滤,语法“SELECT {*|字段列名} FROM 数据表名 HAVING 查询条件;”。 本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 MySQL HAVING:过滤分组 在 …

    2026年10月19日 • 用户投稿
    100
  • 你值得了解的15个Mysql索引失效场景(带你快速避坑)

    你值得了解的15个Mysql索引失效场景(带你快速避坑)你值得了解的15个Mysql索引失效场景(带你快速避坑)你值得了解的15个Mysql索引失效场景(带你快速避坑)你值得了解的15个Mysql索引失效场景(带你快速避坑)

    本篇文章总结分享15个mysql索引失效场景,让大家可避坑踩雷,希望能够给大家提供帮助! 无论你是技术大佬,还是刚入行的小白,时不时都会踩到Mysql数据库不走索引的坑。常见的现象就是:明明在字段上添加了索引,但却并未生效。 前些天就遇到一个稍微特殊的场景,同一条SQL语句,在某些参数下生效,在某些…

    2026年10月19日 • 用户投稿
    300
  • mysql怎么增加数据库

    mysql怎么增加数据库mysql怎么增加数据库mysql怎么增加数据库mysql怎么增加数据库

    在mysql中,可以利用“CREATE DATABASE”语句来增加数据库,语法为“CREATE DATABASE [IF NOT EXISTS] 库名 [CHARACTER SET 字符集名] [COLLATE 校对规则名];”。 本教程操作环境:windows7系统、mysql8版本、Dell …

    2026年10月18日 • 用户投稿
    300
  • mysql中not exists的用法是什么

    mysql中not exists的用法是什么mysql中not exists的用法是什么mysql中not exists的用法是什么mysql中not exists的用法是什么

    mysql中,“not exists”是不存在的意思,在where后进行条件判断,后面紧跟子查询语句,根据子查询语句有没有结果来进行判断,语法为“Select*from TableA a where Not Exists (子查询语句)”。 本教程操作环境:windows10系统、mysql8.0.…

    2026年10月18日 • 用户投稿
    300
  • mysql聚集索引和非聚集索引的区别是什么

    mysql聚集索引和非聚集索引的区别是什么mysql聚集索引和非聚集索引的区别是什么mysql聚集索引和非聚集索引的区别是什么mysql聚集索引和非聚集索引的区别是什么

    区别:1、聚集索引在叶子节点存储的是表中的数据,而非聚集索引在叶子节点存储的是主键和索引列;2、聚集索引中表记录的排列顺序和索引的排列顺序一致,而非聚集索引的排列顺序不一致;3、聚集索引每张表只能有一个,而非聚集索引可以有多个。 本教程操作环境:windows7系统、mysql8版本、Dell G3…

    2026年10月18日 • 用户投稿
    100
  • MYSQL之巧用字符函数做数据筛选

    本文主要介绍了mysql 一个巧用字符函数做数据筛选的题,需要的朋友可以参考下,希望能帮助到大家。 问题描述: 结构: test 有两个字段,分别是col1和col2,都是字符字段,里面的内容都是用,号分隔的三个数字,并且是一一对应的, 比如col1内容是:26,59,6col2内容是:1502.5…

    2026年10月18日
    200
  • mysql视图是什么?视图有哪些优缺点?

    mysql视图是虚拟表,不存储实际数据,基于真实表查询结果。1.优点:简化复杂查询,将多表join封装为视图方便调用;2.安全性:控制访问权限,隐藏敏感字段;3.缺点:性能可能受影响,尤其嵌套视图或复杂逻辑时;4.更新限制:含聚合函数、distinct、group by或多表连接的视图不可更新。使用…

    2026年10月18日
    300

发表回复

登录后才能评论
关注微信