触发器
当某个表发生更改时需要MySQL自动处理事件就是触发器。MySQL只会响应以下语句从而自动执行一条MySQL语句
:
- DELETE
- INSERT
- UPDATE
创建触发器
创建触发器时,需要注意一些细节:
- 唯一的触发器名
- 触发器关联的表
- 触发器应该响应的活动(DELETE,INSERT,UPDATE)
- 触发器何时执行(处理之前或之后)
在MySQL5中同一数据库中的两个表可以用同一个名字,但是同一个表中的触发器名字必须唯一。但是在DBMS数据库中触发器名只能唯一。
可以用CREATE TRIGGER
语句创建触发器。
CREATE TRIGGER test_tt AFTER DELETE ON `test` FOR EACH ROW
BEGIN
DECLARE s VARCHAR(20) DEFAULT 'hello';
SET s = 'world';
UPDATE `member` SET `name` = s WHERE id = OLD.id;
END
当在删除test表的数据时,会在对应的member对应的id中添加name字段值为world。
每个表最多支持6个触发器。单一触发器不能与多个事件或者多个表关联,所以如果需要响应多个事件必须创建多个触发器。
删除触发器
DROP TRIGGER test_tt
触发器不能修改更新,只能删除重新创建。
使用触发器
INSERT触发器
- 在INSERT触发器代码内,可引用一个NEW的虚拟表,访问被插入的行。
- 在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改被插入的值)
- 对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSRT之后包含新的自动生成值
CREATE TRIGGER newarticle AFTER INSERT ON articles FOR EACH ROW SELECT NEW.title INTO @result;
该触发器按照AFTER INSERT执行,在后续往数据库中插入新数据之后会返回新数据的title列存入到变量result中。NEW指的是插入的虚拟表。
INSERT INTO articles(id,title,body) VALUES(0,'The Boy Hunters','Go with me to the great river Mississippi.');
查询result变量
SELECT @result;
DELETE触发器
- 在DELETE触发器代码内,可以引用一个名为OLD的虚拟表来访问被删除的行
- OLD中的所有值都是只读的,不能更新
一般都使用BEFORE DELETE触发器,相比AFTER DELETE来说更加安全,如果后续的存入数据失败,那么DELETE本身也将被取消掉。
CREATE TRIGGER newarticle BEFORE DELETE ON articles FOR EACH ROW
BEGIN
INSERT INTO articles(id,title,body) VALUES(0,'The Boy Hunters','Go with me to the great river Mississippi.');
END//
UPDATE触发器
- 在UPDATE触发器代码内,可以引用OLD虚拟表来访问更新前的值,也可以引用NEW虚拟表来访问更新的值
CREATE TRIGGER updatetitle BEFORE UPDATE ON articles FOR EACH ROW SET NEW.title = Upper(NEW.title);
创建一个名为updatetitle的触发器,当数据更新前会出发该触发器将新虚拟表中的title全部改为大写。
触发器的优缺点
优点
- 与存储过程一样,执行前服务器会先预编译所以执行效率很高
- 业务逻辑封装性好,使用简单,方便
- 可以使用触发器来确保数据的一致性(大小写、格式等)
- 触发器可以用作创建审计跟踪,可以用来记录操作日志
- 可以基于数据库的值使用户具有操作数据库的某种权利。可以基于时间限制用户的操作,在特定时间内不能修改数据库。
缺点
- 因为MySQL触发器不能使用CALL语句,所以在对于存储过程的复用性兼容很差,重复的存储过程必须重新写。
- 由于触发器封装完整,所以看不到详细过程,一旦出了错将很难排查。
- 占用服务器端太多的资源,对服务器造成很大的压力