mysql触发器之创建多个触发器操作实例分析
本文实例讲述了mysql触发器之创建多个触发器操作。分享给大家供大家参考,具体如下:
这次记录的内容mysql版本必须得是5.7.2+的哈,之前的会不好使的。废话不多说,咱们开始正文哈。
在mysql5.7.2+版本之前,我们只能为表中的事件创建一个触发器,例如,只能为BEFOREUPDATE或AFTERUPDATE事件创建一个触发器。mysql5.7.2+版本解决了这样限制,并允许我们为表中的相同事件和动作时间创建多个触发器。当事件发生时,触发器将依次激活。我们来参考创建第一个触发器中的语法。如果表中有相同事件有多个触发器,mysql将按照创建的顺序调用触发器。要更改触发器的顺序,需要在FOREACHROW子句之后指定FOLLOWS或PRECEDES。我们来看下这两个词的说明:
- FOLLOWS选项允许新触发器在现有触发器之后激活。
- PRECEDES选项允许新触发器在现有触发器之前激活。
完事来看下使用显式顺序创建新的附加触发器的语法:
DELIMITER$$ CREATETRIGGERtrigger_name [BEFORE|AFTER][INSERT|UPDATE|DELETE]ONtable_name FOREACHROW[FOLLOWS|PRECEDES]existing_trigger_name BEGIN … END$$ DELIMITER;
然后,我们来看一个在表中的同一个事件和动作上,创建多个触发器的例子。我们来基于products表进行演示,首先来创建一个新的price_logs表,完事呢,每当更改产品的价格(MSRP列)时,要将旧的价格记录在一个名为price_logs的表中,先来看想sql:
CREATETABLEprice_logs( idINT(11)NOTNULLAUTO_INCREMENT, product_codeVARCHAR(15)NOTNULL, priceDOUBLENOTNULL, updated_atTIMESTAMPNOTNULLDEFAULT CURRENT_TIMESTAMP ONUPDATECURRENT_TIMESTAMP, PRIMARYKEY(id), KEYproduct_code(product_code), CONSTRAINTprice_logs_ibfk_1FOREIGNKEY(product_code) REFERENCESproducts(productCode) ONDELETECASCADE ONUPDATECASCADE );
完事,当表的BEFOREUPDATE事件发生时,创建一个新的触发器。触发器名称为before_products_update,具体实现如下所示:
DELIMITER$$ CREATETRIGGERbefore_products_update BEFOREUPDATEONproducts FOREACHROW BEGIN INSERTINTOprice_logs(product_code,price) VALUES(old.productCode,old.msrp); END$$ DELIMITER;
然后,当我们更改产品的价格,并使用以下update语句,最后查询price_logs表:
UPDATEproducts SETmsrp=95.1 WHEREproductCode='S10_1678'; --查询结果价格记录 SELECT*FROMprice_logs;
上面查询语句执行后,得到以下结果:
+----+--------------+-------+---------------------+ |id|product_code|price|updated_at| +----+--------------+-------+---------------------+ |1|S10_1678|95.7|2017-08-0302:46:42| +----+--------------+-------+---------------------+ 1rowinset
可以看到结果中,它按我们预期那样工作了。
完事我们再来假设不仅要看到旧的价格,改变的时候,还要记录是谁修改了它。要实现这个,我们可以向price_logs表添加其他列,但是,为了实现多个触发器的演示,我们将创建一个新表来存储进行更改的用户的数据。这个新表的名称为user_change_logs,结构如下:
CREATETABLEuser_change_logs( idint(11)NOTNULLAUTO_INCREMENT, product_codevarchar(15)DEFAULTNULL, updated_attimestampNOTNULLDEFAULTCURRENT_TIMESTAMP ONUPDATECURRENT_TIMESTAMP, updated_byvarchar(30)NOTNULL, PRIMARYKEY(id), KEYproduct_code(product_code), CONSTRAINTuser_change_logs_ibfk_1FOREIGNKEY(product_code) REFERENCESproducts(productCode) ONDELETECASCADEONUPDATECASCADE );
现在,我们创建一个在products表上的BEFOREUPDATE事件上激活的第二个触发器。此触发器将更改的用户信息更新到user_change_logs表。它在before_products_update触发后被激活:
DELIMITER$$ CREATETRIGGERbefore_products_update_2 BEFOREUPDATEONproducts FOREACHROWFOLLOWSbefore_products_update BEGIN INSERTINTOuser_change_logs(product_code,updated_by) VALUES(old.productCode,user()); END$$ DELIMITER;
然后我们来使用update语句更新指定产品的价格:
UPDATEproducts SETmsrp=95.3 WHEREproductCode='S10_1678';
再来分别从price_logs和user_change_logs表查询数据:
mysql>SELECT*FROMprice_logs; +----+--------------+-------+---------------------+ |id|product_code|price|updated_at| +----+--------------+-------+---------------------+ |1|S10_1678|95.7|2017-08-0302:46:42| |2|S10_1678|95.1|2017-08-0302:47:21| +----+--------------+-------+---------------------+ 2rowsinset mysql>SELECT*FROMuser_change_logs; +----+--------------+---------------------+----------------+ |id|product_code|updated_at|updated_by| +----+--------------+---------------------+----------------+ |1|S10_1678|2017-08-0302:47:21|root@localhost| +----+--------------+---------------------+----------------+ 1rowinset
如上所见,两个触发器按照预期的顺序激活执行相关操作了。完事我们来在information_schema数据库的triggers表中的action_order列,看下触发激活同一事件和操作的顺序:
mysql>SELECT trigger_name,action_order FROM information_schema.triggers WHERE trigger_schema='yiibaidb' ORDERBYevent_object_table, action_timing, event_manipulation; +--------------------------+--------------+ |trigger_name|action_order| +--------------------------+--------------+ |before_employee_update|1| |before_products_update|1| |before_products_update_2|2| +--------------------------+--------------+ 3rowsinset
好啦,本次记录就到这里了。
更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL查询技巧大全》、《MySQL事务操作技巧汇总》、《MySQL存储过程技巧大全》、《MySQL数据库锁相关技巧汇总》及《MySQL常用函数大汇总》
希望本文所述对大家MySQL数据库计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。