C C++最全MySQL 触发器_mysql触发器,详解系列文章

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

delimiter ;


成功创建触发器  
 ![image](https://img-blog.csdn.net/20180920155832812?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
   



##### 四、查看触发器


###### 1.查看全部触发器


语法:`show triggers;`  
   



###### 2.查看触发器的创建语句


语法:`show create trigger 触发器名字;`


我们来查看刚才创建的触发器  
 ![在这里插入图片描述](https://img-blog.csdn.net/20180920160023243?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
   



##### 五、触发触发器


基本语法:`drop trigger 触发器名字`


触发不是自动手动触发的,而是在对应的事件发生后才会触发。比如我们创建的触发器,只有在对订单表进行数据操作的时候,触发器才会执行


我们对 orders 表进行数据插入,看看是否触发了触发器  
 ![在这里插入图片描述](https://img-blog.csdn.net/20180920160046199?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 可以看到,在我们对 orders 表进行数据插入的时候,确实 goods 表 id 为 1 的商品的库存发生了改变。但是这是有问题的,即使我们买了 5 个 id 为 1 的商品,对应的 goods 表却只减了 1


如果我们买 5 个 id 为 2 的商品,也只是 goods 表 id 为 1 的商品的发生改变,也是不正确的  
 ![在这里插入图片描述](https://img-blog.csdn.net/20180920160114880?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
   



##### 六、删除触发器


触发器不能修改,只能删除


语法:`drop trigger + 触发器名字`  
 ![](https://img-blog.csdn.net/20180920160128880?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
   



##### 七、触发器应用


触发器针对的是数据库中的每一行记录,每行数据在操作前后都会有一个对应的状态,触发器将没有操作之前的状态保存到 old 关键字中,将操作后的状态保存到 new 中


语法:`old/new.字段名`


需要注意的是,**old 和 new 不是所有触发器都有**




| 触发器类型 | new和old的使用 |
| --- | --- |
| INSERT型触发器 | 没有 old,只有 new,new 表示将要(插入前)或者已经增加(插入后)的数据 |
| UPDATE型触发器 | 既有 old 也有 new,old 表示更新之前的数据,new 表示更新之后的数据 |
| DELETE型触发器 | 没有 new,只有 old,old 表示将要(删除前)或者已经被删除(删除后)的数据 |


我们根据这个重新创建根据订单数据改变自动修改库存的触发器



delimiter ##
– 创建触发器
create trigger after_insert_order after insert on orders for each row
begin
– new 代表 orders 表中新增的数据
update goods set goods_num = goods_num - new.goods_num where id = new.goods_id;
end

delimiter ;


**PS**:对于 auto\_increment 列,new 在 insert 执行之前包括 0,在 insert 执行之后包括新的自动生成的值


这里我们可以根据新插入的 orders 表中的数据来修改 goods 表的库存,此时新插入的数据用 new 来表示  
 ![image](https://img-blog.csdn.net/20180920160147338?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 如果买 5 个 id 为 1 的商品,此时 id 为 1 的商品的库存得到正确的修改。当然,如果买其他种类的商品,最后得到的结果也是正确的,这里就不一一演示了  
 ![](https://img-blog.csdn.net/20180920160203331?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)


**PS**


当然我们还需要考虑一种情况:如果此时商品的库存不够了,该怎么处理?



delimiter ##
– 创建触发器
create trigger before_insert_order before insert on orders for each row
begin
– 取出 goods 表中对应 id 的库存
– new 代表 orders 表中新增的数据
select goods_num from goods where id = new.goods_id into @num;

-- 用即将插入的 orders 表中的库存和 goods 表中的库存进行比较
-- 如果库存不够,中断操作
if @num < new.goods_num then
    -- 中断操作:暴力解决,主动出错
    insert into xxx values(xxx);
end if;

end

delimiter ;


直接创建这个触发器  
 ![](https://img-blog.csdn.net/20180920160222680?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 如果我们买 id 为 3 的商品 100 件,可以看到,此时报错,同时 orders 表和 goods 表的数据并没有得到更新  
 ![](https://img-blog.csdn.net/20180920160234337?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 可以看到,数据连 orders 表都未能插入,那么肯定就不会执行 insert after 这个触发器了


同时,**如果在触发器中出现错误,那么前面的已经执行的操作也会全部清空**  
   



##### 八、其他


###### ① mysql触发器不能对同一张表进行修改操作


假如我在 before update 的时候作一条更新语句,随便将里面哪个字段进行更新



delimiter //
create trigger up before update on orders for each row
begin
update orders set goods_id = 10 where id = new.id;
end;
//
delimiter ;


触发器创建成功  
 ![](https://img-blog.csdn.net/20180920160257444?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 接下来我用 update 语句对 orders 表进行更新  
 ![](https://img-blog.csdn.net/20180920160307971?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhYnljYW41/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)  
 此时报错了,提示不能进行更新。之后,我又尝试在触发器中进行 insert 和 delete 操作,之后更新的时候还是报同样的错误


因此说明:**MySQL 的触发器中不能对本表进行 insert、update 和 delete 操作,否则会报错**  
   



##### 九、优缺点


###### 优点



![img](https://img-blog.csdnimg.cn/img_convert/c3006755cc5d68936d58a01cbf0127b9.png)
![img](https://img-blog.csdnimg.cn/img_convert/310e0e9b95535bda788db8cb1a57816b.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值