触发器(trigger)
作用:监视某种情况并触发某种操作。
触发器定义:进行数据库应用软件的开发时,我们有时会碰到表中的某些数据改变,希望同时引起其他相关数据的改变的需求,利用触发器就能满足这样的需求。
它能在表中的某些特定数据变化时自动完成某些查询。运用触发器不仅可以简化程序,而且可以增加程序的灵活性。
触发器是一类特殊的事务:可以监视某种数据操作(insert/update/delete),并触发相关操作(insert/update/delete )。
触发器应用场合:
1.当向一张表中添加或删除记录时,需要在相关表进行同步操作。如:当一个订单产生时,订单所购的商品库存应相应减少。
2.当表上某列数据的值与其他表中的数据有联系时。如:当某客户进行欠款消费,可以在生成订单时通过设计触发器判断该客户的累计欠款是否超出了最大额度。
3.当需要对某张表进行跟踪时。如:当有新订单产生时,需要及时通知相关人员进行处理,此时可以在订单表上设计添加触发器加以实现。
触发器的四要素:
监视地点(table),监视事件(insert/update/delete),触发时间(after/before),触发事件(insert/update/delete)
创建触发器语法:
create trigger 触发器名称
after/before(触发时间)
insert/update/delete(触发事件)
on 表名(监视地址)
for each row--此句在MySQL中是写死的,只有行触发器,在oracle中还有表触发器
begin
sql1
...
sqlN
end;
触发器举例:
需求:
商品表:goods
订单表:ord
当下一个订单时,对应的商品要相应减少(买几个商品减少几个库存)、
分析:
监视谁:ord
监视动作:insert
触发时间:after
触发事件:update
create trigger t1
after
insert
on ord
for each row
begin
update goods set num=num-2 where gid=1;
end;
深入分析会发现,该触发器所有数据写死,每次不管买任何商品,都只会减少gid=1的商品。
如何在触发器引用行的值
对于insert而言,新增的行用new来表示;行中的每一列的值,用new.列名来表示。
对于delete而言,删除的行用old来表示,行中的每一列的值,用old.列名来表示。
对于update而言,被修改的行,修改前的数据用old来表示,old.列名引用被修改前的行中的值;修改后的数据用new来表示,new.列名引用被修改后的行中的值。
举例升级:
create trigger t1
after
insert
on ord
for each row
begin
update goods set num=num-new.much where gid=new.gid;
end;
注意:老版本的MySQL默认遇到分号结束,如上写法会提示错误,需要先用delimite $将默认分号结束改成功“$”结束(当然也可改成其他结束符),然后end后面跟$即可,begin后的语句仍用分号结束即可。
删除触发器语法:drop trigger 触发器名;
查看所有触发器:show triggers;
before与after的区别
after是先完成数据的增、删、改,再触发。意味着无法影响前面的增删改。
before是先完成触发,再进行数据的增、删、改。触发的语句先于监视的增删改发生,意味着我们有机会审查、判断、修改即将发生的操作。
典型案例:
对于所下订单进行判定,若订单数量>5则认为是恶意订单,强制将订单数量改成5.
实现结果: