Mysql触发器语法详解(附带简单实用例子)

Mysql触发器语法详解(附带简单实用例子)

Mysql触发器

触发器语法实用案例(常用after类型触发器)总结(踩坑记录)

触发器语法

DEFINER:定义该触发器的用户和主机地址,一般默认为当前用户和主机地址。 trigger_name:触发器名称 AFTER|BEFORE:触发器触发状态,二选一。 INSERT|UPDATE|DELETE:触发器触发状态,三选一。 table_name:监控的数据表名称。 FOR EACH ROW:行级触发器,修改一行数据触发一次。不写就默认语句级触发器,不管修改多少行数据,只执行一次。

-- 数据库操作工具方法(navicat、sqlyog)

CREATE DEFINER=`root`@`localhost` TRIGGER trigger_name AFTER|BEFORE INSERT|UPDATE|DELETE ON table_name

FOR EACH ROW -- 行级触发器,修改一行数据触发一次。不写就默认语句级触发器,不管修改多少行数据,只执行一次。

BEGIN

... -- 具体执行语句

END

命令行方式

-- 命令行方式

--先更改语句结束符号

delimiter ## -- 切换自定义结束符号,在可视化操作页面不需要,在命令行中创建触发器则需要。

-- 再创建触发器

CREATE TRIGGER trigger_name AFTER|BEFORE INSERT|UPDATE|DELETE ON table_name

FOR EACH ROW -- 行级触发器

BEGIN

... -- 具体执行语句

END

## -- 代表创建触发器语句结束,这样就不会执行到分号;的时候暂停执行了。

delimiter ; --恢复mysql默认语句结束符号

实用案例(常用after类型触发器)

before触发器一般用于在操作数据前,对新数据的值进行修改。例如:考试时长计算,set new.考试时长 = new endtime - new starttime(很少使用)

-- 在插入bysj_et表后触发

DROP TRIGGER if EXISTS testi; -- 如果存在testi触发器则删除

CREATE TRIGGER testi AFTER INSERT ON bysj_et

FOR EACH ROW

BEGIN

INSERT INTO bysj_dt VALUES (new.id,new.et_name);

END

-- 在删除bysj_et表后触发

DROP TRIGGER if EXISTS testd; -- 如果存在testd触发器则删除

CREATE TRIGGER testd AFTER DELETE ON bysj_et

FOR EACH ROW

BEGIN

DELETE FROM bysj_dt WHERE id = old.id AND dt_name = old.et_name;

END

-- 在更新bysj_et表后触发

DROP TRIGGER if EXISTS testu; -- 如果存在testu触发器则删除

CREATE TRIGGER testu AFTER UPDATE ON bysj_et

FOR EACH ROW

BEGIN

-- SET @oid = old.id; -- 获取更新前旧数据行id

-- SET @odt_name = old.et_name; -- 获取更新前旧数据行et_name

-- SET @nid = new.id; -- 获取新数据行id

-- SET @ndt_name = new.et_name; -- 获取新数据行et_name

--UPDATE bysj_dt SET id = @nid,dt_name = @ndt_name WHERE id = @oid AND dt_name = @odt_name; --具体执行语句

-- 上面的语句熟悉了之后可以优化成下面这样

UPDATE bysj_dt SET id = new.id,dt_name = new.et_name WHERE id = old.id AND dt_name = old.et_name;

END

总结(踩坑记录)

1.new.字段的值可以在before类型的触发器中进行赋值和取值,在after类型触发器中只能取值。(在after类型触发器中进行对new数据行赋值操作会报错。因为after是在操作之后,已经产生了新数据行,不可修改。) 2.在insert操作中,只有new数据行,没有old数据行。(使用old关键字会报错) 3.在update操作中,new数据行和old数据行存在。 4.在delete操作中,只有old数据行。(使用new关键字会报错) 5.在mysql5.7之前的版本,同一张表中,不能存在两个类型一样的触发器。如果想在一个触发器种实现两种不同的处理语句执行,可以增加条件判断。 例如:使用if语句

CREATE DEFINER=`root`@`localhost` TRIGGER testi AFTER INSERT ON bysj_et

FOR EACH ROW

BEGIN

IF(new.id = 6) -- 当新id为6时

THEN IF(new.et_name = '6') -- 当新id为6,并且name也为6才执行插入语句

THEN INSERT INTO bysj_dt VALUES (new.id,new.et_name);

END IF;

END IF;

END;

或使用case when语句

CREATE DEFINER=`root`@`localhost` TRIGGER testi AFTER INSERT ON bysj_et

FOR EACH ROW

BEGIN

CASE

WHEN new.id = 6 AND new.et_name = '6' THEN

INSERT INTO bysj_dt VALUES (new.id,'等于6');

WHEN new.id < 6 THEN

INSERT INTO bysj_dt VALUES (new.id,'小于6');

ELSE

INSERT INTO bysj_dt VALUES (100,'100');

END CASE;

END

6.在mysql5.7之后的版本可以存在两个类型的触发器。 但是要注意主键策略问题,两个触发器执行语句都为新增,当新增数据表的某列为主键时,第二次插入同样的数据就会报错。id为6的新数据不能插入bysj_dt表两次。 7.在mysql中,只存在6种触发器。(before insert、before update、before delete、after insert、after update、after delete) 8.查看所有触发器:show triggers;

相关推荐

下界核心 (Nether Core) - Gany的下界 (Gany's Nether) - MC百科
365网站打不开了

下界核心 (Nether Core) - Gany的下界 (Gany's Nether) - MC百科

📅 09-16 👁️ 3920
‎大润发e路发
365网站打不开了

‎大润发e路发

📅 09-22 👁️ 5778
國外知名網站選出「全世界最熱門10大Cosplayer」,但很多網友發現他們選的是「胸前那兩粒」…
亲身体验,PRADA 普拉达男士时尚休闲鞋上脚
365bet资讯

亲身体验,PRADA 普拉达男士时尚休闲鞋上脚

📅 10-21 👁️ 5250
王者为什么一直服务器无响应
365网站打不开了

王者为什么一直服务器无响应

📅 09-26 👁️ 8189
禄丰医院大全
365batapp

禄丰医院大全

📅 10-09 👁️ 1957