时间:2021-07-01 10:21:17 帮助过:17人阅读
触发器(trigger)是MySQL提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作(insert,delete, update)时就会激活它执行。简单理解为:你执行一条sql语句,这条sql语句的执行会自动去触发执行其他的sql语句。
- 可在写入数据表前,强制检验或转换数据。
- 触发器发生错误时,异动的结果会被撤销。
- 部分数据库管理系统可以针对数据定义语言(DDL)使用触发器,称为DDL触发器。
- 可依照特定的情况,替换异动的指令 (INSTEAD OF)。
- 监视地点(table)
- 监视事件(insert、update、delete)
- 触发时间(after、before)
- 触发事件(insert、update、delete)
语法:
before/after: 触发器是在增删改之前执行,还是之后执行
delete/insert/update: 触发器由哪些行为触发(增、删、改)
on 表名: 触发器监视哪张表的(增、删、改)操作
触发SQL代码块: 执行触发器包含的SQL语句
1CREATE TRIGGER 触发器名
2BEFORE|AFTER DELETE|INSERT|UPDATE
3ON 表名 FOR EACH ROW
4BEGIN
5触发SQL代码块;
6END;
注意: 触发器也是存储过程程序的一种,而触发器内部的执行SQL语句是可以多行操作的,所以在MySQL的存储过程程序中,要定义结束符。
如果MySQL存储过程不了解的小伙伴,可以参考此文面向MySQL存储过程编程,文章中详细讲解了MySQL存储过程的优势和语法等等,相信你会在其中得以收获。
1# 设置MySQL执行结束标志,默认为;
2delimiter //
首先,我先展示一下创建的两张表,因为创建的表很简单,这里我没有提供库表操作的SQL命令。
tb_class
employee
其次,创建了一个含有update操作的存储过程
1delimiter //
2create procedure update_emp(in i int, in p int)
3begin
4 update employee set phone = p where id = i;
5end //
再创建一个触发器
分析: 触发器名称为t1,触发时间为after,监视动作为update,监视表为employee表。汇总一起解释这个触发器就是:创建一个触发器名称为t1的触发器,触发器监视employee表执行update(更新)操作后,就开始执行触发器内部SQL语句
update tb_class set num = num + 1 where id = 1;
。简单来说就是一个监视一个表的增、删、改操作并设置操作前后时间,在设置时间的范围内对另外一个表进行其他操作。
如果你学到这里还是一知半解,后面我会讲解一个订单与库存的数据关系,到那时候你就会明白了!
1delimiter //
2# 创建触发器,触发器名称为t1
3create trigger t1
4 # 触发器执行在update操作之后
5 after update
6 # 监视employee表
7 on employee
8 for each row
9begin
10 # 触发执行的SQL语句
11 update tb_class set num = num + 1 where id = 1;
12end //
最后调用函数,并查看、分析结果
1call update_emp(2, 110);
触发器在此场景的作用分析
当employee表发生update操作时,触发器就对tb_class表中的num值做修改。
执行结果发现,我们在使用函数将employee表中id为2员工的phone修改为110后,触发器监视到employee表中发生了update更新操作,就执行了内部SQL语句,也就是将tb_class表中id为1的num值自增1。
查看已有触发器:
show triggers
删除已有触发器:
drop trigger 触发器名称
这里扩展,在oracle触发器中,触发器分为行触发器和语句触发器。也就是说,假设你监视一个修改操作,它修改了1000行代码,在Oracle中触发器会触发1000次。
在oracle中,for each row如果不写,无论update语句一次影响了多少行,都只执行一次触发事件。
而MySQL中,不支持语句级触发器,所以在MySQL中并不需要在意。
订单与库存的关系: 用户下订单,意味着创建该商品订单,该商品订单中的商品数量为1,库存中的该商品数量-1。往往订单表和库存表中的数量是同时操作的,所以我们这里可以用触发器。
触发器应用: 关于订单表,下订单肯定是涉及到insert插入数据数量的操作。我们可以创建一个监视订单表insert操作后执行库存表数量-1的触发器来完成订单与库存表的同时修改。
创建表,并在表中添加几条数据:
1create table goods(
2 gid int,
3 name varchar(20),
4 num smallint
5);
6create table ord(
7 oid int,
8 gid int,
9 much smallint
10);
11insert into goods values(1,‘cat‘,40);
12insert into goods values(2,‘dog‘,63);
13insert into goods values(3,‘pig‘,87);
创建触发器
1create trigger t1
2after
3insert
4on ord
5for each row
6begin
7 update goods set num = num - 1 where gid = 1;
8end$
该触发器意为,用户不管下什么订单,都会把商品编号为1的商品的库存减去1。
- 在触发目标上执行insert操作后会有一个新行,如果在触发事件中需要用到这个新行的变量,可以用new关键字表示
- 在触发目标上执行delete操作后会有一个旧行,如果在触发事件中需要用到这个旧行的变量,可以用old关键字表示
- 在触发目标上执行update操作后原纪录是旧行,新记录是新行,可以使用new和old关键字来分别操作