【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.rhkb.cn/news/259439.html

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

相关文章

JRT监听-PDF-Excel-Img

依赖全新设计,我们无需再顾虑历史兼容性的束缚;同时,基于多年来累积的深入需求理解,JRT监听机制巧妙地借助CMD命令模式,达成了监听的全面统一。无论是PDF、Excel还是图片文件,都不再需要特殊对待或额外区分…

unity学习(15)——服务器组装(1)

1.新建好的c#项目如下: 文件夹中内容如下: 此时已经可以通过vs2022打开.sln文件,就可以打开项目了。 2.我们把逆向后(主程序)的内容的代码粘贴过去。有些逆向功底,很快可以定位到,服务器的入口…

【Java EE初阶十八】网络原理(三)

3. 网络层 网络层要做的事情主要是两方面: 1)、地址管理:制定一系列的规则,通过地址,描述出网络上一个设备的位置; 2)、路由选择:网络环境是比较复杂的,从一个节点到另一个节点之间,存在很…

【GPT-2】论文解读:Language Models are Unsupervised Multitask Learners

文章目录 介绍zero-shot learning 零样本学习 方法数据Input Representation 结果 论文:Language Models are Unsupervised Multitask Learners 作者:Alec Radford, Jeff Wu, Rewon Child, D. Luan, Dario Amodei, I. Sutskever 时间:2019 介…

Linux系统中 uboot、内核与文件系统之间的关系

前言: 最近正在学习Linux,总结了一下Linux系统中 uboot、内核与文件系统之间的关系 Linux初学者首先要搞清楚的三个文件: 引导程序(bootoader):uboot.bin/uboot.imx Linux内核镜像: zlmage 文件系统镜像:system.img/rootfs.tar.ba2 初期很多工作都是围…

文件上传漏洞--Upload-labs--Pass02--Content-Type绕过

一、什么是 Content-Type 我们在上传文件时利用 Burpsuite 进行抓包,如下图所示: 上传文件后台的源代码可能会对 Content-Type 进行规定,设置白名单 或 黑名单,这时就要利用Content-Type绕过上传含有恶意代码的 php文件。 二、代…

[ linux网络 ] 网关服务器搭建,综合应用SNAT、DNAT转换,dhcp分配、dns分离解析,nfs网络共享以及ssh免密登录

实验准备工作: 网关服务器安装:dhcp bind (yum install -y dhcp bind bind-utlis) server1安装:httpd (yum install -y httpd) 没有网络就搭建本地yum仓库或者配置网卡使其能够上网。 ( 1)网关服务器…

unity C#中的封装、继承和多态简单易懂的经典实例

文章目录 封装 (Encapsulation)继承 (Inheritance)多态 (Polymorphism) C#中的封装、继承和多态是面向对象编程(OOP)的三大核心特性。下面分别对这三个概念进行深入解释,并通过实例来说明它们在实际开发中的应用。 封装 (Encapsulation) 实例…

解决updatexml和extractvalue查询显示不全

报错注入是一种常见的SQL 注入方式,通过注入代码,触发数据库的错误响应,并从错误信息中获取有用的信息。 updatexml和extractvalue updatexml和extractvalue 是常用的两个报错注入函数 http://localhost/sqli/Less-5/?id1%27and%20updat…

【Pygame手册03/20】用于绘制形状的 pygame 模块

目录 一、说明二、画图函数2.1 接口draw下的函数2.2 pygame.draw.rect()2.3 pygame.draw.polygon()2.4 pygame.draw.circle()2.5 pygame.draw.ellipse()2.6 pygame.draw.arc()2.7 pygame.draw.line ()2.8 pygame.draw.lines()2.9 pygame.draw.aaline()2.10 pygame.draw.aaline…

【Redis】理论进阶篇------Redis的主从复制

一、原理解释 1、什么是Redis的主从复制 主从复制,是指将一台Redis服务器的数据复制到其他Redis服务器。前者称为主节点(master),后者称为从节点(slave);对于数据的复制是单项的,只能从主节点到从节点。Ma…

C#上位机与三菱PLC的通信06--MC协议之QnA-3E报文测试

1、A-3E报文回顾 1、存储区分类及访问规则 2、命令类型 命令由主命令子命令组成 3、报文结构 2、启动mc服务器 3、创建VS项目 这节继续使用上节的VS2022的项目,增加一个方法 MCTestA3E(),具体怎么创建项目,见上节的过程。C#上位机与三菱…

在 CentOS 平台下安装与配置 MySQL 5.7.36

CentOS平台常用有三种MySQL安装方式,即RPM安装包、二进制压缩包和源码包。一般来讲,建议使用二进制压缩包,因为该版本比其他的分发版使用起来要简单灵活。本次实验在 CentOS 7.6 平台上选用二进制压缩包安装方式。 1、清理MySQL安装环境 Cent…

MySQL 基础知识(九)之视图

目录 1 视图的介绍 2 视图算法 3 创建视图 4 查看视图结构 5 修改视图 6 删除视图 7 参考文档 1 视图的介绍 视图是一张并不存储数据的虚拟表,其本质是根据 SQL 语句动态查询数据库中的数据。数据库中只存放了视图的定义,通过 SQL 语句使用视图时…

【6-1】使用hanlp进行实体抽取以及句法分析(问题待解决)

1.使用hanlp抽取法人名称、企业名称等信息 # -*- coding: utf-8 -*- from pyhanlp import *text1"1998年11月11日,马化腾和同学张志东在广东省深圳市正式注册成立“深圳市腾讯计算机系统有限公司”,之后许晨晔、陈一丹、曾李青相继加入。当时公司…

论文解读:Masked Generative Distillation

文章汇总 话题 知识蒸馏 创新点 带掩盖的生成式蒸馏 方法旨在通过学生的遮罩特征来生成老师的特征(通过遮盖学生部分的特征来生成老师的特征),来帮助学生获得更好的表现 输入:老师:,学生:,输入:,标签:,超参数: 1:使…

水质监测站工作原理!

TH-LSZ06】水质监测站的工作原理基于现代化学和生物学技术,主要通过化学分析和生物检测两种方法来检测水中有害物质。化学分析技术包括酸碱度、氧化还原电位、重金属离子、有机物、氮和磷等,而生物检测技术则主要关注病毒、细菌、真菌等微生物。 在水质…

Mac M1芯片编译openjdk报错问题解决

使用命令: sudo sh configure --with-target-bits64 用mac m1芯片编译openjdk一直报错: configure: The tested number of bits in the target (64) differs from the number of bits expected to be found in the target (32) configure: error: Cann…

【前端工程化面试题目】webpack 的热更新原理

可以在顺便学习一下 vite 的热更新原理,请参考这篇文章。 首先有几个知识点需要明确 热更新是针对开发过程中的开发服务器的,也就是 webpack-dev-serverwebpack 的热更新不需要额外的插件,但是需要在配置文件中 devServer 属性中配置 hot&a…

云原生之容器编排实践-基于CentOS7搭建三个节点的Kubernetes集群

背景 前面采用 minikube 作为 Kubernetes 环境来体验学习 Kubernetes 基本概念与操作,这样避免了初学者在裸金属主机上搭建 Kubernetes 集群的复杂度,但是随着产品功能的逐渐完善,我们需要过渡到生产环境中的 K8S 集群模式;而在实…