MySQL触发器

MySQL触发器
一、 MySQL触发器概念
MySQL5.0以上版本支持触发器,触发器是与表有关的命名数据库对象,当表出现特定事件时,将激活该对象。
二、 MySQL触发器语法
CREATE TRIGGER trigger_name trigger_time trigger_event
       ON tbl_name FOR EACH ROW trigger_stmt
trigger_time:触发动作时间,可以是BEFORE或AFTER,以指明触发程序是在激活它的语句之前或之后触发。BEFORE update能否取到new.字段值?BEFORE AFTER使用时的区别?
Before与After区别:before:(insert、update)可以对new进行修改,after不能对new进行修改。两者都不能修改old数据。
                              在本表插入字段值需要用new计算,只能用before,在别的表中记录插入成功记录或统计插入的条数用after。
trigger_event:激活触发程序的语句类型。
            INSERT:将新行插入表时激活触发程序,如INSERT、LOAD DATA和REPLACE语句。
UPDATE:更改某一行时激活触发程序,如UPDATE语句。
DELETE:从表中删除某一行时激活触发程序,如DELETE和REPLACE语句
trigger_stmt:触发程序激活时执行的语句。如果你打算执行多个语句,可使用BEGIN ... END复合语句结构。
DELIMITER |
CREATE TRIGGER testref BEFORE INSERT ON test1
  FOR EACH ROW BEGIN
    INSERT INTO test2 SET a2 = NEW.a1;
    DELETE FROM test3 WHERE a3 = NEW.a1; 
    UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
  END
|
DELIMITER ;
注:
1、 使用别名OLD和NEW,能够引用与触发程序相关的表中的列。OLD.col_name在更新或删除它之前,引用已有行中的1列,是否可以引
用old与trigger_time无关,NEW.col_name在更新它之后引用将要插入的新行的1列或已有行的1列。
INSERT:只可引用NEW、DELETE:只可引用OLD、 UPDATE:可以引用NEW或OLD。
2、激活触发程序时,对于触发程序引用的所有OLD和NEW列,需要具有SELECT权限,对于作为SET赋值目标的所有NEW列, 需要具
有UPDATE权限。
    3、CREATE TRIGGER语句需要SUPER权限。
4、show   triggers \G :显示数据库中所有触发器。
5、对于具有相同触发程序动作时间和事件的给定表,不能有两个触发程序。
6、触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL
7、触发程序不能使用以显式或隐式方式开始或结束事务的语句,如START TRANSACTION、COMMIT或ROLLBACK。
DROP TRIGGER [schema_name.]trigger_name
三、 MySQL触发器例子
可以在从表中删除每一行之前,或在更新了每一行后激活触发程序。
CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET @sum = @sum + NEW.amount;
SET @sum = 0;
INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
SELECT @sum AS 'Total amount inserted';
注:
如果触发程序比较复杂,可以将其单独定义在存储过程中,然后使用简单的CALL语句从触发程序调用存储程序
MySQL处理错误的方式如下:
如果BEFORE触发程序失败,不执行相应行上的操作。
仅当BEFORE触发程序(如果有的话)和行操作均已成功执行,才执行AFTER触发程序。
如果在BEFORE或AFTER触发程序的执行过程中出现错误,将导致调用触发程序的整个语句的失败。
四、 项目中使用
应用场景:记录会员表user_login、user_x表变更情况
DELIMITER $$
create trigger `member`.`tri_userloginmod` AFTER UPDATE on `member`.`user_login`
for each row BEGIN
SELECT COUNT(1) INTO @count FROM member_modify WHERE userid=OLD.userid;
IF @count<1 THEN
INSERT INTO member_modify(userid,modify_time) values(OLD.userid,NOW());
ELSE
UPDATE member_modify SET modify_time=NOW() WHERE userid=OLD.userid;
END IF ;
END;
$$
DELIMITER ;

for i in `seq 0 99`;do mysql -h10.34.43.111 member -p -e "DELIMITER $$
create trigger member.tri_user${i}mod AFTER UPDATE on member.user_${i}
for each row BEGIN
SELECT COUNT(1) INTO @count FROM member_modify WHERE userid=OLD.userid;
IF @count<1 THEN
INSERT INTO member_modify(userid,modify_time) values(OLD.userid,NOW());
ELSE
UPDATE member_modify SET modify_time=NOW() WHERE userid=OLD.userid;
END IF ;
END;
$$
DELIMITER ;";done

你可能感兴趣的:(数据结构,sql,mysql)