【MySQL】变量、流程控制

news2025/1/18 6:57:50

一、变量

在MySQL的存储过程与函数中,可以使用变量来存储查询或计算的中间结果数据,或者输出最终的结果数据。它可以分为用户自定义变量系统变量

1、系统变量

1)系统变量分为全局变量(需要使用关键字global)和会话系统变量(需要使用关键字session),如果没有声明global,那默认是session级别的变量

  • 全局系统变量对所有会话(连接)都有效,但是重启后就会重置
  • 会话系统变量仅针对当前会话(连接)有效。会话期间,当前会话对某个会话系统变量的修改,并不会影响其他会话中同一会话系统变量的值。而且会话重新连接之后,变量值也会重置
  • 会话1修改了某个全局系统变量会影响到会话2中同一全局系统变量

2)MySQL中有些变量只能是全局系统变量,例如max_connection用于限制服务器的最大连接数
有些系统变量既可以是全局的又可以是会话级别的,如character_client_set用于设置客户端的字符集
有些系统变量只能是会话级别的,例如pseudo_thread_id用于标记当前会话的MySQL连接id

3)查看系统变量

# 查看所有全局变量
SHOW GLOBAL VARIABLES;

# 查看所有会话变量
SHOW SESSION VARIABLES;
或者
SHOW VARIABLES;

# 查看满足条件的部分全局系统变量
SHOW GLOBAL VARIABLES LIKE '%标识符%';

# 查看满足条件的部分会话系统变量
SHOW SESSION VARIABLES LIKE '%标识符%';
或者
SHOW VARIABLES LIKE '%标识符%';

# 查看指定全局系统变量
SELECT @@global.变量名;

# 查看指定会话系统变量
SELECT @@session.变量名;
或者
SELECT @@变量名;  #不声明全局还是会话级别的情况下,会先去会话系统变量中找,如果没有再去全局系统变量中找

4)修改系统变量

  • 方式一:修改MySQL的配置文件,但是需要重启服务
  • 方式二:使用set命令重新设置系统变量的值
# 修改全局系统变量值
SET @@global.变量名 = 变量值;
或者
SET GLOBAL 变量名 = 变量值;

# 修改会话系统变量值
SET @@session.变量名 = 变量值;
或者
SET SESSION 变量名 = 变量值;

2、用户变量

1)用户变量是用户自己定义的,MySQL中用户变量以@开头进行定义。根据作用范围的不同分为会话用户变量局部变量

  • 会话用户变量:作用域和会话变量一样,只对当前连接会话有效。注意和会话系统变量区分开
  • 局部变量:只在BEGIN和END语句块中有效,只能在存储过程和函数中使用

2)会话用户变量的使用

声明和赋值

# 方式一:使用=或者:=
SET @用户变量 =;
SET @用户变量 :=;

# 方式二:使用:=或者INTO关键字,就相当于在查询语句中插入一段用户变量的声明,方式二不能使用=
SELECT @用户变量 := 表达式 [FROM 等子句];
SELECT 表达式 INTO @用户变量 [FROM 等子句];
#例如
SELECT @A1 := COUNT(*) FROM t_test;
SELECT AVG(salary) INTO @A2 FROM t_employee;

查询

SELECT @用户变量;

3)局部变量

  • 相关关键字:使用关键字DECLARE进行定义,使用SET进行赋值,使用SELECT进行查询
  • 作用域:仅在定义它的BEGIN...END之间有效,即存储过程、函数中
  • 位置:只能放在BEGIN...END中,且只能放在第一句

定义变量,如果不声明默认值,那么初始值为null

DECLARE 变量名 类型 [default]; 
例如
DECLARE v1 INT DEFAULT 100;

变量赋值

# 方式一:使用=或者:=
SET 局部变量 =;
SET 局部变量 :=;

# 方式二:使用INTO关键字,就相当于在查询语句中插入一段用户变量的声明
SELECT 字段或表达式 INTO 局部变量 FROM;
#例如
SELECT AVG(salary) INTO A2 FROM t_employee;

变量的使用

SELECT 局部变量名;

它是怎么在存储过程、函数中进行使用的呢?

DELIMITER $

CREATE PROCEDURE test_var()
BEGIN
	# 变量声明,如果a,b默认值都是0,可以使用DECLARE a,b INT DEFAULT 0来声明
	DECLARE a INT DEFAULT 0;
	DECLARE b INT;
	DECLARE c VARCHAR(25);

	# 变量赋值
	SET a = 1;
	SET b := 2;
	SELECT emp_name INTO c FROM t_emp WHERE emp_id = 101;

	# 变量使用
	SELECT a,b,c;
END $

DELIMITER ;

# 调用存储过程
CALL test_var();

4)用户变量(包括会话用户变量、局部变量)和系统变量的区别

  • 声明方面:
    • 用户变量:
      • 会话用户变量的声明和使用需要带一个@
      • 局部变量不需要带@,但是局部变量的定义需要使用关键字DECLAER
    • 系统变量如果使用时带@符号需要带2个
  • 定义位置:
    • 会话用户变量可以定义在任何地方
    • 局部变量只能放在BEGIN...END中,且只能放在第一句
  • 作用域:
    • 会话用户变量:当前会话
    • 局部变量:定义它的BEGIN...END

二、定义条件与处理程序

定义条件:指事先定义程序执行过程中可能遇到的问题
处理程序:定义了在遇到问题之后的处理方式,保证了存储过程或者存储函数在遇到警告或者错误时能继续执行,增强了其处理问题的能力,避免程序因异常停止运行

定义条件处理程序存储函数、存储过程中都是支持的

1、定义条件

假设我们有一个学生表t_student
它有2个字段,stu_id和stu_name,其中stu_id在声明的时候就加了非空约束

DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student`  (
  `stu_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学生id',
  `stu_name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '学生姓名'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


INSERT INTO `t_student` VALUES ('001', 'jack');
INSERT INTO `t_student` VALUES ('002', 'rose');

按照我们的认知,加了非空限制的字段不管是更新还是新增,都不应该支持null做值
但是,我测试的时候发现了一个很神奇的现象
这里的stu_id被我更新成null了!!
在这里插入图片描述
后来排查一番发现是我的MySQL数据库缺少STRICT_TRANS_TABLES(严格模式)配置
改完再重启mysql服务就好了
在这里插入图片描述
在这里插入图片描述

言归正传,我们声明一个存储过程,将t_student中的stu_id更新为null

DELIMITER //
CREATE PROCEDURE testExecption()
	BEGIN
		SET @X = 1;
		UPDATE t_student set stu_id = NULL where stu_name = 'jack';
		SET @X = 2;
		UPDATE t_student set stu_id = '001' where stu_name = 'jack';
		SET @X = 3;
	END //
DELIMITER ;

# 调用存储过程
call testExecption();

# 查询变量X
select @X;

调用存储过程,发现报错如下
在这里插入图片描述
在这里插入图片描述
这里的1048和23000就是错误码
1048是MySQL_error_code,他是数值类型错误代码
23000是sqlstate_value,它是长度为5的字符串类型错误代码

1)定义条件就是给MySQL中错误码命名。它将一个错误名字指定的错误条件进行关联
这个名字可以随后被用在定义处理程序的DECALRE HANDLER语句中,

定义条件不是必要的,只有在处理程序中需要用到的时候才要去定义

定义条件使用DECLARE关键字,语法为

DECLARE 错误名称 CONDITION FOR 错误码(或者错误条件);

举例:我们现在要使用Field_Not_Be_Null这个错误名称来与MySQL中违反非空约束的错误类型ERROR 1048 (23000)进行对应

# 方式一:使用MySQL_error_code
DECLARE Field_Not_Be_Null CONDITION FOR 1048;
# 方式二:使用sqlstate_value
DECLARE Field_Not_Be_Null CONDITION FOR SQLSTATE '23000';

2、定义处理程序

1)定义语法

DECLARE 处理方式 HANDLER FOR 错误类型 处理语句;

处理方式:

  • CONTINUE:遇到指定的错误类型不处理,继续往下执行
  • EXIT:遇到指定的错误类型马上退出
  • UNDO:遇到指定的错误类型撤回之前的操作,MySQL中暂时不支持

错误类型:

  • MySQL_error_code
  • sqlstate_value
  • 错误名称:上面定义条件里声明的错误名称
  • SQLWARNING:匹配所有01开头的sqlstate错误码
  • NOT FOUND:匹配所有02开头的sqlstate错误码
  • SQLEXCEPTION:匹配所有没被SQLWARNING和NOT FOUND捕获的sqlstate错误码

处理语句:

  • 可以是SET 变量 = 值这样的简单语句
  • 也可以是BEGIN...END编写的符合语句

接下来,我们看下如何使用上面说的6种错误类型来定义处理程序

# 捕获MySQL_error_code
DECLARE CONTINUE HANDLER FOR 1048 SET @result = 'Column stu_id cannot be null';

# 捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @result = 'Column stu_id cannot be null';

# 先定义条件,再调用错误类型
DECLARE Field_Not_Be_Null CONDITION FOR 1048;
DECLARE CONTINUE HANDLER FOR Field_Not_Be_Null SET @result = 'Column stu_id cannot be null';

# 使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @result = 'Column stu_id cannot be null';

# 使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @result = 'Column stu_id cannot be null';

# 使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @result = 'Column stu_id cannot be null';

2)案例处理
掌握了定义条件与处理程序之后
我们怎么处理上面更新t_student中stu_id为null时执行报错的问题呢

DROP PROCEDURE testExecption;

# 重新定义存储过程,体现错误的处理程序
DELIMITER //
CREATE PROCEDURE testExecption()
	BEGIN
		# 在开始就声明处理程序
		# 方式一:如果是使用错误名称,需要先定义条件
		# DECLARE Field_Not_Be_Null CONDITION FOR 1048;
		# DECLARE CONTINUE HANDLER FOR Field_Not_Be_Null SET @result = 'Column stu_id cannot be null';
		# 方式二:捕获sqlstate_value
		# DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @result = 'Column stu_id cannot be null';
		# 方式三:捕获MySQL_error_code
		DECLARE CONTINUE HANDLER FOR 1048 SET @result = 'Column stu_id cannot be null';
		SET @X = 1;
		UPDATE t_student set stu_id = NULL where stu_name = 'jack';
		SET @X = 2;
		UPDATE t_student set stu_id = '001' where stu_name = 'jack';
		SET @X = 3;
	END //
DELIMITER ;

# 调用存储过程
call testExecption();

# 查询变量X和result
select @X,@result;

执行结果如下
在这里插入图片描述

如有错误,欢迎指正!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1455693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(boost库的使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 作为c程序员来说,除了qt之外,另外值得学的开发库就是boost。boost本身包含的内容非常多,基本我们常用的功能都已…

linux下ffmpeg调用GPU硬件解码(VDPAU/VAAPI)保存文件

本文讲解在linux下面,如何通过ffmpeg调用GPU硬件解码,并保存解码完的yuv文件。 其实,ffmpeg自带的例子hw_decode.c这个文件,就已经能满足要求了,因此,本文就尝试讲解以下hw_decode这个例子。hw_decode.c可以…

使用vscode传入参数的方式进行debug

使用vscode传入参数的方式进行debug {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0","configurations": [{&quo…

【AGI视频】Sora的奇幻之旅:未来影视创作的无限可能

在五年后的未来,科技的发展为影视创作带来了翻天覆地的变化。其中,Sora视频生成软件成为了行业的翘楚,引领着全新的创作潮流。Sora基于先进的Transformer架构,将AI与人类的创造力完美结合,为观众带来了前所未有的视听盛…

【分享】windows11 vmware centos7 搭建k8s完整实验

概述 开年第一天,补充下自己的技术栈。 参考文章: k8s安装 - 知乎 【Kubernetes部署篇】K8s图形化管理工具Dasboard部署及使用_k8s可视化管理工具-CSDN博客 centos7环境下安装k8s 1.18.0版本带dashboard界面全记录(纯命令版)_sysconfig1.…

通俗易懂地解释OpenAI Sora视频生成的特点有哪些?与Runway Gen2、Pika有什么区别?缺点是什么?

OpenAI的Sora模型是最近两天最火热的模型。它生成的视频无论是清晰度、连贯性和时间上都有非常好的结果。在Sora之前,业界已经有了很多视频生成工具和平台。但为什么Sora可以引起如此大的关注?Sora生成的视频与此前其它平台生成的视频到底有哪些区别&…

MATLAB知识点:meshgrid函数(★★★★☆)返回二维网格坐标(在MATLAB中经常用于生成绘制三维图的数据)

讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 节选自第3章:课后习题讲解中拓展的函数 在讲解第三…

入门级10寸加固行业平板—EM-I10J

亿道信息以其坚固耐用的智能终端设备而闻名,近日发布了一款理想入门级 10 英寸加固平板电脑—I10J。 EM-I10J​​ 这是一款 10 英寸的平板电脑,主要运行 Windows 10操作系统,带有硬化塑料外壳,具有 IP65 防水防尘功能和 MIL-STD 8…

踩坑实录(Fourth Day)

今天开工了,其实还沉浸在过年放假的喜悦中……今天在自己写 Vue3 的项目,虽说是跟着 B 站在敲,但是依旧是踩了一些个坑,就离谱……照着敲都能踩到坑,我也是醉了…… 此为第四篇(2024 年 02 月 18 日&#x…

2024免费版EasyRecovery软件有哪些功能限制?

EasyRecovery软件的主要功能包括: 数据恢复:这是EasyRecovery软件的核心功能。它可以恢复因各种原因丢失或删除的数据,无论是由于磁盘格式化、文件删除还是其他因素。EasyRecovery使用高级的数据恢复算法,能够快速扫描整个磁盘&a…

python绘制k线图均线图

AAPL.csv 数据文件 Date,Close,Volume,Open,High,Low 06/23/2023,$186.68,53117000,$185.55,$187.56,$185.01 06/22/2023,$187.00,51245330,$183.74,$187.045,$183.67 06/21/2023,$183.96,49515700,$184.90,$185.41,$182.5901 06/20/2023,$185.01,49799090,$184.41,$1…

互联网加竞赛 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习多目标跟踪 …

基于Doris构建亿级数据实时数据分析系统

背景 随着公司业务快速发展,对业务数据进行增长分析的需求越来越迫切,与此同时我们的业务数据量也在快速激增、每天的数据新增量大概在30w 左右,一年就会产生1 个亿的数据,显然基于传统MySQL数据库已经无法支撑满足以上需求 基于上…

《Linux 简易速速上手小册》第2章: 命令行的艺术(2024 最新版)

文章目录 2.1 基本 Linux 命令2.1.1 重点基础知识2.1.2 重点案例:整理下载文件夹2.1.3 拓展案例 1:批量重命名文件2.1.4 拓展案例 2:查找并删除特定文件 2.2 文件和目录管理2.2.1 重点基础知识2.2.2 重点案例:部署一个简单的网站2…

RabbitMQ鉴权设计以及相关探讨

文章目录 1. rabbitmq的鉴权设计2. rabbitmq鉴权应用范围3. rabbitmq鉴权的常用方法3.1 用户管理3.2 角色管理3.3 权限管理 4. 默认鉴权4.1 默认用户4.2 默认角色 5. 参考文档 鉴权,分别由鉴和权组成 鉴: 表示身份认证,认证相关用户是否存在…

AlexNet的出现推动深度学习的巨大发展

尽管AlexNet(2012)的代码只比LeNet(1998)多出几行,但学术界花了很多年才接受深度学习这一概念,并应用其出色的实验结果。 AlexNet(由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton共同设计…

Docker原理及概念相关

Docker最核心的组件 image:镜像,构建容器,也可以通过Dockerfile文本描述镜像的内容。 (我们将应用程序运行所需的环境,打包为镜像文件) Container:容器 (你的应用程序,就跑在容器中 ) 镜像仓库(dockerhub)(…

Java学习笔记2024/2/18

1.API 1.1API概述 什么是API API (Application Programming Interface) :应用程序编程接口 java中的API 指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这…

kali无线渗透之蓝牙原理与探测与侦听

“传统蓝牙”规范在2.4GHz的ISM波段上定义了79个信道,每个信道有1MHz的带宽。设备在这些信道中以每秒1600次的频率进行跳转,换句话说,就是每微秒625次跳转。这项信道跳转技术被称为“跳频扩频”(Frequency HoppingSpread Spectrum&#xff0c…

电路设计(20)——数字电子钟的multism仿真

1.设计要求 使用数字芯片,设计一个电子钟,用数码管显示,可以显示星期,时、分、秒,可以有按键校准时间。有整点报警功能。 2.设计电路 设计好的multism电路图如下所示 3.芯片介绍 时基脉冲使用555芯片产生。在仿真里面…