MySQL的变量、流程控制与游标

目录

1.变量的分类

1.系统变量的分类

1.1.二者关系

2.查看系统变量

3.修改系统变量的值

4.用户变量

4.1会话用户变量

1.变量声明与赋值

2.变量使用

4.2.局部变量

[1.使用declare 声明](#1.使用declare 声明)

2.局部变量声明格式

3.局部变量赋值

4.变量使用

5.定义条件与处理程序

1.定义条件:

2.定义条件格式:

3.处理程序:

6.流程控制之分支结构

7.循环结构

8.跳转语句

9.游标

1.游标的作用

2.使用游标的步骤

3.游标的优缺点


1.变量的分类

变量分为:系统变量、用户变量

1.系统变量的分类

全局系统变量

会话系统变量

1.1.二者关系

• 全局系统变量针对于所有会话有效,但不能 跨重启

会话系统变量针对当前会话有效,修改某个会话系统变量不会影响其他会话系统变量

修改全局系统变量也会修改其他会话的全局系统变量值

• 有些系统变量只能是全局系统变量,有些能当全局也能当会话系统变量,有些只能是会话系统变量

2.查看系统变量

• show global variables

• show session variables

• show variables - 默认查询会话系统变量

• select @@global.变量名/查看指定系统变量

• select @@session.变量名

• select @@变量名 先查看会话,没有就查看全局系统变量

sql 复制代码
#查看全局系统变量
SHOW GLOBAL VARIABLES;

#查看会话系统变量
SHOW SESSION VARIABLES;

#查询指定会话系统变量
SELECT @@global.max_connections;

#查询指定全局系统变量
SELECT @@global.character_set_client;

查询结果:

全局系统变量:

会话系统变量:

3.修改系统变量的值

• set @@global.变量名

• set global 全局变量名

sql 复制代码
SET @@global.max_connections = 161;
SET GLOBAL max_connections = 171;

针对于当前的数据库实例有效,一旦重启mysql服务,就失效了

• set @@session.变量名

• set session 变量名

sql 复制代码
SET @@session.admin_port = 161;
SET SESSION admin_port = 171;

• 针对于当前会话有效,一旦结束会话,重新建立起新的会话,就失效

4.用户变量

• 分为会话用户变量(@修饰)、局部变量

会话用户变量:使用@开头,只对当前连接会话有效

局部变量:只在begin和end语句有效,只能在存储过程和函数使用

4.1会话用户变量

1.变量声明与赋值

• set @用户变量 := 值

• select @用户变量 := 语句 from

• select 语句 into @用户变量 from 表名

sql 复制代码
#设置会话用户变量
SET @m1 := 1;

SELECT @count := COUNT(*) FROM employees;

SELECT AVG(salary) INTO @salary FROM employees; 

2.变量使用

• select @变量名

sql 复制代码
#变量的使用
SET @sum := @m1 + @count;

SELECT @sum;

4.2.局部变量

1.使用declare 声明

必须声明并使用在begin...end中

必须使用在存储过程/函数中

declare的方式声明的局部变量必须声明在begin中的首行的位置

• 必须变量指明类型

2.局部变量声明格式

• declare 变量名 类型

3.局部变量赋值

• set 变量 := 值

• select 语句 into 变量 from 表名

4.变量使用

• select 变量名

以上所有的代码示例:

sql 复制代码
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	#局部变量声明
	DECLARE a INT DEFAULT 0;
	DECLARE emp_name VARCHAR(20);

	#局部变量赋值
	SET a := 1;
	SELECT last_name INTO emp_name FROM employees WHERE emp_id = 111;

	#局部变量使用
	SELECT a,emp_name;
END $

DELIMITER ;

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

5.定义条件与处理程序

1.定义条件:

给mysql中的错误码命名,有助于存储的程序代码更清晰

将一个错误名字和指定的错误条件关联起来

2.定义条件格式:

declare 错误名称 condition for 错误码

错误码:举例:

ERROR 1148(42000);

1418-mysql_error_code;

HY000-sqlstate_value

sql 复制代码
#定义 "ERROR 1148(42000)"错误,名称为command_not_allowed
#定义方式1:使用MySQL_error_code
DECLARE command_not_allowed CONDITION FOR 1148;

#定义方式2:使用sqlstate_value
DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000';

3.处理程序:

遇到问题时应当采取的处理方式,并且保证存储过程/函数在遇到错误时能够继续执行

• declare 处理方式 handler for 错误类型 处理语句

• 处理方式:continue、exit、undo(不支持)

sql 复制代码
#定义处理程序
#方式1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @info = 'NO_SUCH_TABLE';

#方式2:捕获MySQL_error_code
DECLARE CONTINUE HANDLER FOR 1148 SET @info = 'NO_SUCH_TABLE';

#方式3
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';

6.流程控制之分支结构

• if使用

sql 复制代码
#IF的使用
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	DECLARE var INT DEFAULT 20;
	
	IF var > 40
		THEN SELECT '中年';
	ELSEIF var > 18
		THEN SELECT '青年';
	ELSEIF var > 8
		THEN SELECT '少年';
	ELSE 
		SELECT '幼年';
	END IF;
END $

DELIMITER ;

• case使用

sql 复制代码
#CASE的使用
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	DECLARE var INT DEFAULT 20;
	
	CASE var
		WHEN 40 THEN SELECT '中年';
		WHEN 20 THEN SELECT '青年';
		WHEN 10 THEN SELECT '少年';
		ELSE SELECT '幼年';
	END CASE;
END $

DELIMITER ;

7.循环结构

• 循环结构四要素:初始化条件、循环条件、循环体、迭代条件

• loop

sql 复制代码
#loop的使用
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	DECLARE var INT DEFAULT 20;
	loop_label:LOOP
		SET var = var + 1;
		IF var >= 10 THEN LEAVE loop_label;
		END IF;
	END LOOP loop_label;

END $

DELIMITER ;

• while

sql 复制代码
#while的使用
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	DECLARE var INT DEFAULT 20;
	WHILE var <= 10 DO
		SET num = num + 1;
	END WHILE;

END $

DELIMITER ;

• repeat相当于-do...while...

sql 复制代码
#repeat的使用
DELIMITER $

CREATE PROCEDURE test()
BEGIN
	DECLARE var INT DEFAULT 20;
	REPEAT
		SET var = var + 1;
		UNTIL var >= 10
	END REPEAT;
END $

DELIMITER ;

8.跳转语句

• leave-相当于break

• iterate-相当于continue;只能在循环结构中使用

sql 复制代码
#跳转语句之leave
DELIMITER $

CREATE PROCEDURE leave_begin(IN num INT)
begin_label: BEGIN
IF num<=0
THEN LEAVE begin_label;
ELSEIF num=1
THEN SELECT AVG(salary) FROM employees;
ELSEIF num=2
THEN SELECT MIN(salary) FROM employees;
ELSE
SELECT MAX(salary) FROM employees;
END IF;
SELECT COUNT(*) FROM employees;
END $

DELIMITER ;

9.游标

1.游标的作用

游标让SQL这种面向集合的语言有了面向过程开发的能力

• 游标充当了指针的作用,是一种临时的数据库对象

2.使用游标的步骤

  1. 定义游标:declare...cursor for...;(在oracle中使用cursor is)

  2. 打开游标:open cursor_name

  3. 使用游标(从游标中取得数据):fetch into

  4. 关闭游标:close ...

sql 复制代码
#游标的使用
DELIMITER //

CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,
OUT total_count INT)
BEGIN
	DECLARE emp_sal DOUBLE DEFAULT 0.0;
	DECLARE sum_sal DOUBLE DEFAULT 0.0;
	DECLARE count_re INT DEFAULT 0;
	
	
	#定义游标
	DECLARE emp_cursor CURSOR FOR SELECT salary FROM employees ORDER BY salary DESC;
	#打开游标
	OPEN emp_cursor;
	
	REPEAT
		#使用游标
		FETCH emp_cursor INTO emp_sal;
		SET sum_sal = sum_sal + emp_sal;
		SET count_re = count_re + 1;
		UNTIL sum_sal >= limit_total_salary
	END REPEAT;
	
	SET total_count = count_re;
	
	#关闭游标
	CLOSE emp_cursor;
END //

DELIMITER ;

为什么要关闭游标:

因为游标会占用系统资源,不及时关闭,游标会一直保持到存储过程结束,影响系统运行的效率

3.游标的优缺点

**• 优点:**为逐条读取结果集中的数据提供了完美的解决方案。

**• 缺点:**使用游标时会对数据行进行加锁,在业务并发量大时,会影响业务效率、消耗系统资源、造成内存不足;因为游标是在内存中进行的处理

**• 建议:**用完游标及时关闭,提高效率

相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ18 分钟前
mybatisPlus打印sql配置
数据库·sql
弗拉唐29 分钟前
将Excel文件的两个表格经过验证后分别读取到Excel表和数据库
数据库·excel
刘艳兵的学习博客1 小时前
刘艳兵-DBA033-如下那种应用场景符合Oracle ROWID存储规则?
服务器·数据库·oracle·面试·刘艳兵
simpleGq1 小时前
Redis知识点整理 - 脑图
数据库·redis·缓存
NiNg_1_2341 小时前
关系型数据库和非关系型数据库详解
数据库·oracle·nosql
paopaokaka_luck1 小时前
基于Spring Boot+Vue的多媒体素材管理系统的设计与实现
java·数据库·vue.js·spring boot·后端·算法
python资深爱好者1 小时前
NoSQL数据库与关系型数据库的主要区别
数据库·oracle·nosql
sj11637394031 小时前
Kafka参数了解
数据库·分布式·kafka
小扳2 小时前
Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
运维·spring boot·后端·mysql·spring cloud·docker·容器
日里安2 小时前
8. 基于 Redis 实现限流
数据库·redis·缓存