第一章: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]