一、基本概念

触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的,即不是主动调用而执行的;而存储过程则需要主动调用其名字执行

触发器:trigger,是指事先为某张表绑定一段代码,当表中的某些内容发生改变(增、删、改)的时候,系统会自动触发代码并执行。

二、作用

可在写入数据前,强制检验或者转换数据(保证护数据安全)
    触发器发生错误时,前面用户已经执行成功的操作会被撤销,类似事务的回滚

三、创建触发器

基本语法

delimiter 自定义结束符号
create trigger 触发器名字 触发时间 触发事件 on 表 for each row
begin
    -- 触发器内容主体,每行用分号结尾
end
自定义的结束符合

delimiter ;

1
    2
    3
    4
    5
    6
    7
    8

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

触发时间

当 SQL 指令发生时,会令行中数据发生变化,而每张表中对应的行有两种状态:数据操作前和操作后

before:表中数据发生改变前的状态
    after:表中数据发生改变后的状态

PS:如果 before 触发器失败或者语句本身失败,将不执行 after 触发器(如果有的话)

触发事件

触发器是针对数据发送改变才会被触发,对应的操作只有

INSERT
    DELETE
    UPDATE

注意事项

在 MySQL 5 中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一,即同一数据库中的两个表可能具有相同名字的触发器
    每个表的每个事件每次只允许一个触发器,因此,每个表最多支持 6 个触发器,before/after insert、before/after delete、before/after update

例子

1.首先创建两张表,商品表和订单表

2.如果订单表发生数据插入,对应的商品库存应该减少。因此这里对订单表创建触发器

语法

delimiter ##
-- 创建触发器
create trigger after_insert_order after insert on orders for each row
begin
    -- 更新商品表的库存,这里只指定了更新第一件商品的库存
    update goods set goods_num = goods_num - 1 where id = 1;
end
##

delimiter ;

1
    2
    3
    4
    5
    6
    7
    8
    9
    10

成功创建触发器
image

四、查看触发器
1.查看全部触发器

语法:show triggers;

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

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

我们来查看刚才创建的触发器
在这里插入图片描述

五、触发触发器

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

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

我们对 orders 表进行数据插入,看看是否触发了触发器
在这里插入图片描述
可以看到,在我们对 orders 表进行数据插入的时候,确实 goods 表 id 为 1 的商品的库存发生了改变。但是这是有问题的,即使我们买了 5 个 id 为 1 的商品,对应的 goods 表却只减了 1

如果我们买 5 个 id 为 2 的商品,也只是 goods 表 id 为 1 的商品的发生改变,也是不正确的
在这里插入图片描述

六、删除触发器

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

语法:drop trigger + 触发器名字

七、触发器应用

触发器针对的是数据库中的每一行记录,每行数据在操作前后都会有一个对应的状态,触发器将没有操作之前的状态保存到 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 ;

1
    2
    3
    4
    5
    6
    7
    8
    9

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

这里我们可以根据新插入的 orders 表中的数据来修改 goods 表的库存,此时新插入的数据用 new 来表示
image
如果买 5 个 id 为 1 的商品,此时 id 为 1 的商品的库存得到正确的修改。当然,如果买其他种类的商品,最后得到的结果也是正确的,这里就不一一演示了

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 ;

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

直接创建这个触发器

如果我们买 id 为 3 的商品 100 件,可以看到,此时报错,同时 orders 表和 goods 表的数据并没有得到更新

可以看到,数据连 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 ;

1
    2
    3
    4
    5
    6
    7

触发器创建成功

接下来我用 update 语句对 orders 表进行更新

此时报错了,提示不能进行更新。之后,我又尝试在触发器中进行 insert 和 delete 操作,之后更新的时候还是报同样的错误

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

九、优缺点
优点

触发器可以通过数据库中的关联表实现级联更改,即一张表数据的改变会影响其他表的数据
    可以保证数据安全,并进行安全校验

缺点

过分依赖触发器,影响数据库的结构,增加数据库的维护成本

十、参考

https://blog.csdn.net/chl191623691/article/details/79607761
https://blog.csdn.net/qq_35246620/article/details/78946070
https://www.cnblogs.com/phpper/p/7587031.html

【MYsql触发器】相关推荐

  1. 利用MySQL触发器实现check和assertion

    MySQL虽然输入check语句不会报错,但是实际上并没有check的功能.但是MySQL 依然可以利用触发器来实现相应功能. 本文将根据两个例子简要阐述MySQL实现check和assertion的 ...

  2. MySQL 触发器应用案例

    网友问题:对于MySQL主从复制结构中,如何让Slave过滤delete操作. 问题分析:该问题对应的是保全所有的记录,包括delete的记录. 对于MySQL本身的过滤规则粒度是精确到表的粒度. 主 ...

  3. mysql latid1_【转】mysql触发器的实战经验(触发器执行失败,sql会回滚吗) | 学步园...

    1   引言Mysql的触发器和存储过程一样,都是嵌入到mysql的一段程序.触发器是mysql5新增的功能,目前线上凤巢系统.北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本,很多程 ...

  4. mysql利用触发器删除数据库_[数据库]mysql 触发器的创建 修改 删除

    [数据库]mysql 触发器的创建 修改 删除 0 2015-12-16 23:00:04 //做一个简单的练习,创建一个简单的触发器 完成添加文章的时候,自动加上时间,默认作者 为 '日记本的回忆' ...

  5. mysql 触发器学习

    mysql 触发器学习 1. 一个简单的例子 1.1. 创建表: create table t(s1 integer); 1.2. 触发器: delimiter | create trigger t_ ...

  6. mysql 触发器 分行_mysql 触发器

    mysql 触发器中有两个insert 语句 第二个inert 要用第一个insert 的结果怎么实现 DELIMITER $$ USE `nightclub`$$ DROP TRIGGER /*!5 ...

  7. mysql触发器 存储过程_mysql触发器和存储过程

    Mysql触发器和存储过程 1 / 9Mysql触发器 1.语法:命名规则 CREATE TRIGGER { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ...

  8. mysql之触发器详解_学习笔记之MySQL触发器详解

    触发器是由事件来触发某个操作,这些事件包括INSERT语句,UPDATE语句和DELETE语句 创建触发器 创建只有一个执行语句的触发器 CREATE TRIGGER 触发器名 BEFORE|AFTE ...

  9. MySql 触发器同步备份数据表记录

    添加记录到新记录表 DELIMITER $$ USE `DB_Test`$$ CREATE/*!50017 DEFINER = 'root'@'%' */TRIGGER `InsertOPM_Alar ...

  10. mysql触发器 while循环_mysql触发器跳出当前循环方法

    mysql触发器跳出当前循环方法 set @num=@UnitLength/3; label: while i set @length=(select SUBSTRING(@unit_sid_fk,1 ...

最新文章

  1. mysql元数据死锁日志_这个未修复的MySQL 5.7死锁Bug,你知道么?
  2. 【整理】RPA选择器针对SAP系统的设置
  3. angularjs $watch
  4. Kubernetes系列之Helm介绍篇
  5. 两台邮件服务器共用一个公网地址,两个不同域邮件服务器的互通
  6. Html5不允许修改但允许赋值,JavaScript | 引用类型变量的赋值问题
  7. mysql+win10+64位安装步骤_win10 安装 mysql解压版安装步骤
  8. 「兼容M1」iZotope RX 9 Advanced for Mac - 音频修复工具
  9. Nexus max file descriptors
  10. 绝对受用的求职经验分享
  11. Java位运算优化:位域、位图棋盘等
  12. Pytnon画一个小猪佩奇
  13. 【深信服】Python 开发工程师(云计算、网络安全) 【已offer】
  14. Python——绑定与方法调用
  15. 「历时6个月招聘数据收集」一份Python招聘分析报告
  16. Teams app 的 SSO 机制
  17. 求部门最高工资(Mysql多表查询)
  18. linux 安装snap7,基于linux7的ectd安装与部署
  19. Spring及Springboot IOC与AOP思考
  20. Mysql 慢日志查询小于1000ms显示0s问题排查

热门文章

  1. 【20180128】【matlab】均值、标准差、方差、协方差、中值的求解
  2. VR全景制作的展示方式你了解多少?具体有哪些?
  3. 比 Elasticsearch 更快, RediSearch + RedisJSON = 王炸
  4. 亚洲“印度河水塔”是受依赖度最高、最为脆弱的高山系统
  5. Python爬虫 --- Scrapy爬取IT桔子网
  6. 211毕业生3天被辞退:offer不等于工作稳了!
  7. Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)
  8. Redis缓存穿透、击穿、雪崩、概念及解决办法
  9. Android毛玻璃效果实现
  10. 软件开发视频资源分享