《SQL与数据库基础》15. 触发器
阅读原文时间:2023年08月29日阅读:1

目录


本文以 MySQL 为例

触发器

触发器是与表有关的数据库对象,指在 insert/update/delete 之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合

触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。

使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。

触发器类型

NEW 和 OLD

INSERT 型触发器

NEW 表示将要或者已经新增的数据

UPDATE 型触发器

OLD 表示修改之前的数据,NEW 表示将要或已经修改后的数据

DELETE 型触发器

OLD 表示将要或者已经删除的数据

触发时机:BEFORE、AFTER。

创建触发器

CREATE TRIGGER 触发器名称
触发时机 触发类型
ON 表名 FOR EACH ROW
BEGIN
    sql逻辑;
END;

查看触发器

SHOW TRIGGERS;

删除当前库触发器

DROP TRIGGER 触发器名;

删除指定库的触发器

DROP TRIGGER 库名.触发器名;

示例,数据准备:

CREATE TABLE tb_user(
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
    name VARCHAR(50) NOT NULL COMMENT '用户名',
    phone VARCHAR(11) NOT NULL COMMENT '手机号',
    email VARCHAR(100) COMMENT '邮箱',
    profession VARCHAR(11) COMMENT '专业',
    age TINYINT UNSIGNED COMMENT '年龄',
    gender CHAR(1) COMMENT '性别, 1: 男, 2: 女',
    user_status CHAR(1) COMMENT '状态',
    createtime DATETIME COMMENT '创建时间'
) COMMENT '系统用户表';

INSERT INTO tb_user (name, phone, email, profession, age, gender, user_status, createtime)
VALUES ('吕布', '17799990000', 'lvbu666@163.com', '软件工程', 23, '1', '6', '2001-02-02 00:00:00'),
       ('曹操', '17799990001', 'caocao666@qq.com', '通讯工程', 33, '1', '0', '2001-03-05 00:00:00'),
       ('赵云', '17799990002', '17799990@139.com', '英语', 34, '1', '2', '2002-03-02 00:00:00'),
       ('孙悟空', '17799990003', '17799990@sina.com', '工程造价', 54, '1', '0', '2001-07-02 00:00:00'),
       ('花木兰', '17799990004', '19980729@sina.com', '软件工程', 23, '2', '1', '2001-04-22 00:00:00'),
       ('大乔', '17799990005', 'daqiao666@sina.com', '舞蹈', 22, '2', '0', '2001-02-07 00:00:00'),
       ('露娜', '17799990006', 'luna_love@sina.com', '应用数学', 24, '2', '0', '2001-02-08 00:00:00'),
       ('程咬金', '17799990007', 'chengyaojin@163.com', '化工', 38, '1', '5', '2001-05-23 00:00:00'),
       ('项羽', '17799990008', 'xiaoyu666@qq.com', '金属材料', 43, '1', '0', '2001-09-18 00:00:00'),
       ('白起', '17799990009', 'baiqi666@sina.com', '机械工程及其自动化', 27, '1', '2', '2001-08-16 00:00:00'),
       ('韩信', '17799990010', 'hanxin520@163.com', '无机非金属材料工程', 27, '1', '0', '2001-06-12 00:00:00'),
       ('荆轲', '17799990011', 'jingke123@163.com', '会计', 29, '1', '0', '2001-05-11 00:00:00'),
       ('兰陵王', '17799990012', 'lanlinwang666@126.com', '工程造价', 44, '1', '1', '2001-04-09 00:00:00'),
       ('狂铁', '17799990013', 'kuangtie@sina.com', '应用数学', 43, '1', '2', '2001-04-10 00:00:00'),
       ('貂蝉', '17799990014', '84958948374@qq.com', '软件工程', 40, '2', '3', '2001-02-12 00:00:00'),
       ('妲己', '17799990015', '2783238293@qq.com', '软件工程', 31, '2', '0', '2001-01-30 00:00:00'),
       ('芈月', '17799990016', 'xiaomin2001@sina.com', '工业经济', 35, '2', '0', '2000-05-03 00:00:00'),
       ('嬴政', '17799990017', '8839434342@qq.com', '化工', 38, '1', '1', '2001-08-08 00:00:00'),
       ('狄仁杰', '17799990018', 'jujiamlm8166@163.com', '国际贸易', 30, '1', '0', '2007-03-12 00:00:00'),
       ('安琪拉', '17799990019', 'jdodm1h@126.com', '城市规划', 51, '2', '0', '2001-08-15 00:00:00'),
       ('典韦', '17799990020', 'ycaunanjian@163.com', '城市规划', 52, '1', '2', '2000-04-12 00:00:00'),
       ('廉颇', '17799990021', 'lianpo321@126.com', '土木工程', 19, '1', '3', '2002-07-18 00:00:00'),
       ('后羿', '17799990022', 'altycj2000@139.com', '城市园林', 20, '1', '0', '2002-03-10 00:00:00'),
       ('姜子牙', '17799990023', '37483844@qq.com', '工程造价', 29, '1', '4', '2003-05-26 00:00:00');

# 日志表 user_logs
CREATE TABLE user_logs(
    id INT(11) NOT NULL AUTO_INCREMENT,
    operation VARCHAR(20) NOT NULL COMMENT '操作类型, insert/update/delete',
    operate_time DATETIME NOT NULL COMMENT '操作时间',
    operate_id INT(11) NOT NULL COMMENT '操作的ID',
    operate_params VARCHAR(500) COMMENT '操作参数',
    PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

以语法中的tb_user表与user_logs表为例:

# 通过触发器记录 tb_user 表的数据变更日志,将变更日志插入到日志表user_logs中(插入数据触发器)
CREATE TRIGGER tb_user_insert_trigger
AFTER INSERT ON tb_user FOR EACH ROW
BEGIN
    INSERT INTO user_logs(id, operation, operate_time, operate_id, operate_params)
    VALUES(NULL, 'insert', NOW(), NEW.id, CONCAT('插入的数据内容为: id=', NEW.id, ',name=', NEW.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
END;

/*
测试
*/
# 查看触发器
SHOW triggers;

# 插入数据到tb_user
INSERT INTO tb_user(id, name, phone, email, profession, age, gender, user_status, createtime)
VALUES (26, '三皇子', '18809091212', 'erhuangzi@163.com', '软件工程', 23, '1', '1', NOW());

# 测试完毕之后,检查日志表中的数据是否可以正常插入,以及插入数据的正确性。

以语法中的tb_user表与user_logs表为例:

# 通过触发器记录 tb_user 表的数据变更日志,将变更日志插入到日志表user_logs中(更新数据触发器)
CREATE TRIGGER tb_user_update_trigger
AFTER UPDATE ON tb_user FOR EACH ROW
BEGIN
    INSERT INTO user_logs(id, operation, operate_time, operate_id, operate_params)
    VALUES(NULL, 'update', NOW(), NEW.id, CONCAT('更新之前的数据: id=', OLD.id, ',name=', OLD.name, ', phone=', OLD.phone, ', email=', OLD.email, ', profession=', OLD.profession, ' | 更新之后的数据: id=', NEW.id, ', name=', NEW.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
END;

/*
测试
*/
# 查看触发器
SHOW triggers;

# 更新tb_user表数据
UPDATE tb_user SET profession = '会计' WHERE id <= 5;

# 测试完毕之后,检查日志表中的数据是否可以正常插入,以及插入数据的正确性。

以语法中的tb_user表与user_logs表为例:

# 通过触发器记录 tb_user 表的数据变更日志,将变更日志插入到日志表user_logs中(更新数据触发器)
CREATE TRIGGER tb_user_delete_trigger
AFTER DELETE ON tb_user FOR EACH ROW
BEGIN
    INSERT INTO user_logs(id, operation, operate_time, operate_id, operate_params)
    VALUES(NULL, 'delete', NOW(), OLD.id, CONCAT('删除之前的数据: id=', OLD.id, ', name=', OLD.name, ', phone=', OLD.phone, ', email=', OLD.email, ', profession=', OLD.profession));
END;

/*
测试
*/
# 查看触发器
SHOW triggers;

# 删除tb_user表数据
DELETE FROM tb_user WHERE id = 26;

# 测试完毕之后,检查日志表中的数据是否可以正常插入,以及插入数据的正确性。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器