写在前面: 跟随B站的康师傅学习mysql的笔记摘要和自我总结。
1、为什么要使用触发器?
在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如商品信息 和库存信息 分别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性 ,必须同时在库存表中添加一条库存记录。
这样一来,我们就必须把这两个关联的操作步骤写到程序里面,而且要用事务 包裹起来,确保这两个操作成为一个原子操作 ,要么全部执行,要么全部不执行。要是遇到特殊情况,可能还需要对数据进行手动维护,这样就很容易忘记其中的一步 ,导致数据缺失。
这个时候,就可以使用触发器。我们可以创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作。 这样一来,就不用担心因为忘记添加库存数据而导致的数据缺失了。
2、创建触发器语法
创建触发器的语法结构是:
CREATE TRIGGER 触发器名称
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名
FOR EACH ROW
触发器执行的语句块;
说明:
表名 :表示触发器监控的对象。BEFORE|AFTER :表示触发的时间。BEFORE 表示在事件之前触发;AFTER 表示在事件之后触发。INSERT|UPDATE|DELETE :表示触发的事件。
- INSERT 表示插入记录时触发;
- UPDATE 表示更新记录时触发;
- DELETE 表示删除记录时触发。
触发器执行的语句块 :可以是单条SQL语句,也可以是由BEGIN…END结构组成的复合语句块。
代码举例:
先简单创建两个表
CREATE TABLE test_trigger (
id INT PRIMARY KEY AUTO_INCREMENT,
t_note VARCHAR(30)
);
CREATE TABLE test_trigger_log (
id INT PRIMARY KEY AUTO_INCREMENT,
t_log VARCHAR(30)
);
案例1:
CREATE TRIGGER before_insert
BEFORE INSERT ON test_trigger
FOR EACH ROW
INSERT INTO test_trigger_log(t_log) VALUES('beforeInsert');
INSERT INTO test_trigger(t_note) VALUES('test 2');
SELECT * FROM test_trigger;
SELECT * FROM test_trigger_log;
查询结果:
+
| id | t_note |
+
| 1 | test 2 |
+
+
| id | t_log |
+
| 1 | beforeInsert |
+
案例2:
DELIMITER $
CREATE TRIGGER salary_check_trigger
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
DECLARE mgr_sal DOUBLE;
SELECT salary INTO mgr_sal FROM employees WHERE employee_id = NEW.manager_id;
IF NEW.salary > mgr_sal
THEN SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪资高于领导薪资错误';
END IF;
END $
DELIMITER ;
DESC employees;
当添加新员工的工资不满足上述条件时,代码演示:
INSERT INTO employees
VALUES(301,'A','B','C','D','2021-12-14','F',50000,NULL,205,110);
因为该新员工的领导(employee_id是205) 的工资是12000,所以:上述代码就会执行失败,报“错误代码:1644 薪资高于领导薪资错误” 的错误!!!
3、查看触发器
方式1:查看当前数据库的所有触发器的定义
SHOW TRIGGERS;
方式2:查看当前数据库中某个触发器的定义
SHOW CREATE TRIGGER 触发器名
方式3:从系统库information_schema的TRIGGERS表中查询触发器的信息。
SELECT * FROM information_schema.TRIGGERS;
4、 删除触发器
DROP TRIGGER IF EXISTS 触发器名称;
爱在结尾:总体来说,触发器这一章节并不难,重点需要记住的就是创建触发器的语法了;触发器的删除、查看,就很容易了。
|