【MySQL】变量、流程控制

一、变量

在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()BEGINSET @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_codeDECLARE 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.mzph.cn/news/689896.shtml

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

相关文章

【前端素材】bootstrap5实现房产信息网HomeFi平台(附源码)

一、需求分析 房产信息网是一个在线平台,专门提供房地产相关信息的网站。这些网站通常为买家、卖家、租客、房地产经纪人等提供各种房产信息,包括可售房屋、出租房源、房价走势、地产市场分析、房产投资建议等内容。以下是房产信息网的主要功能和特点: 房源信息浏览:用户可…

【lesson60】网络基础

文章目录 网络发展认识协议网络协议初识OSI七层模型TCP/IP五层(或四层)模型网络传输基本流程数据包封装和分用网络中的地址管理 网络发展 以前没有网络剧的工作模式是:独立模式:,计算机之间相互独立 所以多个计算机要协同开发比较难。 有了网络以后&am…

6.s081 学习实验记录(九)lock parallelism

文章目录 一、Memory allocator简介提示实验代码实验结果 二、Buffer cache简介提示实验代码实验结果 该实验将重构某些代码以提高并发度。 首先切换到lock分支: git fetchgit checkout lockmake clean 一、Memory allocator 简介 user/kalloctest 这个程序会对…

关于投资,房地产,AI

各位朋友,新年好! 过个年,世界发生了很多大事! 投资 先是证监会,证监会年前换帅,吴清接棒,吴清何许人也?江湖人称“券商屠夫”,成功处置了2008年的券商风险&#xff0…

Eclipse - Format Comment

Eclipse - Format & Comment 1. Correct Indentation2. Format3. Toggle Comment4. Add Block Comment5. Remove Block CommentReferences 1. Correct Indentation Ctrl A: 选择全部代码 Ctrl I: 校正缩进 or right-click -> Source -> Correct Indentation 2. F…

【开工大吉】推荐4款开源、美观的WPF UI组件库

WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、数据绑定、样式和模板、动画效果等功能,让开发者可以创建出吸引人且交互性强的应用程序。 HandyControl HandyControl是一套WPF控件库&#xf…

安全技术和防火墙

1.安全技术和防火墙 1.1安全技术 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报警和事后监督为主,提供有针对性的指导措施和安全决…

普中51单片机学习(九)

蜂鸣器 蜂鸣器简介 在单片机应用的设计上,很多方案都会用到蜂鸣器,大部分都是使用蜂鸣器来做提示或报警,比如按键按下、开始工作、工作结束或是故障等等。改变单片机引脚输出波形的频率,就可以调整控制蜂鸣器音调,产…

Python操作Kafka基础教程

01 Python操作Kafka基础教程 创建ZooKeeper容器 docker run -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper创建Kafka容器 语法是: docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID0 -e KAFKA_ZOOKE…

世界顶级名校计算机专业,都在用哪些书当教材?(文末送书)

目录 01《深入理解计算机系统》02《算法导论》03《计算机程序的构造和解释》04《数据库系统概念》05《计算机组成与设计:硬件/软件接口》06《离散数学及其应用》07《组合数学》08《斯坦福算法博弈论二十讲》参与规则 清华、北大、MIT、CMU、斯坦福的学霸们在新学期里…

讨好型人格的职业分析,如何改变讨好型人格

一味讨好他人,忽略自己感受,凡事以人为先,忽视自己需求,这就是讨好型人格。 讨好型人格最典型的表现就是非常注重外界的看法,不管做什么事都会小心翼翼,生怕自己所做的事会引发别人的不满。 如果自己哪方…

MAC电脑系统清理空间免费版软件CleanMyMac X2024

大家好,我是那个总是被苹果电脑“内存已满”提示搞得焦头烂额的专业博主。如果你也像我一样,在使用Mac时经常遭遇卡顿、慢吞吞的情况,那么今天的Mac清理空间妙招分享绝对适合你! CleanMyMac X全新版下载如下: https://wm.makedi…

【Redis快速入门】深入解读哨兵模式

个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻‍❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…

HTML 入门指南

简述 参考:HTML 教程- (HTML5 标准) HTML 语言的介绍、特点 HTML:超级文本标记语言(HyperText Markup Language) “超文本” 就是指页面内可以包含图片、链接等非文字内容。“标记” 就是使用标签的方法将需要的内容包括起来。…

电阻(二):希尔伯特(Hilbert)曲线

1、Hilbert简介 希尔伯特曲线是一种能在 2D平面完美填充正方形的曲线,连续且稳定(当细分足够小时,线构成面)而又不可导的曲线。只要恰当选择函数,画出一条连续的参数曲线,当参数 t 在 [0、1 ] 区间取值时&a…

ESP32-Cam学习(2)——PC实时显示摄像头画面

具体代码和操作过程见: 3. 实时显示摄像头画面 (itprojects.cn)https://doc.itprojects.cn/0006.zhishi.esp32/02.doc/index.html#/e03.showvideo我主要记录一下我在复现的过程中,遇到的问题以及解决方法。 1.安装第三方库 首先电脑端的代码需要用pych…

备战蓝桥杯---动态规划(入门3之子串问题)

本专题再介绍几种经典的字串问题。 这是一个两个不重叠字串和的问题,我们只要去枚举分界点c即可,我们不妨让c作为右区间的左边界,然后求[1,c)上的单个字串和并用max数组维护。对于右边,我们只要反向求单个字串和然后选左边界为c的…

java中x++和++x的区别,执行后x的值是多少

在Java和C等编程语言中,x 和 x 都是用来对变量 x 进行自增操作的表达式,它们的主要区别在于自增操作发生的时机以及返回值: 后置递增运算符 x: 先使用当前 x 的值进行表达式计算,然后将 x 的值加 1。 执行后的 x 值为…

django连接本地数据库并执行增删改查

1,首先需要将本地数据库的表同步到django的models.py文件 py manage.py inspectdb tb_books tb_heros > demo001/models.py 2,同步成功后models.py会根据每张表映射出不同的类 models.py文件根据数据库表映射出对应的类 3,然后根据不同…

初识 Rust 语言

目录 前言一、Rust 的背景二、Rust的特性三、部署开发环境,编写一个简单demo1、在ubuntu 20.04部署环境2、编写demo测试 四、如何看待Linux内核引入Rust 前言 自Linux 6.1起,初始的Rust基础设施被添加到Linux内核中。此后为了使内核驱动程序能够用Rust编…