http://qdjyyl.blog.51cto.com/1222376/885501
触发器,概念一律不解释!
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `qqfs_db_gm`.`a` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `qqfs_db_gm`.`<Table Name>`
FOR EACH ROW BEGIN
END
根据以上语法,做几点解释!
在解释之前,阐述下我对触发器的观点!
由于我在游戏行业,所面对的数据,都是高并发,读写频繁,但是数据并不一定海量!这个时候,我们对性能的要求非常高!触发器,对性能影响过大!所以,在我们的几个项目中,我从没有引入触发器!不过对于小数据,或者是低并发、修改不频繁的应用,适当的引入触发器还是可以行的!
DEFINER:触发器的创建者,可以手动指定创建者,默认为当前用户
BEFORE/AFTER:BEFORE,就是在触发的动作之前执行你所想要执行的语句(begin后面的sql语句);AFTER,在触发动作之后执行你所想要的语句!
INSERT/UPDATE/DELETE:你所要触发的条件。分别是insert、update、delete。这里不单单的针对这三个关键字,同样的有同类效果的语句也会触发!如LOAD DATA和REPLACE语句也会触发insert
`qqfs_db_gm`.`<Table Name>`:触发的对象都是表
语法解释非常简单!需要注意以下几点:
1.触发器里面不允许执行动态语句!或者是执行带动态语句的存储过程、存储函数等!
2.对于具有相同触发程序动作时间和事件的给定表,不能有两个触发程序。例如,对于某一表,不能有两个BEFORE UPDATE触发程序。但可以有1个BEFORE UPDATE触发程序和1个BEFORE INSERT触发程序,或1个BEFORE UPDATE触发程序和1个AFTER UPDATE触发程序(官方说明)
3.触发的对象和触发执行的语句不能为同一个表!如:触发器a触发b表的insert操作,然后在b表执行insert操作,会报错!这里应该是触发器的一种强制的锁机制!所以就带有很大的性能损耗!
4.不能让两个触发器触发两个表,并使之循环!如:触发器a触发b表的insert操作,并往d表insert数据;触发器c触发d表的insert操作,并往表b insert数据;这样是不行的!会报错如下:Can't update table 'test' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.(第三点也会报这样的错误!)
5.触发器中有new和old关键字。old是指老的数据,很容易想到,会产生老数据的是update和delete操作,因为insert之前没有旧数据和该insert有直接关系!new关键字是指新数据,同理可知道,delete操作是没有新数据产生的,所有new关键字使用的触发条件是insert和update!其实从这里可以看出,触发器又保存了两份数据,结合上面的对表的触发锁定,触发器的性能是不敢恭维的!
6.如果要在触发update的同时,修改该数据加1!用传统的方法update table set id = old.id + 1;这样肯定是不行的,违背了第三点,会报错:Can't update table 'test' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.注意,这个错在触发器编译的时候,是能够通过的,但是在更新的时候,数据库会抛这个异常!
如果一定要这样做,那该怎么办呢?借助关键字new和old.
SET new.id = new.id + 1;
利用这个特性,可以实现很多功能!读者可以自己发散,嘿嘿!
本文出自 “原下” 博客,请务必保留此出处http://qdjyyl.blog.51cto.com/1222376/885501