mysql 触发器 new.much_MySQL触发器

触发器是一类特殊的事务,可以监视某种数据操作(insert,update,delete),并触发相关操作(insert,update,delete)

触发器创建之四要素:

监视地点

(table)

监视事件

(insert,update,delete)

触发时间

(after,before)

触发事件

(insert,update,delete)

举个例子,有两张表,分别是商品表goods和订单表ord

当下一个订单的时候,对应的商品要相应减少(买几个商品就少几个库存)

分析:

监视谁:ord

监视动作:insert

触发时间:after

触发事件:update

那么就来写创建触发器的语法:

delimiter $     (这是指定程序碰见$才结束,而不是以分号结束)

create trigger 触发器名称

after/before(触发时间)

insert/update/delete(监视事件)

on 表名(监视地址)

for each row

begin

sql1;

...

sqlN;

end $

---------------------

我们可以看到我们的商品表已经创建好了:

0808201987f97804b43adc2f084357o.png

然后我们下订单:

我想买3只猫,那么我们用触发器来实现这个操作:

create trigger t2

after

insert

on ord

for each row

begin

update goods set num=num-new.much where gid=new.gid;

end$

080820194085eba354c6ed6a084358o.png

我们可以看到订单表是空的,然后我们给里面插入数据:

08082019d6f9b9677231aa74084358o.png

然后我们去看看商品表里面的库存变了没:

0808201954050a58965abbb5084358o.png

我们可以看到猫的库存确实减少了三只

那我们想删除一个订单,退货,那么库存就应该再加回去,应该怎么做?

我们新建一个触发器,监视删除订单的操作:

create trigger t3

after

delete

on ord

for each row

begin

update goods set num=num+old.much where gid=old.gid;

end$

080820191506c20801f246e8084358o.png

上面是原来的订单和库存,下面是我们执行删除订单后的数据,没有任何问题:

08082019e410381c5112044b084358o.png

---------------------

那我们想修改订单,我们想把上面的订单买的猫数量改一下:我想买1只猫,三只猫太多了养不过来。

那我们建立一个新的触发器来监视订单的修改:

create trigger t4

before

update

on ord

for each row

begin

update goods set num=num+old.much-new.much where gid=new.gid;

end$

08082019dddf810d4809b26d084358o.png

这是改订单之前我们的库存。

然后我们来改订单:

update ord set much=1 where oid=1$

080820197725b97f239b6740084358o.png

我们可以看到猫的数量变成了33,这证明我们写的触发器没有问题。

---------------------------------

那么我们再思考,如果购买的数量超过库存应该怎么办?能不能预防?

假设我们有个大客户他下了一个订单想买25头猪:

我们增加一个订单:

insert into ord values(2,3,25)$

08082019f287b1066bdd040c084358o.png

我们看到这个订单确实被增加进去了,但是库存呢?

08082019be3c538c3775a610084358o.png

我们看到这个猪的库存变成了-4,这种情况叫爆仓,这是不允许发生的,那么我们怎么预防它?

我们建立一个判断,如果new.much的值>num,那么我们把new.much=num

我们把原来的t2触发器删掉,新建一个t5触发器:

create trigger t5

before

insert

on ord

for each row

begin

declare

rnum int;

select num into rnum from goods where gid=new.gid;

if new.much>rnum then

set new.much=rnum;

end if;

update goods set num=num-new.much where gid=new.gid;

end$

注意一定要用before,否则会报下面的错误:

08082019a042452fed95a92f084358o.png

080820191f0b0f4acfbcc526084358o.png

这是我们的库存,接下来我们生成一个订单,买25头猪:

08082019b27bf56de5bc18e5084358o.png

我们可以看到库存已经为0;

0808201947a1430cda3d1389084358o.png

订单表也显示只买了21头猪。

这证明我们的触发器确实发挥了作用。

然后我们看到我们的触发器语句里面有for each row,那么它是干啥的?

举个例子:

我们建立一个新表:

0808201927f47632c729243e084358o.png

我们创建一个触发器:每当ord的数据被修改,我们就往tmp表插入一个5

create trigger t9

after

update

on

ord

for each row

begin

insert into tmp values(5);

end$

0808201988f04e3a8c176785084359o.png

0808201947a1430cda3d1389084358o.png

我们看到我们的tmp现在是空的,我们接下来修改ord表中的值:

08082019ebef426dec79881084359o.png

然后我们去看看tmp表有何变化:

08082019fc67d64d02dd78b9084359o.png

我们可以看到tmp表一次被增加了两条数据。

这就是for each row的作用:它是声明 每一行受影响,触发器都触发一次,这种触发器也叫行级触发器。mysql暂时不支持语句级触发器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值