MySQL:触发器(Trigger)

触发器(TRIGGER)是用户定义在关系表上的一类由事件驱动的特殊过程,在满足一定条件或达到一定阈值时会自动触发。可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力。

Trigger 又叫做 事件-条件-动作(event- condition-action)规则。当特定的系统事件(如对一个表的增、删、改操作,事务的结束等)发生时,对规则的条件进行检查,如果条件成立则执行规则中的动作,否则不执行该动作。规则中的动作体可以很复杂,可以涉及其他表和其他数据库对象,通常是一段 SQL 存储过程

触发器是 MySQL 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是 CALL 手动启动,而是由事件来触发,比如当对一个表进行操作(INSERTDELETEUPDATE)时就会激活它执行。

创建触发器

四要素

触发器创建的四个要素

  1. 监视地点 TABLE

  2. 监视事件 INSERT / UPDATE / DELETE

  3. 触发时间 AFTER / BEFORE

  4. 触发事件 INSERT / UPDATE / DELETE

只有表的创建者才可以在表上创建触发器,并且一个表上只能创建有限数量的触发器

语法

触发器的语法会根据具体的数据库管理系统而有所不同,下面是一般常用的触发器语法:

CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
[REFERNCEING NEW|OLD ROW|TABLE AS <var_name>]
FOR EACH [ROW | STATEMENT]
[WHEN condition]
BEGIN
    -- 触发器动作
END;
  • trigger_name 是触发器的名称,可以自定义。

  • {BEFORE | AFTER} 指定触发器在事件之前或之后执行。

    • AFTER 操作,是在执行了监视动作后,才会执行触发事件
    • BEFORE 操作,是在执行了监视动作前,会执行触发事件
  • {INSERT | UPDATE | DELETE} 指定触发器关联的事件类型。可以是INSERT、DELETE或UPDATE,也可以是它们的组合;同样也可以 UPDATE OF<列名,...,>,也即进一步指明哪些列变化时需要激活触发器

  • table_name 是触发器关联的表名。触发器只能定义在表上,不可在视图上。当基本表的数据发生变化时,将激活定义在该表上相应触发事件的触发器

  • REFERENCING 用来指定在触发器程序中使用的伪表或变量的名称,以便访问新插入、更新或删除的行。

    • OLD ROWNEW ROW: 分别代表被修改的行之前和之后的值。这些值可以通过使用 OLDNEW 前缀来访问到,例如在 AFTER UPDATE 触发器中,可以通过 OLD.column_nameNEW.column_name 分别访问修改之前和之后的列值。

    • OLD TABLENEW TABLE: 用于 DELETEINSERT 操作时访问伪表。Oracle 数据库中,这些伪表也称为临时表,它们具有与被触发的表相同的结构,但内容为更新前或更新后的值。在 MySQL 中使用 OLD TABLE 可以访问删除操作之前的表中的行,使用 NEW TABLE 可以访问插入操作之后的表中的行。

  • FOR EACH ROW 行级触发器:针对每一条记录执行触发器操作,当有大量行被修改时,FOR EACH ROW 触发器会执行相同数量次的操作。

  • FOR EACH STATEMENT 语句触发器:只执行一次触发体动作,即在触发器执行的条件下对整个 SQL 语句中受影响的所有行执行相同的操作。即使它会受到多行更新的影响,只会执行一次触发器操作

  • WHEN condition 是可选的,用于指定触发器执行的条件。如果省略WHEN 触发条件,则触发体动作在触发器激活后立即执行

  • BEGINEND 之间是触发器的动作,可以包含 SQL 语句或调用其他存储过程、函数等。

  • 触发体动作:触发动作体既可以是一个匿名 PL/SQL 过程块,也可以是对已创建存储过程的调用。

    • 如果是行级触发器,用户可以在过程体中使用 NEW 和 OLD 引用 UPDATE/INSERT 事件之后的新值和 UPDATE/DELETE 事件之前的旧值

    • 如果是语句级触发器,则不能在触发动作体中使用 NEW 或 OLD 进行引用。

    • 如果触发动作体执行失败,激活触发器的事件就会终止执行,触发器的目标表或触发器可能影响的其他对象不发生任何变化

示例

创建 INSERT 触发器
DELIMITER $$  
CREATE TRIGGER user_insert_trigger  
AFTER INSERT ON user  
FOR EACH ROW  
BEGIN  
    INSERT INTO user_operation(operation_type, operation_content)  
    VALUES('insert', CONCAT('添加后的数据:', NEW.name));  
END$$  
DELIMITER ;

这个触发器会在向 user 表插入数据后,向 user_operation 表中插入一条记录,记录操作类型为 INSERT 和插入的数据内容。

创建 UPDATE 触发器
DELIMITER $$  
CREATE TRIGGER user_update_trigger  
AFTER UPDATE ON user  
FOR EACH ROW  
BEGIN  
    INSERT INTO user_operation(operation_type, operation_content)  
    VALUES('update', CONCAT('修改前的数据: name:', OLD.name, ', age:', OLD.age));  
    INSERT INTO user_operation(operation_type, operation_content)  
    VALUES('update', CONCAT('修改后的数据: name:', NEW.name, ', age:', NEW.age));  
END$$  
DELIMITER ;

这个触发器会在 user 表的数据更新后,向 user_operation 表中插入两条记录,分别记录修改前后的数据。

激活触发器

每当触发事件发生时,该触发器会被激活

触发器的执行是由触发器事件激活的,如果同一个表上有多个触发器,激活时会按照以下顺序执行

  1. 执行该表上的 BEFORE 触发器
  2. 激活触发器的 SQL 语句
  3. 执行该表上的 AFTER 触发器

对于同一个表上的多个 BEFORE(AFTER) 触发器,遵循“谁先创建谁先执行”的原则,即按照触发器创建的时间先后顺序执行

删除触发器

删除触发器:

DROP TRIGGER [IF EXISTS] trigger_name;

触发器引用行变量

  1. 在触发目标上执行 INSERT 操作后会有一个新行,如果在触发事件中需要用到这个新行的变量,可以用 NEW 关键字表示。

  2. 在触发目标上执行 DELETE 操作后会有一个旧行,如果在触发事件中需要用到这个旧行的变量,可以用 OLD 关键字表示。

  3. 在触发目标上执行 UPDATE 操作后原记录是旧行,新记录是新行,可以使用 NEWOLD 关键字来分别操作。

NEW.column
OLD.column

触发器的作用

触发器在数据库管理中具有多种作用,包括但不限于:

  • 维护数据完整性:确保数据的正确性和一致性。

  • 自动化业务逻辑:在数据变更时自动执行复杂的业务逻辑。

  • 审计和日志记录:记录数据变更的历史,方便追踪和审计。

总结

MySQL 触发器是一种强大的数据库功能,能够在特定事件发生时自动执行预定义的 SQL 语句或程序块。通过合理使用触发器,可以极大地简化数据库的管理和维护工作,提高数据处理的效率和准确性。但需要注意的是,过度使用触发器可能会降低数据库的性能,因此在设计时应谨慎考虑。

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值