有时会碰到表的某些数据改变,希望同时引起其他相关数据改变的需求,利用触发器就可以满足这样的需求。
它能在表中的某些特定数据变化时自动完成某些查询。
运用触发器不仅可以简化程序,而且可以增加程序的灵活性。
* 触发器是一类特殊事务,可以监视某种数据操作(insert、update、delete),并出发相关操作(insert、update、delete)
触发器创建语法
4要素
监视地点(table)
监视事件 insert、update、dalete
触发时间 after、before
触发事件 insert、update、dalete
* 触发器引用行变量
insert new 新行 (监控新增的一条数据)
delete old 旧行 (监控删除的一条数据)
引用
new.字段名
old.字段名
update old->new 改前到改后 (监控修改一条数据)
查看触发器:
show triggers
删除发触发:
drop trigger triggerName
触发器 trigger:
需求:
商品表: goods
订单表: ord
当有新订单、修改订单、删除订单操作时,对应的商品要相应减少(买几个商品就少几个库存)
分析:
操作:新订单
监视:ord
监视动作:insert
触发时间:after
触发事件:update
操作:删除订单
监视:ord
监视动作:delete
触发时间:after
触发事件:update
操作:修改订单
监视:ord
监视动作:update
触发时间:before
触发事件:update
创建表
CREATE TABLE `ord` (
`oid` int(10) NOT NULL auto_increment,
`gid` int(10) DEFAULT NULL,
`much` int(10) DEFAULT NULL,
PRIMARY KEY (`oid`)
);
CREATE TABLE `goods` (
`gid` int(11) NOT NULL auto_increment,
`name` varchar(20) DEFAULT NULL,
`num` smallint(6) DEFAULT NULL,
PRIMARY KEY (`gid`)
);
insert into goods values(1,'cat',34),(2,'dog',65),(3,'pig',21);
触发器
//设置mysql定界符为$ 因为begin里的sql用';'结尾。 如多行情况下,让mysql分开每条sql语句,而不结束
delimiter $
//有新订单时
create trigger ordAdd
after insert
on ord
for each row
begin
update goods set num = num-new.much where gid = new.gid;
end$
//删除订单时
create trigger ordDel
after delete
on ord
for each row
begin
update goods set num = num+old.much where gid = old.gid;
end$
//改订单时
create trigger ordUp
before update
on ord
for each row
begin
update goods set num = num+old.much-new.much where gid = old.gid;
end$
# 思考: before目前似乎没有看出与after的区别
# 再思考: 如果剩余3头猪,但客户买了10头,发生什么情况?能否预防?
# 能否在购买量much > 库存量num时,把much自动改为num
# 提示 before
create trigger ordAdd
before insert
on ord
for each row
begin
declare //声明变量
rnum int; //变量rnum为INT型
//将查询出来的num赋给变量rnum
select num into rnum from goods where gid = new.gid;
//判断
if rnum < new.much then
set new.much = rnum;
end if
update goods set num = num-new.much where gid = new.gid;
end$
# 触发器(trigger)中 for each row 是什么意思
在oracle触发器中,触发器份语句级触发器和行级触发器。
for each row 是行级触发器
例如
after|before update
update影响了100行数据,那么sqlN会被触发100次。
在oracle中 for each row 如果不写,无论update语句一次影响了多少行数据,都只执行1次。
比如:1人下了订单,买了5件商品,insert 5次,可以用行级触发器修改5次库存。
用语句触发器,insert一条发货提醒。
遗憾的是 mysql目前不支持语句触发器。
所以在mysql触发器(trigger)中for each row必须写。
如何查看mysql的触发器 mysql触发器监控字段变化
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章