MySQL

37-触发器

2022-09-19  本文已影响0人  紫荆秋雪_文

一、触发器作用

在实际开发中,我们经常会遇到这样的情况:有2个或者多个相互关联的表,如商品信息库存信息分别放在2个不同的数据库中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在库存表中添加一条库存记录。这样一来,我们就必须把这两个关联的操作步骤写到程序里面,而且要用事务包裹起来,确保这两个操作成为一个原子操作,要么全部执行,要么全部不执行。要是遇到特殊情况,可能还需要对数据进行手动维护,这样就很容易忘记其中的一步,导致数据缺失。这个时候,可以使用触发器。可以创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作。这样一来,就不用担心因为忘记添加库存数据而导致的数据缺失了

二、触发器的概述

MySQL的触发器和存储过程一样,都是嵌入到MySQL服务器的一段程序。触发器是由 事件来触发 某个操作,这些事件包括 INSERTUPDATEDELETE 事件。所谓事件就是指
用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句时候,就相当于事件发生了,就会 自动 激发触发器执行相应的操作。

三、触发器的创建

1、触发器创建的语法

CREATE TRIGGER 触发器名称 
{BEFORE|AFTER} 
{INSERT|UPDATE|DELETE} ON 表名 
FOR EACH ROW 
触发器执行的语句块;

四、实战

1、实战1

创建触发器:创建名称为 before_insert 的触发器,向test_trigger数据表插入数据之前,向test_trigger_log数据表中插入before_insert的日志信息

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)
);
DELIMITER $
CREATE TRIGGER before_insert
    BEFORE INSERT
    ON test_trigger
    FOR EACH ROW
BEGIN
    INSERT INTO test_trigger_log(t_log) VALUES ('before_insert');
END $
DELIMITER ;
INSERT INTO test_trigger (t_note)
VALUES ('测试 BEFORE INSERT 触发器');
SELECT *
FROM test_trigger_log;

SELECT *
FROM test_trigger;

2、实战2

定义触发器“salary_check_trigger”,基于员工表“employees”的INSERT事件,在INSERT之前检查将要添加的新员工薪资是否大于他领导的薪资,如果大于领导薪资,则报sqlstate_value为'HY000'的错误,从而使得添加失败

DELIMITER $
CREATE TRIGGER salary_check_trigger
    BEFORE INSERT
    ON emp
    FOR EACH ROW
BEGIN
    DECLARE mgr_salary DOUBLE DEFAULT 0;
    SELECT salary INTO mgr_salary FROM emp WHERE id = new.mng_id;

    IF new.salary > mgr_salary THEN
        SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪资高于领导薪资错误';
    END IF;
END $
DELIMITER ;
INSERT INTO emp (id, name, mng_id, salary)
VALUES (301, 'Raven-02', 101, 19000);

3、实战3

创建删除触发器,无论是代码删除还是物理直接删除都可以监听到


DELIMITER $
CREATE TRIGGER delete_trigger
    AFTER DELETE
    ON emp
    FOR EACH ROW
BEGIN
    DECLARE mgr_salary DOUBLE DEFAULT 0;
    SELECT salary INTO mgr_salary FROM emp WHERE id = old.mng_id;

    IF old.salary < mgr_salary THEN
        SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪资低于领导薪资错误';
    END IF;
END $
DELIMITER ;
DELETE
FROM emp
WHERE id = 302;
image.png

五、查看触发器

查看触发器是查看数据库中已经存在的触发器的定义、状态和语法信息等

SHOW TRIGGERS\G
SHOW CREATE TRIGGER 触发器名
SELECT * FROM information_schema.TRIGGERS

六、触发器的优缺点

1、优点

1、触发器可以确保数据的完整性
2、触发器可以帮助我们记录操作日志。
3、触发器还可以用在操作数据前,对数据进行合法性检查。

2、缺点

1、触发器最大的一个问题就是可读性差。
2、相关数据的变更,可能会导致触发器出错。

3、注意点

mysql> update demo.membermaster set memberdeposit=20 where memberid = 2; 
ERROR 1054 (42S22): Unknown column 'aa' in 'field list'

但是此时不会激活触发器t1。只有直接对子表员工表(t_employee)执行DELETE语句时才会激活触发器
t1。

上一篇下一篇

猜你喜欢

热点阅读