关于触发器的介绍:
http://dev.mysql.com/doc/refman/5.1/zh/triggers.html
基本的介绍都可以在这里找到,对于基本的概念在这里不做赘述,针对一些重点来说。
trigger_event与以表操作方式激活触发程序的SQL语句并不很类似,这点很重要。例如,关于INSERT的BEFORE触发程序不仅能被INSERT语句激活,也能被LOAD DATA语句激活。
可能会造成混淆的例子之一是INSERT INTO .. ON DUPLICATE UPDATE ...语法:BEFORE INSERT触发程序对于每一行将激活,后跟AFTER INSERT触发程序,或BEFORE UPDATE和AFTER UPDATE触发程序,具体情况取决于行上是否有重复键。
使用别名OLD和NEW,能够引用与触发程序相关的表中的列。OLD.col_name在更新或删除它之前,引用已有行中的1列。NEW.col_name在更新它之后引用将要插入的新行的1列或已有行的1列。
此外,激活触发程序时,对触发程序执行的语句也存在一些限制:
· 触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL(允许存储程序通过参数将数据返回触发程序)。
· 触发程序不能使用以显式或隐式方式开始或结束事务的语句,如START TRANSACTION、COMMIT或ROLLBACK。
使用OLD和NEW关键字,能够访问受触发程序影响的行中的列(OLD和NEW不区分大小写)。在INSERT触发程序中,仅能使用NEW.col_name,没有旧行。在DELETE触发程序中,仅能使用OLD.col_name,没有新行。在UPDATE触发程序中,可以使用OLD.col_name来引用更新前的某一行的列,也能使用NEW.col_name来引用更新后的行中的列。
用OLD命名的列是只读的。你可以引用它,但不能更改它。对于用NEW命名的列,如果具有SELECT权限,可引用它。在BEFORE触发程序中,如果你具有UPDATE权限,可使用“SET NEW.col_name = value”更改它的值。这意味着,你可以使用触发程序来更改将要插入到新行中的值,或用于更新行的值。
如下是一个监控插入、删除以及更新表的触发器,所有更新的数据都将移入新表。
DELIMITER |
#创建插入触发器
CREATE TRIGGER INSERT_TRIGGER BEFORE INSERT ON tmp_test
FOR EACH ROW
BEGIN
INSERT INTO tmp_tmp SELECT * FROM tmp_test WHERE id = NEW.id;
END
|
#创建更新触发器,仅当target_url和user_cate更新时在临时表中插入数据
CREATE TRIGGER UPDATE_TRIGGER AFTER UPDATE ON tmp_test
FOR EACH ROW
BEGIN
IF NEW.target_url != OLD.target_url
THEN
INSERT INTO tmp_tmp SELECT * FROM tmp_test WHERE id = NEW.id ON DUPLICATE KEY UPDATE target_url = NEW.target_url;
END IF;
IF NEW.user_cate != OLD.user_cate
THEN
INSERT INTO tmp_tmp SELECT * FROM tmp_test WHERE id = NEW.id ON DUPLICATE KEY UPDATE user_cate = NEW.user_cate;
END IF;
END
|
#创建删除触发器
CREATE TRIGGER DELETE_TRIGGER BEFORE DELETE ON tmp_test
FOR EACH ROW
BEGIN
INSERT INTO tmp_tmp SELECT * FROM tmp_test WHERE id = OLD.id;
UPDATE tmp_tmp SET enabled = 0 WHERE id = OLD.id;
END
|
DELIMITER ;