第一章:mysql触发器 1.所谓触发器,就是指设置好某个表的某个操作[insert ,update ,delete]时候,同时触发的一个操作[insert,update,delete] 使用场景:比如商城订单操作,当用户完成下单操作后,需要对商品表进行库存减一操作,这时候我们可以采用PHP来做相应的逻辑处理,但如果是使用mysql触发器来操作,就可以节省我们写PHP逻辑代码的时间 我们如果要深入理解mysql触发器,必须掌握触发器的四要素: **1.监控的表[数据库中的某张表]** **2.监视的事件[某张表表的insert,update,delete操作]** **3.触发时间在 insert,update,delete 等操作前还是操作后** **4.需要触发的事件[insert,update,delete]** 基本格式: ``` delimiter $$ --delemiter:声明定界符为 $$ create trigger orderMinusOne --创建一个触发器:orderMinusOne触发器名称 after|before --触发时间 insert|delete|update --监听的事件 on tabName --监听的表 for each row --行级触发器。mysql不支持语句触发器,所以必须写for each row,每行受影响,触发器都执行 begin --开始 xxx #SQL语句 end $$ --结束 delimiter; ``` 一个栗子:模拟商品下单场景,用户下单成功之后,根据购买数量相应的商品表商品数量减去购买数。 商品表: ``` SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for tb_goods -- ---------------------------- DROP TABLE IF EXISTS `tb_goods`; CREATE TABLE `tb_goods` ( `goods_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id', `goods_num` int(11) unsigned NOT NULL COMMENT '商品数量', `goods_price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品价格', `goods_name` varchar(255) NOT NULL DEFAULT '' COMMENT '商品名', `is_rease` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否发布,0发布,1不发布', PRIMARY KEY (`goods_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; 订单表: SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for tb_order -- ---------------------------- DROP TABLE IF EXISTS `tb_order`; CREATE TABLE `tb_order` ( `order_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单id', `goods_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '订单id', `buy_num` int(11) NOT NULL DEFAULT '0' COMMENT '购买个数', `order_number` varchar(19) NOT NULL DEFAULT '' COMMENT '订单编号', `is_valid` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否有效,0有效,1无效', PRIMARY KEY (`order_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; ``` 因为触发器会监视mysql的insert,delete,update等操作,所以如果表中新增一列或者减少一列都会被记录,如果需要找到新增列[insert]的字段字,可以使用 new.字段 表示,相应的减少列[delete]操作可以用 old.字段表示。 创建触发器: ``` delimiter $$ --delemiter $$ 声明定界符为 delimiter create trigger orderMinusOne --创建一个触发器:orderMinusOne触发器名称 after --触发时间 insert --监听的事件 on tb_order --监听的表 for each row begin --开始 update tb_goods set goods_num = goods_num - new.buy_num where goods_id = new.goods_id -- 商品表商品数量减去购买数量的值 end $$ --以 $$ 分隔符结束 delimiter; ``` 注:对于insert操作,只能使用new.字段,对于delete操作,只能使用old.字段,而update操作,old.字段,new.字段都可以使用 ``` 查看我们创建的触发器: show triggers; ``` ``` 删除触发器命令: drop trigger triggerName; ``` 当然,这只是一个简单的栗子,实际应用场景要比这复杂的多,比如,如果库存字段我们没有设置为非负数极可能出现超卖的情况。除了逻辑代码与限制字段非负,用触发器我们同样也可以实现。 一个符合生产情况的栗子: ``` delimiter $$ --delemiter $$ 声明定界符为 delimiter create trigger orderMinusOne --创建一个触发器:orderMinusOne触发器名称 before --触发时间 insert --监听的事件 on tb_order --监听的表 declare goodsnum int --declare 声明一个int类型的goodsnum的变量,用于后续存储查询出来的变量 for each row begin --开始 select goods_num into goodsnum from tb_goods where goods_id = new.goods_id --将商品表的库存查询出来赋值给goods_num if new.buy_num > goodsnum then --判断,如果购买数量大于库存量的话 set new.buy_num = goodsnum --让购买数量等于库存量 end if update tb_goods set goods_num = goods_num - new.buy_num where goods_id = new.goods_id --执行商品表库存减操作 end $$ delimiter; ``` [TOC] [TOC] [TOC]