触发器是什么?

触发器(Triggers)是数据库中的一种特殊对象,它们会在某些数据库事件发生时自动执行。触发器的主要作用是对表的操作(如INSERTUPDATEDELETE)做出响应,并执行特定的操作。

触发器的操作

CREATE TRIGGER trigger_name
BEFORE/AFTER INSERT/UPDATE/DELETE ON table_name FOR EACH ROW
BEGIN
    -- 触发器执行的 SQL 语句
END;

触发器的组成部分:

  1. trigger_name:这是触发器的名称,用户可以根据需要自定义,以便标识和管理触发器。

  2. BEFORE/AFTER:指定触发器的触发时间。BEFORE意味着在数据操作之前执行,AFTER意味着在数据操作完成之后执行。

    • BEFORE:可以用于在插入、更新或删除之前进行数据验证或转换。
    • AFTER:适合在数据操作后进行日志记录或数据同步等操作。
  3. INSERT/UPDATE/DELETE:这是触发器监视的操作类型。可以指定触发器在数据插入、更新或删除时触发执行。

    • INSERT:当表中有新记录插入时触发。
    • UPDATE:当表中的记录被更新时触发。
    • DELETE:当表中的记录被删除时触发。
  4. table_name:表示触发器所监视的表的名称,意味着该触发器将监听此表的指定操作。

  5. FOR EACH ROW:表示触发器会对表中受影响的每一行执行一次。如果操作影响了多行记录,那么触发器会逐行执行。

  6. SQL 语句:触发器定义的核心逻辑部分,在触发事件发生时自动执行。可以是简单的 SQL 操作,也可以是复杂的逻辑操作。

触发器的应用场景:

  • 数据验证:在数据插入或更新前,使用触发器验证数据的合法性。
  • 自动计算字段:可以通过触发器在插入数据时自动计算或设置一些字段的值。
  • 日志记录:当对表执行某些操作时,触发器可以自动记录日志。
  • 数据同步:在主表的数据发生变化时,触发器可以自动更新或同步到其他表中。

注意事项:

  • 触发器的频繁使用可能导致数据库的性能下降,尤其是在表的操作非常频繁的情况下。
  • 复杂的触发器可能会导致维护难度增加,因此需要谨慎设计。

NEW 和 OLD 的含义:

  1. NEW

    • 当执行 INSERTUPDATE 操作时,NEW 用于指代新插入或更新后的数据
    • INSERT 触发器中,NEW 引用的是即将被插入的行数据。
    • UPDATE 触发器中,NEW 引用的是更新后的行数据。
  2. OLD

    • 当执行 UPDATEDELETE 操作时,OLD 用于指代旧数据(即触发器前的数据)。
    • UPDATE 触发器中,OLD 引用的是更新之前的行数据。
    • DELETE 触发器中,OLD 引用的是即将被删除的行数据。

举例说明:

假设有一个表 my_table,其中包含一个名为 quantity 的列。在这个表的 UPDATE 操作上创建一个触发器,用来将旧的 quantity加到新的 quantity中。代码如下:

CREATE TRIGGER my_trigger
BEFORE UPDATE ON my_table
FOR EACH ROW
BEGIN
    SET NEW.quantity = NEW.quantity + OLD.quantity;
END;

解释:

  • OLD.quantity 引用的是更新之前该行的 quantity 值。
  • NEW.quantity 引用的是更新之后即将被保存到表中的 quantity 值。
  • 在触发器中,新的 quantity 值会变成旧值和新值的总和。

注意事项:

  • NEWOLD 只能在适用于它们的操作中使用。例如,INSERT 触发器中无法使用 OLD,因为插入时不存在旧数据,反之,DELETE 触发器中无法使用 NEW
  • 使用 BEFOREAFTER 时要注意,如果修改了 NEW 的值,应该在 BEFORE 触发器中进行,因为 AFTER 触发器已经是操作后的阶段。

示例:

drop table if exists dept2;
create table dept2(
    id int primary key comment  'ID',
    name varchar(50) not null comment '部门名称'
) comment '部门';
INSERT INTo dept2(id, name) VALUES(1,'研发部'),(2,'市场部'),(3,'财务部'),(4,'销售部');

drop table if exists oper_log;
create table oper_log(
    id bigint primary key auto_increment,
    table_name varchar(100) not null comment '操作的哪张表',
    oper_type varchar(100) not null comment '操作类型包括insert delete update',
    oper_time datetime not null comment '操作时间',
    oper_id bigint not null comment '操作的那行记录的id',
    oper_desc text comment '操作描述'
);

/*
    触发器:需求:当向dept表当中insert插入数据之后(after),在oper_log表中记录日志
*/
 drop trigger if exists trigger_dept_insert;

create trigger trigger_dept_insert
/*  触发规则  */
after insert  on dept2 for each row
begin
    /* 一旦触发后发生的操作 */
    insert into oper_log(id, table_name, oper_type, oper_time, oper_id, oper_desc)
    values (null,'dept', 'insert', now(), new.id, concat('插入数据: id =', new.id , ', name = ', new.name));
end;
INSERT INTO dept2 (id, name) VALUES (5, '总经办');

# SHOW CREATE TABLE dept;

/*
 触发器
需求:更新dept表之后,在oper_log中记录日志
 */

drop trigger if exists trigger_dept_update;

create trigger trigger_dept_update  after update on dept2 for each row
begin
    /* 一旦触发后发生的操作 */
    insert into oper_log(id, table_name, oper_type, oper_time, oper_id, oper_desc)
    values (null,'dept', 'update', now(), new.id, concat('更新后: id = ', new.id , ', name = ', new.name,'  更新前: id = ',old.id, ' ,name = ', OLD.name));
end;


/*
 触发器
需求:删除dept表的数据之后,在oper_log中记录日志
 */
drop trigger if exists trigger_dept_delete;

create trigger trigger_dept_delete after delete on dept2 for each row
begin
    insert into oper_log(id, table_name, oper_type, oper_time, oper_id, oper_desc)
    values (null,'dept', 'drop', now(), old.id, concat('删除数据: id =', old.id , ', name = ', old.name));
end;

 

 

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部