当前位置:网站首页>MySQL 触发器
MySQL 触发器
2022-07-16 14:11:00 【陈弋辛】
在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信息 分别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在库存表中添加一条库存记录。
1. 触发器概述
2. 触发器的创建
2.1 创建触发器语法
CREATE TRIGGER 触发器名称{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名FOR EACH ROW触发器执行的语句块;
2.2 代码举例
举例1:
1、创建数据表:
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)
);# 2、创建触发器:创建名称为before_insert的触发器,向test_trigger数据表插入数据之前,
# 向test_trigger_log数据表中插入before_insert的日志信息。
DELIMITER //
CREATE TRIGGER before_insert
BEFORE INSERT ON test_trigger
FOR EACH ROW
BEGIN
INSERT INTO test_trigger_log(t_log)
VALUES ('before into ...');
END //
DELIMITER ;# 3、向test_trigger数据表中插入数据
INSERT INTO test_trigger(t_note)
VALUES (' 测试 before into 触发器');
# 举例2: 创建名称为after_insert的触发器,向test_trigger数据表插入数据之后,
# 向test_trigger_log数据表中插入after_insert的日志信息。
CREATE TRIGGER after_insert
AFTER INSERT ON test_trigger
FOR EACH ROW
INSERT INTO test_trigger_log(t_log)
VALUES ('after insert ...');
INSERT INTO test_trigger(t_note)
VALUES('测试 after insert 触发器');
SELECT * FROM test_trigger;
SELECT * FROM test_trigger_log;
# 举例3:定义触发器“salary_check_trigger”,基于员工表“employees”的INSERT事件,
# 在INSERT之前检查将要添加的新员工薪资是否大于他领导的薪资,
# 如果大于领导薪资,则报sqlstate_value为'HY000'的错误,从而使得添加失败。
# 准备工作
CREATE TABLE employees
AS
SELECT * FROM atguigudb.`employees`;
CREATE TABLE departments
AS
SELECT * FROM atguigudb.`departments`;
DESC employees;
#创建触发器
DELIMITER //
CREATE TRIGGER salary_check_trigger
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
#查询到要添加的数据的manager的薪资
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 ;
#测试
#添加成功:依然触发了触发器salary_check_trigger的执行
INSERT INTO employees(employee_id,last_name,email,hire_date,job_id,salary,manager_id)
VALUES(300,'Tom','[email protected]',CURDATE(),'AD_VP',8000,206);
# 1644 - 薪资高于领导薪资错误
INSERT INTO employees(employee_id,last_name,email,hire_date,job_id,salary,manager_id)
VALUES(301,'Tom2','[email protected]',CURDATE(),'AD_VP',9000,206);
SELECT * FROM employees;
上面触发器声明过程中的NEW关键字代表INSERT添加语句的新记录。
还有OLD表示原有的数据记录。
3. 查看、删除触发器
3.1 查看触发器
方式1:查看当前数据库的所有触发器的定义
SHOW TRIGGERS\G
方式2:查看当前数据库中某个触发器的定义
SHOW CREATE TRIGGER 触发器名
方式3:从系统库information_schema的TRIGGERS表中查询
SELECT * FROM information_schema.TRIGGERS;
3.2 删除触发器
DROP TRIGGER [IF EXISTS] 触发器名称;
4. 触发器的优缺点
4.1 优点
1、触发器可以确保数据的完整性。


2、触发器可以帮助我们记录操作日志。
3、触发器还可以用在操作数据前,对数据进行合法性检查。
4.2 缺点
1、触发器最大的一个问题就是可读性差。
update demo.membermaster set memberdeposit=20 where memberid = 2;
#ERROR 1054 (42S22): Unknown column 'aa' in 'field list'结果显示,系统提示错误,字段“aa”不存在。 这是因为,触发器中的数据插入操作多了一个字段,系统提示错误。可是,如果你不了解这个触发器,很可能会认为是更新语句本身的问题,或者是会员信息表的结构出了问题。说不定你还会给会员信息表添加一个叫“aa”的字段,试图解决这个问题,结果只能是白费力。
2、相关数据的变更,可能会导致触发器出错。
4.3 注意点
5.练习
5.1 练习1
#0. 准备工作
CREATE TABLE emps
AS
SELECT employee_id,last_name,salary
FROM atguigudb.`employees`;1. 复制一张emps表的空表emps_back,只有表结构,不包含任何数据
#1. 复制一张emps表的空表emps_back,只有表结构,不包含任何数据
CREATE TABLE emps_back
AS
SELECT *
FROM emps
WHERE employee_id = 0;2. 查询emps_back表中的数据
#2. 查询emps_back表中的数据
SELECT * FROM emps_back;
3. 创建触发器emps_insert_trigger,每当向emps表中添加一条记录时,同步将这条记录添加到emps_back表中
#3. 创建触发器emps_insert_trigger,每当向emps表中添加一条记录时,
# 同步将这条记录添加到emps_back表中
DELIMITER //
CREATE TRIGGER emps_insert_trigger
AFTER INSERT ON emps
FOR EACH ROW
BEGIN
INSERT INTO emps_back(employee_id,last_name,salary)
VALUES (NEW.employee_id,NEW.last_name,NEW.salary);
END //
DELIMITER ;
4. 验证触发器是否起作用
#4. 验证触发器是否起作用
INSERT INTO emps VALUES(300,'Tom',5600);
SELECT * FROM emps_back; #300 Tom 5600.005.2 练习2
1. 复制一张emps表的空表emps_back1,只有表结构,不包含任何数据
# 练习2
#1. 复制一张emps表的空表emps_back1,只有表结构,不包含任何数据
CREATE TABLE emps_back1
AS
SELECT *
FROM emps
WHERE 1 = 2;
2. 查询emps_back1表中的数据
#2. 查询emps_back1表中的数据
SELECT * FROM emps_back1; # NULL NULL NULL
3. 创建触发器emps_del_trigger,每当向emps表中删除一条记录时,同步将删除的这条记录添加到emps_back1表中
#3. 创建触发器emps_del_trigger,每当向emps表中删除一条记录时,
# 同步将删除的这条记录添加到emps_back1表中
DELIMITER //
CREATE TRIGGER emps_del_trigger
BEFORE DELETE ON emps
FOR EACH ROW
BEGIN
INSERT INTO emps_back1(employee_id,last_name,salary)
VALUES (OLD.employee_id,OLD.last_name,OLD.salary);
END //
DELIMITER ;
4. 验证触发器是否起作用
#4. 验证触发器是否起作用
DELETE FROM emps
WHERE employee_id = 100;
SELECT * FROM emps_back1; # 100 King 24000.00边栏推荐
- Log4j log configuration
- [PaddleSeg源码阅读] 关于PaddleSeg模型返回的都是list这件小事
- 云原生(三十五) | Prometheus入门和安装
- 三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里
- JD finance, are you bad, or are you cutting too much??
- 【Ucos-III源码分析】——事件标志组
- [动态规划]DP20 计算字符串的编辑距离-中等
- 2022.7.15-----leetcode.558
- About STM32 driving LCD display screen, the solution to the problem that the white screen and disordered code need to be powered on and reset to return to normal after the program is downloaded
- Basic operation of queue
猜你喜欢

Use plt When the savefig() method saves the drawing, the picture is all white or all black

MySQL super detailed installation tutorial will teach you to install Mysql to use the simplest MySQL installation method of MySQL. This method is also simple to install and uninstall

Xray安装使用

鸿湖万联致远开发板正式合入OpenHarmony主干
![[graduation project] network public opinion hotspot analysis system based on Emotional Analysis](/img/b6/c297f9b81446d8b2d0220c5f8774b5.png)
[graduation project] network public opinion hotspot analysis system based on Emotional Analysis

rman异机恢复后,报错ora-01017

(Note)七彩虹30系列显卡——《一键超频》按键

Leetcode 49. 字母异位词分组

2022 latest Tianjin Construction Safety Officer simulation question bank and answers
![P1789 [MC survival] torch [introduction]](/img/3d/8fec5832a42762ceb534f4239173b0.jpg)
P1789 [MC survival] torch [introduction]
随机推荐
Anaconda 的认识以及和它相关的一些编辑器的简单介绍
2022.7.14-----leetcode.745
腾讯四面面经,问傻了
华为影像XMAGE:求尽世间像,终见菩提心
2022 latest Tianjin Construction Safety Officer simulation question bank and answers
L'art de l'annotation de code, un bon Code n'a - t - il vraiment pas besoin d'annotation?
canvas绘制的线条位置错乱
PNAS | 南农张瑞福组揭示了微生物肥料功能菌根际趋化的信号识别新机制
Web crawler realizes sending SMS verification code
nn. BCEWithLogisticLoss() & nn. The difference between bceloss(), nn CrossEntropyLoss() & nn. Nllloss() differences
【C#】正序、逆序、最大值、最小值和平均值
自己第一次正畸情况(持续更新中)
Error ora-01017 is reported after RMAN recovers
集合(Properties)
uCOS-III学习笔记——软件定时器
准确率100%,阿里商旅账单系统架构设计实践
【Ucos-III源码分析】——互斥信号量(互斥锁)
动态内存管理(C语言)详细总结
Data visualization: plotting pie chart with Matplotlib
Package C language files into exe executable programs