【MySQL】触发器学习

MySQL手册中对触发器的定义是:

  触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。表必须是永久性表,不能将触发程序与临时表与视图关联起来。

  相同触发程序动作时间和事件的给定表,不能有两个触发程序。同一张表不能有两个before update(不同字段可写在一个trigger里面),但是可以同时有before update、after update或before insert。

语法:

DELIMITER $$

CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `db`.`tri_name` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `db`.`tb_name`
FOR EACH ROW BEGIN
#######
command
#######
END$$ DELIMITER ;

trgger_time:

  before/after

trigger_event:

  1.insert:insert、load data、replace可触发

  2.update:

  3.delete:delete、replace可触发

  对于insert into ..on duplicate update语法要注意

使用别名OLD和NEW,能够引用与触发程序相关的表中的列。OLD。col_name在更新或删除它之前,引用已有行中的列。NEW。col_name在更新它之后引用将要插入的新行或已有行的列。

使用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” 更改它的值。这意味着,你可以使用触发程序来更改将要插入到新行中的值,或用于更新行的值。

激活触发程序时,对于触发程序引用的所有OLD和NEW列,需要具有select权限,对于作为SET赋值目标的所有NEW列,需要具有UPDATE权限。

CREATE TRIGGER需要SUPER权限。

建表:

CREATE TABLE `test1`.`tri_test` (
`a` int(1) DEFAULT NULL,
`b` int(1) DEFAULT NULL
) CREATE TABLE `test2`.`tri_test` (
`a` int(1) DEFAULT NULL,
`b` int(1) DEFAULT NULL
)

示例:跨库两表insert数据同步触发器

DELIMITER $$

CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `test1`.`tri_test.insert.a` AFTER INSERT
ON `test1`.`tri_test`
FOR EACH ROW BEGIN
INSERT INTO test2.tri_test VALUES (new.a,new.b);
END$$ DELIMITER ;

示例:跨库两表update数据同步触发器

DELIMITER $$

CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `test1`.`tri_test.insert.a` AFTER INSERT
ON `test1`.`tri_test`
FOR EACH ROW BEGIN
IF new.b!=old.b
THEN
UPDATE test2.tri_test SET test2.tri_test.b=new.b
WHERE test2.tri_test.a=old.a ;
END IF;
END$$ DELIMITER ;

例:

delimiter //
CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
ELSEIF NEW.amount > 100 THEN
SET NEW.amount = 100;
END IF;
END;//
delimiter ;

注意:

触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL (允许存储程序通过参数将数据返回触发程序)。
触发程序不能使用以显式或隐式方式开始或结束事务的语句,如START TRANSACTION、COMMIT 或ROLLBACK。

上一篇:MySQL PXC 高可用集群搭建


下一篇:hdu 4738 Caocao's Bridges 图--桥的判断模板