MySQL触发器介绍(mysql 触发器)
yuyutoo 2025-05-08 22:04 9 浏览 0 评论
前言:
在学习 MySQL 的过程中,可能你了解过触发器的概念,不清楚各位是否有详细的去学习过触发器,最近看了几篇关于触发器的文档,分享下 MySQL 触发器相关知识。
1.触发器简介
触发器即 triggers ,它是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。
参考官方文档,触发器创建语法模板如下:
CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
触发器只能创建在永久表上,不能对临时表或视图创建触发器。触发器的名称在单个数据库内是唯一的。参考上面创建语句,触发器创建有几点要素,下面简要说明下:
trigger_time:是触发动作时间,可以是 BEFORE 或 AFTER ,表示触发器在要修改的每一行之前或之后激活。
trigger_event:指示激活触发器的操作类型。这些 trigger_event 值是被允许的:
- insert:只要向表中插入新行,触发器就会激活。例如 insert 、load data、replace 语句。
- update:更改表中某一行数据时激活触发器。例如 update 语句。
- delete:从表中删除某一行数据时激活触发器。例如 delete 和 replace 语句。表上的 DROP TABLE 和 TRUNCATE TABLE 语句不会激活此触发器,因为它们不使用 delete ,删除分区也不会激活 delete 触发器。
trigger_body:是触发器激活时要执行的语句。如果要执行多个语句,可使用 BEGIN…END 复合语句结构。在触发器主体中,可以使用 old 和 new 来引用触发器中发生变化的记录内容。
2.触发器具体操作
下面来看下触发器相关的具体操作:
# 创建表 创建触发器
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql> delimiter //
mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
ELSEIF NEW.amount > 100 THEN
SET NEW.amount = 100;
END IF;
END;//
mysql> delimiter ;
# 验证触发器作用
mysql> select * from account;
+----------+---------+
| acct_num | amount |
+----------+---------+
| 137 | 14.98 |
| 141 | 1937.50 |
| 97 | -100.00 |
+----------+---------+
3 rows in set (0.00 sec)
mysql> update account set amount = 114.98 where acct_num = 137;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from account;
+----------+---------+
| acct_num | amount |
+----------+---------+
| 137 | 100.00 |
| 141 | 1937.50 |
| 97 | -100.00 |
+----------+---------+
3 rows in set (0.00 sec)
# 查看触发器
mysql> show triggers;
# 删除触发器
mysql> drop trigger if exists upd_check;
# 查看数据库实例中所有触发器
SELECT
a.TRIGGER_SCHEMA,
a.TRIGGER_NAME,
a.ACTION_TIMING,
a.EVENT_OBJECT_TABLE,
a.EVENT_MANIPULATION
FROM
information_schema.`TRIGGERS` a
WHERE
a.TRIGGER_SCHEMA NOT IN ( 'information_schema', 'performance_schema', 'mysql', 'sys' );
delimiter // 设置MySQL执行结束标志,默认为;
上面展示了一些关于触发器的基本操作,其实触发器在生产环境中还是比较少见的,即使它能解决我们某些数据库需求,因为触发器的使用存在一系列的缺点,简要总结几点缺点如下:
- 使用触发器实现的业务逻辑在出现问题时很难进行定位,特别是涉及到多个触发器的情况下,会使后期维护变得困难。
- 大量使用触发器容易导致代码结构被打乱,增加了程序的复杂性,
- 如果需要变动的数据量较大时,触发器的执行效率会非常低。
- 触发器隐式调用容易被忽略,出现问题不好排查。
但是触发器也并不是一无用处,比如我们不想让人删除或更新这个表的数据,可以用触发器实现,下面的一些场景可能对你有所启发:
# 禁止删除数据 即使你有权限
mysql> select * from student;
+--------------+------+--------+-------+-------+
| increment_id | s_id | s_name | s_sex | s_age |
+--------------+------+--------+-------+-------+
| 1 | 1001 | sdfsd | 男 | 18 |
| 2 | 1003 | zsdfsd | 女 | 19 |
+--------------+------+--------+-------+-------+
2 rows in set (0.00 sec)
mysql> delimiter //
mysql> CREATE TRIGGER `tri_delstu` BEFORE DELETE ON `student` FOR EACH ROW begin
-> declare msg varchar(255);
-> set msg="不允许删除学生信息";
-> SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg;
-> end; //
Query OK, 0 rows affected (0.02 sec)
mysql> delimiter ;
mysql> delete from student where s_id = 1003;
ERROR 1644 (HY000): 不允许删除学生信息
# 禁止更新某个字段
mysql> delimiter //
mysql> CREATE TRIGGER trg__updateSid BEFORE UPDATE ON `student`
-> FOR EACH ROW
-> BEGIN
-> DECLARE msg VARCHAR(100);
-> IF NEW.s_id <> OLD.s_id THEN
-> SET msg='不允许修改学号';
-> SIGNAL SQLSTATE 'HY000' SET message_text = msg;
-> END IF;
-> END; //
Query OK, 0 rows affected (0.06 sec)
mysql> delimiter ;
mysql> update student set s_id = 1002 where increment_id = 2;
ERROR 1644 (HY000): 不允许修改学号
# 限制修改范围
mysql> delimiter //
mysql> CREATE TRIGGER `tri_update_age` BEFORE UPDATE ON `student` FOR EACH ROW BEGIN
-> DECLARE msg VARCHAR(20);
-> IF (NEW.s_age<0) THEN
-> set msg="年龄不能小于0";
-> signal sqlstate 'HY000' set message_text=msg;
-> END IF;
-> END; //
Query OK, 0 rows affected (0.02 sec)
mysql> delimiter ;
mysql> update student set s_age=10 where s_id = 1001;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update student set s_age=-10 where s_id = 1001;
ERROR 1644 (HY000): 年龄不能小于0
总结:
本篇文章简要介绍了触发器的定义及使用案例。在业务逻辑复杂或表变动比较频繁的系统还是不推荐使用触发器,当然它也是有自己的应用场景,无论怎样,触发器的逻辑总是越简单越好,我们应该让数据库做它擅长做的事,不能想着所有逻辑都在数据库层面实现。
相关推荐
- 一枚硬币影响亿万美元!独行侠抛硬币胜公牛 最终拿状元签!
-
直播吧05月13日讯公牛记者KC约翰逊报道,公牛因为一枚硬币痛失今年的状元签!事情的具体原因是:独行侠和公牛战绩相同,因此需要抛硬币来决定选秀顺位,随后,独行侠在抛硬币中胜出。最终,独行侠手中的那套...
- 超速移动!假面骑士OOO 全形态数据揭秘:鹰虎豹!顶级的敏捷性!
-
假面骑士OOO是日本特摄剧...
- 旧版一英镑硬币退出流通 英国民众“花钱忙”(图)
-
中新网10月16日电综合报道,英国时间10月15日24时开始,旧版面值1英镑的圆形硬币退出流通,取而代之的是黄色和白色金属构成的12边形硬币组合。根据英国财政部公布的消息,圆形币不再用于支付。资料图...
- 手把手教你如何用硬币得到一个卦象:3分钟学会《易经》
-
本文记录一个普通凡人从零开始学《易经》的点点滴滴。01、《易经》其实很容易《易经》是一部阐述天地世间万象变化的经书,被称作群经之首,智慧之源。...
- 假面骑士OOO 全形态数据揭秘:鹰猩蝗!压倒铠武者怪人的强大力量
-
假面骑士OOO是日本特摄剧...
- 平成假面骑士共有20位,以下是详细介绍:(后10位
-
平成假面骑士共有20位,以下是详细介绍:(后10位)11.《假面骑士W》:-主角:左翔太郎&菲利普。两人是“二人一体”的假面骑士,翔太郎是一个充满正义感的私家侦探,菲利普则拥有极高的智慧和强大的记...
- 盘点3种值钱的一角硬币,拍出48400元!千万别花掉了
-
一角硬币大家都不陌生,前几年又有新的版本的一角出来,这个面值算是我们花的最多的面值了,不过现在购买力下降,已经很少有人用了,你会想过买东西它买不到,但是收藏行业确是个宝一角硬币有兰花一角,铝制内九边一...
- 拍了27万!这三个年份的5分钱硬币,千万别丢掉了
-
硬币收藏也是有很多种类的,有些硬币花样组合也是很有收藏价值目前一元硬币还在使用中,一些面值比较小的分币已经退出流通,基本看不到了很多人收藏是看中了它的收藏价值,像壹分,贰分,伍分硬币这些小的面值已经升...
- 日本造币局“平成31年”硬币套装订购量意外火爆
-
中新网2月18日电据日媒报道,刻有“平成31年”的6种硬币组合而成的日本独立行政法人造币局的硬币套装人气火爆。作为“平成最后的纪念”,来自日本全国的邮购网购订单纷至沓来。虽然订单受理已经结束,但现已...
- 用三枚硬币起卦——如何玩转易经(之一)
-
《易经》是卜筮的书,玩占的方法很多,用三枚硬币起卦,简单实用。第一步:准备三枚一元的硬币(以第四套为例)。纸和笔。第二步:默念或小声说出你要占问的问题。...
- 想要每天被金钱围绕着?英国父子用钱铺地
-
住在英国萨默塞特郡彭斯福德的一对父子为了让新建车库的地面显得特别,决定用一种特殊材料铺地:面值2便士的硬币。为了实现这个“壮举”,55岁的退休老爸多米尼克·洛办了一个烧烤会招待村里人,请他们帮忙贡献面...
- 类似鸡兔同笼的经典数学题(像鸡兔同笼这样的题)
-
龟鹤问题,硬币问题,乘船问题,答题得分问题,买笔问题,租车问题,住宿问题,邮票问题等等都是鸡兔同笼问题,以下作为例题讲解:一,硬币问题硬币问题是鸡兔同笼问题的变形,常见的解题技巧有假设法、方程法等,以...
- 为什么大多数硬币都是圆形的?(硬币为什么设计成圆的)
-
现在世界各国的造币厂在铸造非圆形硬币方面变得相当有创意。特别是对于以高价出售给收藏家的非流通法定货币,你可以找到几乎任何你能想象到的形状的硬币,长方形的,扇形的,梅花形的,心形的......
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)