数据库触发器

触发器 trigger
	创建create trigger t1
	删除drop trigger t1
	查看show triggers \G
需求
商品表goods
订单表prd

当下一个订单 对应商品相对减少(买几个少几个

分析
监视谁 prd
监视动作 insert
触发时间 after
触发事件 update

create trigger t1
after
insert
on prd
for each row
begin
update goods xxxxx
end;

创建表
create table goods(
	gid int,
	name varchar(20),
	num smallint
);

create table prd(
	pid int,
	gid int,
	much smallint
);

创建数据
insert into goods values
(1,'cat',34),
(2,'dog',65),
(3,'pig',21);

insert into prd values(1,1,2);

创建触发器(	加$符号使数据库识别该语句为不分行)
delimiter $
create trigger t1
after
insert
on prd
for each row
begin
update goods set num=num-2 where gid=1;
end$
问题:为什么买什么都减少两只猫呢
答案:因为触发器减少的gid=1,这里要动态引入变量

(增加)触发器引入变量new
delimiter $
create trigger t2
after
insert
on prd
for each row
begin
update goods set num=num-new.much where gid=new.gid;
end$

(删除)触发器引入变量old
delimiter $
create trigger t3
after
delete
on prd
for each row
begin
update goods set num=num+old.much where gid=old.gid;
end$

(更改)触发器引入变量old
delimiter $
create trigger t4
before
update
on prd
for each row
begin
update goods set num=num+old.much-new.much where gid=new.gid;
end$

思考:before和after的区别
	  如果剩余3头猪,但客户下单买10头,会发生什么情况?(会爆仓 库存变为负数)怎么防止?
	  能否在购买量much>库存量num时,把much自动改为num(使用before)

在t2基础上完成much和num的判断
create trigger t5
after
insert
on prd
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$	
这样会报错:
Updating of NEW row is not allowed in after trigger
原因:insert之后,new行已经插入到表中,已经成为事实,改new已经来不及了

在t5基础上,继续改进
create trigger t6
before
insert
on prd
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$

在触发器中 for each row是干嘛的
在Oracle触发器中,触发器分语句级触发器,和行级触发器(每一行受影响,触发器都执行)
比如
create trigger th
after update
on xxtable
for each row
begin 
	sqlN
end$
当执行:update xxtable set xxx=xxx where id>100;
那么sqlN会被触发100次

在Oracle中for each row如果不写
无论update语句执行多少行,都执行一次

  

posted @ 2018-07-28 07:43  TangYJun  阅读(233)  评论(0编辑  收藏  举报