触发器(trigger)
触发器(trigger)是个特殊的存储过程,它的调用不是由程序员调用,而是由事件触发的。比如insert --> 触发 update 操作。
触发器可以用来监视某表的变化。当发生变化时,触发某个操作。
应用场景,一般用在业务逻辑不可分割的场景。比如下了订单,库存就必须减少。相当于这些操作是原子的。
触发器能监视:增、删、改
触发操作:增、删、改
触发器的创建要素:
(1)
监视地点 table
(2)
监视事件 insert/update/delete
(3)
触发时间 after/before
(4)
触发事件 insert/update/delete
创建触发器语法:(for each row是因为mysql不支持表触发,orcale可以不用for each row)
create trigger triggername after/before insert/update/deleteon 表名 for each row
begin sql语句; end; #sql语句可以是一句或多句
由于sql语句后面有分号’;',所以在运行触发器前需要把语句终止符';'改为其他,例如
delimiter $ 将$改为终止符,注意不要有;号,否则终止符会改为$;
删除触发器: drop trigger triggername:
显示触发器:show triggers;
触发器中引用行的值
触发器对于sql语句是固定的,那么如何在触发器中引用行的值?
对于insert而言,新增的行,用new表示,行中每一列的值,用new.列名来表示。
例如:
增加insert订单,举例:
#监视地点 o表
#监视事件 delete
#触发事件 update
#触发时间 after
mysql> create trigger tg2
-> after insert on o
-> for each row
-> begin
-> update g set num=num-new.much where id=new.gid; #注意new来引用新的行, new.列名就是新的列的值
-> after insert on o
-> for each row
-> begin
-> update g set num=num-new.much where id=new.gid; #注意new来引用新的行, new.列名就是新的列的值
-> end$
#监视地点 o表
#监视事件
#触发事件
#触发时间
create trigger tg3 after delete on o for each row begin
update g set num=num+old.much where id=old.gid; end$ #注意
old.列名用来引用删除行的值
修改update订单,举例:
被修改的行,
修改前的数据,用old来表示,
old列名引用被修改之前行中的值
修改后的数据,用new来表示,
new.列名可以引用被修改之后的行中的值
mysql> create trigger tg4
-> after update on o
-> for each row
-> begin
-> update g set num = num+old.much-new.much where id = old.gid;
-> end$
-> after update on o
-> for each row
-> begin
-> update g set num = num+old.much-new.much where id = old.gid;
-> end$
触发器里after和before的区别:
after是先完成数据的增删改,再触发。触发的语句晚于增删改,无法影响前面的增删改工作。
brfore是先完成触发,再增删改。触发的语句先于监视的增删改发生,我们有机会判断修改即将发生的操作。
典型案例:
对于所下订单进行判断,如果订单的数量>5,就认为是恶意订单,强制把锁定的商品数量改成5。
mysql> create trigger tg5
-> before
-> insert on o
-> for each row
-> begin
-> if new.much > 5
-> then set new.much = 5;
-> end if;
-> update g set num=num-new.much where id=new.gid;
-> end$
-> before
-> insert on o
-> for each row
-> begin
-> if new.much > 5
-> then set new.much = 5;
-> end if;
-> update g set num=num-new.much where id=new.gid;
-> end$