码迷,mamicode.com
首页 > 数据库 > 详细

mysql触发器trigger

时间:2018-08-21 21:04:01      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:log   mysql   分隔符   myisam   对象   tip   excel导入   字段   分享图片   

2018年8月15日,今天由于之前的失误(因为刚来公司不太懂业务导致的)使一个不应该赋值的字段给赋值了,神奇的是居然上生产了,后来就是一系列数据错误,为了及时抑制事态的严重,只能写触发器了,因为改代码已经不现实了,大致情况是这样的,有一张表里面一个订单号和一个订单状态,由于当时是excel导入的数据,excel并没有这两个字段,当时来的时间不长,看到这个表有个订单号,感觉一个是个重要的字段,就问了一组长,他说用UUID赋值就行,后来就赋值了,赋值以后会不断的调取华泰那边的接口,因为这个订单号是我们生成的,华泰并没有,然后就是各种错,后来组长说谁让你赋值的,你见过那个业务字段可以随机赋值的,心里一万个MMP,当时不是你说的吗,后来就洗个触发器止损吧!!!

原文地址转载:https://www.cnblogs.com/phpper/p/7587031.html 通过这问大神的指点才写出来

先上我写的触发器:

DROP TRIGGER if EXISTS upd_che;
CREATE TRIGGER upd_che BEFORE INSERT ON wl_ser_info FOR EACH ROW
BEGIN
IF (
    NEW.SERVICE_ORDER_STATUS = ‘‘
    OR NEW.SERVICE_ORDER_STATUS IS NULL
) THEN
SET NEW.SERVICE_ORDERNO = NULL;
end if;
END;

MySQL好像从5.0.2版本就开始支持触发器的功能了,本次博客就来介绍一下触发器,首先还是谈下概念性的东西吧:

什么是触发器

触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性。

创建触发器:

CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt
trigger_name:触发器的名称
tirgger_time:触发时机,为BEFORE或者AFTER
trigger_event:触发事件,为INSERT、DELETE或者UPDATE
tb_name:表示建立触发器的表明,就是在哪张表上建立触发器
trigger_stmt:触发器的程序体,可以是一条SQL语句或者是用BEGIN和END包含的多条语句
所以可以说MySQL创建以下六种触发器:
BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE
AFTER INSERT,AFTER DELETE,AFTER UPDATE


其中,触发器名参数指要创建的触发器的名字

BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后

FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器

创建有多个执行语句的触发器
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
    执行语句列表
END

其中,BEGIN与END之间的执行语句列表参数表示需要执行的多个语句,不同语句用分号隔开

tips:一般情况下,mysql默认是以 ; 作为结束执行语句,与触发器中需要的分行起冲突

     为解决此问题可用DELIMITER,如:DELIMITER ||,可以将结束符号变成||

     当触发器创建完成后,可以用DELIMITER ;来将结束符号变成;

mysql> DELIMITER ||
mysql> CREATE TRIGGER demo BEFORE DELETE
    -> ON users FOR EACH ROW
    -> BEGIN
    -> INSERT INTO logs VALUES(NOW());
    -> INSERT INTO logs VALUES(NOW());
    -> END
    -> ||
Query OK, 0 rows affected (0.06 sec)

mysql> DELIMITER ;

上面的语句中,开头将结束符号定义为||,中间定义一个触发器,一旦有满足条件的删除操作

就会执行BEGIN和END中的语句,接着使用||结束

最后使用DELIMITER ; 将结束符号还原

tigger_event:

技术分享图片

load data语句是将文件的内容插入到表中,相当于是insert语句,而replace语句在一般的情况下和insert差不多,但是如果表中存在primary 或者unique索引的时候,如果插入的数据和原来的primary key或者unique相同的时候,会删除原来的数据,然后增加一条新的数据,所以有的时候执行一条replace语句相当于执行了一条delete和insert语句。

触发器可以是一条SQL语句,也可以是多条SQL代码块,那如何创建呢?

DELIMITER $  #将语句的分隔符改为$
BEGIN
sql1;
sql2;
...
sqln
END $
DELIMITER ;  #将语句的分隔符改回原来的分号";"

在BEGIN...END语句中也可以定义变量,但是只能在BEGIN...END内部使用:


DECLARE var_name var_type [DEFAULT value] #定义变量,可指定默认值
SET var_name = value  #给变量赋值
NEW和OLD的使用:
技术分享图片

根据以上的表格,可以使用一下格式来使用相应的数据:
NEW.columnname:新增行的某列数据
OLD.columnname:删除行的某列数据

说了这么多现在我们来创建一个触发器吧!


现在有表如下:
用户users表


技术分享图片
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,
  `add_time` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`(250)) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1;
技术分享图片

日志logs表:


CREATE TABLE `logs` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `log` varchar(255) DEFAULT NULL COMMENT 日志说明,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=日志表‘;

需求是:当在users中插入一条数据,就会在logs中生成一条日志信息。


创建触发器:


技术分享图片
DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;#后面发现中文字符编码出现乱码,这里设置字符集
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2);     #函数CONCAT可以将字符串连接
INSERT INTO logs(log) values(s1);
END $
DELIMITER ;
技术分享图片

技术分享图片

 

技术分享图片

查看触发器

SHOW TRIGGERS语句查看触发器信息

技术分享图片

Tip:

上面我用的navicat直接创建,如果大家用的mysql front,name这里会有个区别,我们删除刚才的触发器,在Mysql front中测试
drop trigger  user_log;#删除触发器

打开Mysql Front:

技术分享图片

 

 

 

mysql front在编译sql时,不用定义结尾分隔符,修改后的sql直接这样既可:


技术分享图片
#DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
DECLARE s1 VARCHAR(40)character set utf8;
DECLARE s2 VARCHAR(20) character set utf8;
SET s2 = " is created";
SET s1 = CONCAT(NEW.name,s2);     #函数CONCAT可以将字符串连接
INSERT INTO logs(log) values(s1);
END #$
#DELIMITER ;
技术分享图片技术分享图片

 


 

这里再啰嗦几句:

tips:SHOW TRIGGERS语句无法查询指定的触发器

在triggers表中查看触发器信息
SELECT * FROM information_schema.triggers;

 技术分享图片

 

结果显示了所有触发器的详细信息,同时,该方法可以查询制定触发器的详细信息

SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME=user_log‘;

tips:所有触发器信息都存储在information_schema数据库下的triggers表中

     可以使用SELECT语句查询,如果触发器信息过多,最好通过TRIGGER_NAME字段指定查询

回到上面,我们创建好了触发器,继续在users中插入数据并查看数据:

insert into users(name,add_time) values(周伯通‘,now());

mysql触发器trigger

标签:log   mysql   分隔符   myisam   对象   tip   excel导入   字段   分享图片   

原文地址:https://www.cnblogs.com/mdh-java/p/9513720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!