【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。

 

原文地址:https://www.cnblogs.com/jiangxu67/p/3586993.html