内容正文:
第12章 触发器和事件
主要内容
12.1 触发器
12.2 事件
12.3 本章小结
12.1 触发器
12.1.1 触发器概述
MySQL的触发器是与表有关的命名数据库对象,本质上是一种特殊的存储过程,它在插入、修改和删除特定表中的数据时触发执行。
触发器不能使用CALL语句调用,当表上出现特定事件时,MySQL将自动调用该触发器。
触发器可以查询其他表,也可以包含复杂的SQL语句,但不能在触发器中以显式或隐式方式开始或结束事务。
12.1 触发器
12.1.1 触发器概述
触发器的优点:
触发器不需要明确调用,当触发表中的数据做出相应的修改后由系统自动调用。
触发器支持回滚机制,保证了数据的一致性和完整性。
触发器可以用来实施比FOREIGN KEY、CHECK约束等更为复杂的检查和操作。
触发器可以通过数据库中的相关表修改其他表。
12.1 触发器
12.1.1 触发器概述
触发器比数据库本身标准的功能有更精细和更复杂的数据控制能力,用户利用触发器可以方便地实现数据库中数据的完整性和一致性。
MySQL中的触发器是行级触发器,在增加、删除和修改操作相对频繁的表上尽量不要创建触发器,因为它会对表中受影响的每一行都执行一次触发器,所以触发器消耗资源较大,要慎重使用。
12.1 触发器
12.1.2 NEW和OLD变量
在触发器中不能直接使用列名去标识,我们用“NEW.列名”和“OLD.列名”来区分。
对于insert、update和delete三种触发器事件,“NEW.列名”和“OLD.列名”并不是都适用,需要注意它们的合法性。
12.1 触发器
12.1.2 NEW和OLD变量
当向表中插入新记录时,在触发器中可以使用NEW.列名来获得新纪录的某个列的值,此时OLD是不合法的。
当从表中删除记录时,在触发器中可以使用OLD.列名来获得被删除纪录的某个列的值,此时NEW是不合法的。
当修改表中的某条记录时,在触发器中可以使用OLD来获得修改前的记录的值,使用NEW来获得修改后的记录的值。
OLD记录是只读的,不能修改;NEW记录可以在BEFORE触发器中修改(SET NEW.列名=值),但在AFTER触发器中不能更改。
12.1 触发器
12.1.3 创建触发器
使用命令创建触发器
语法格式:
CREATE TRIGGER [IF NOT EXISTS] trigger_name
BEFORE|AFTER INSERT|UPDATE|DELETE
ON table_name FOR EACH ROW
[ FOLLOWS | PRECEDES other_trigger_name]
BEGIN
trigger_body
END
12.1 触发器
12.1.3 创建触发器
使用命令创建触发器
根据触发动作时间和触发器事件的组合,在同一张表上建立的同一触发器事件、不同触发动作时间的触发器的执行顺序如下所示:
如果有 BEFORE触发器,先执行BEFORE触发器。
执行SQL语句。
如果有AFTER触发器,执行AFTER触发器。
若SQL语句或触发器执行失败,MySQL会回滚事务,顺序如下所示:
如果 BEFORE 触发器执行失败,SQL语句无法正确执行。
如果SQL语句执行失败,AFTER型触发器不会被触发。
如果AFTER类型的触发器执行失败,SQL语句会回滚。
12.1 触发器
12.1.3 创建触发器
使用命令创建触发器
增加一个备选课程表,表中四个字段含义分别为课程号、课程名称、还能选课的人数、选课人数上限。
【例12.1】创建备选课程表course_available。
在MySQL命令行客户端输入命令:
CREATE TABLE course_available
(
cno CHAR(3) PRIMARY KEY,
cname VARCHAR(10),
cavailable TINYINT,
climit TINYINT
);
12.1 触发器
12.1.3 创建触发器
使用命令创建触发器
【例12.2】创建触发器,当在备选课程表上插入数据时,检查选课人数上限climit字段的取值是否在0到100之间,如果该值大于100则按100插入,如果该值小于0则按0插入。
在MySQL命令行客户端输入命令:
DELIMITER //
CREATE TRIGGER insert_tri
BEFORE INSERT ON course_available
FOR EACH ROW
BEGIN
IF NEW.climit<0 THEN
SET NEW.climit=0;
END IF;