触发器的相关知识

作者:掠影
最后编辑时间:2017-07-03 18:15:15
浏览次数:1561



    近来在项目中遇到了一些问题:例如对某条订单,在查询时出现了订单状态从4变为3的情况;然而在正常的业务流程中,订单状态可能且仅可能递增变化;在查询了API之后,才发现原来是因为某个外部API在批量更新订单状态时,出现了强制更新订单状态为3的情形;

    这种问题,一般是业务逻辑设计上的误区,常见的解决问题方法大致有两种:

        1. 根据开闭原则,将所有的数据库操作均集成为一个连接器,并且在连接器中规定状态更新无法逆向(即更新前进行状态检查)

        2. 设置一个触发器,在before update时检查原有状态和新状态的大小,在错误时执行某条错误SQL


    下面主要来说下第2条,即触发器相关的知识:

    首先下面是一个触发器的例子

DELIMITER $
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int;
set c = (select stuCount from class where classID=new.classID);
update class set stuCount = c + 1 where classID = new.classID;
end$
DELIMITER ;

其中,DELIMITER 用于声明触发器的截断符号,常用$,//之类的特殊符号

tri_stuInsert为触发器名,随意

after insert 为触发场景,在MySQL中,触发场景主要由Before, after 两种时机和INSERT DELETE UPDATE三种情况,自由组合即有六种触发器场景

begin …… end这部分为代码块,主要为触发器的逻辑部分,在end后用DELIMITER中声明的截断符号

    其中,对于insert情况,我们用new来代表即将插入的这一行,比如new.auto_id即为新插入一行的auto_id属性,从而进行针对性的处理;

    而对于UPDATE和DELETE,有old代表被操作的这一行,如通过old.auto_id来判断其他值,从而处理。


在实际应用中,如文章开头所述的状态更改情况,即可通过如下的触发器来解决对应问题(before update)

begin

IF old.status > new.status  THEN
INSERT INTO test (auto_id,content) VALUES(1,"233");//无法执行的语句,auto_id已被占用
END IF;

end

其中,当old.status > new.status的时候,就执行一条不可能会被通过的语句来手动报错,从而阻止这条UPDATE的运行,反之则正常UPDATE

以上即为触发器的基础知识和应用,谢谢


取消

感谢您的支持,我会继续努力的!关闭

扫码支持
大家有钱的捧个钱场,没钱的捧个人场233333

打开支付宝扫一扫,即可进行扫码打赏哦

分享到: QQ空间 更多



评论区