侧边栏壁纸
博主头像
coydone博主等级

记录学习,分享生活的个人站点

  • 累计撰写 306 篇文章
  • 累计创建 51 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

变量与错误处理

coydone
2022-01-06 / 0 评论 / 0 点赞 / 313 阅读 / 5,153 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-06,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

变量

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

  • 系统变量:全局变量,会话变量。

  • 自定义变量:用户变量,局部变量。

系统变量

变量由系统定义,不是用户定义,属于服务器层面。启动MySQL服务,生成MySQL服务实例期间,MySQL将为MySQL服务器内存中的系统变量赋值,这些系统变量定义了当前MySQL服务实例的属性、特征。这些系统变量的值要么是编译MySQL时参数的默认值,要么是配置文件(例如my.ini等)中的参数值。可以通过网址 https://dev.mysql.com/doc/refman/8.0/en/server-systemvariables.html 查看MySQL文档的系统变量。

注意:全局变量需要添加global关键字,会话变量需要添加session关键字,如果不写,默认会话级别。静态变量(在 MySQL 服务实例运行期间它们的值不能使用 set 动态修改)属于特殊的全局系统变量。

每一个MySQL客户机成功连接MySQL服务器后,都会产生与之对应的会话。会话期间,MySQL服务实例会在MySQL服务器内存中生成与该会话对应的会话系统变量,这些会话系统变量的初始值是全局系统变量值的复制。

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

  • 会话系统变量仅针对于当前会话(连接)有效。会话期间,当前会话对某个会话系统变量值的修改,不会影响其他会话同一个会话系统变量的值。

  • 会话1对某个全局系统变量值的修改会导致会话2中同一个全局系统变量值的修改。

在MySQL中有些系统变量只能是全局的,例如 max_connections 用于限制服务器的最大连接数;有些系统变量作用域既可以是全局又可以是会话,例如 character_set_client 用于设置客户端的字符集;有些系统变量的作用域只能是当前会话,例如 pseudo_thread_id 用于标记当前会话的 MySQL 连接 ID。

1、查看所有系统变量
show [global|session] variables;

2、查看满足条件的部分系统变量
show [global|session] variables like '%char%';

3、查看指定的系统变量的值
select @@global|[session] 系统变量名;
#查看指定的系统变量的值
SELECT @@global.变量名;
#查看指定的会话变量的值
SELECT @@session.变量名;
#或者
SELECT @@变量名;

4、修改系统变量的值
(1)修改MySQL配置文件 ,继而修改MySQL系统变量的值(该方法需要重启MySQL服务)
(2)在MySQL服务运行期间,使用“set”命令重新设置系统变量的值
#为某个系统变量赋值
#方式1:
SET @@global.变量名=变量值;
#方式2:
SET GLOBAL 变量名=变量值;
#为某个会话变量赋值
#方式1:
SET @@session.变量名=变量值;
#方式2:
SET SESSION 变量名=变量值;

全局变量

作用域:针对于所有会话(连接)有效,但不能跨重启。

#①查看所有全局变量
SHOW GLOBAL VARIABLES;
#②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#③查看指定的系统变量的值
SELECT @@global.autocommit;
#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;

MySQL 8.0的新特性:全局变量的持久化

在MySQL数据库中,全局变量可以通过SET GLOBAL语句来设置。例如,设置服务器语句超时的限制,可以通过设置系统变量max_execution_time来实现:

SET GLOBAL MAX_EXECUTION_TIME=2000;

使用SET GLOBAL语句设置的变量值只会 临时生效 。 数据库重启 后,服务器又会从MySQL配置文件中读取变量的默认值。 MySQL 8.0版本新增了 SET PERSIST 命令。例如,设置服务器的最大连接数为1000:

SET PERSIST global max_connections = 1000;

MySQL会将该命令的配置保存到数据目录下的 mysqld-auto.cnf 文件中,下次启动时会读取该文件,用其中的配置来覆盖默认的配置文件。

# 举例:
# 查看全局变量max_connections的值
show variables like '%max_connections%';
# 设置全局变量max_connections的值
set persist max_connections=1000;
#重启MySQL服务器 ,再次查询max_connections的值

会话变量

作用域:针对于当前会话(连接)有效。

#①查看所有会话变量
SHOW SESSION VARIABLES;
#②查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';
#③查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
#④为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';

自定义变量

说明:变量由用户自定义,而不是系统提供的。

使用步骤:1、声明,2、赋值,3、使用(查看、比较、运算等)。

用户变量

作用域:针对于当前会话(连接)有效,作用域同于会话变量。

#赋值操作符:=或:=
#①声明并初始化
SET @变量名=值;
SET @变量名:=值;
SELECT @变量名:=值;

#②赋值(更新变量的值)
#方式一:
	SET @变量名=值;
	SET @变量名:=值;
	SELECT @变量名:=值;
#方式二:
	SELECT 字段 INTO @变量名
	FROM 表;
#③使用(查看变量的值)
SELECT @变量名;

局部变量

作用域:仅仅在定义它的begin end块中有效。应用在 begin end中的第一句话。

#①声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 【DEFAULT 值】;

#②赋值(更新变量的值)
#方式一:
	SET 局部变量名=值;
	SET 局部变量名:=值;
	SELECT 局部变量名:=值;
#方式二:
	SELECT 字段 INTO 具备变量名 FROM 表;
#③使用(查看变量的值)
	SELECT 局部变量名;
#案例:声明两个变量,求和并打印
#用户变量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;

#局部变量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;
SELECT SUM;

#用户变量和局部变量的对比
		作用域			       定义位置		      语法
用户变量	当前会话		        会话的任何地方		加@符号,不用指定类型
局部变量	定义它的BEGIN END中 	BEGIN END的第一句话	一般不用加@,需要指定类型

定义条件与处理程序

定义条件是事先定义程序执行过程中可能遇到的问题, 处理程序定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行。

说明:定义条件和处理程序在存储过程、存储函数中都是支持的。

定义条件

定义条件就是给MySQL中的错误码命名,这有助于存储的程序代码更清晰。它将一个 错误名字 和 指定的错误条件 关联起来。这个名字可以随后被用在定义处理程序的 DECLARE HANDLER 语句中。定义条件使用DECLARE语句,语法格式如下:

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

错误码的说明:

MySQL_error_code 和 sqlstate_value 都可以表示MySQL的错误。MySQL_error_code是数值类型错误代码。sqlstate_value是长度为5的字符串类型错误代码。

例如,在ERROR 1418 (HY000)中,1418是MySQL_error_code,'HY000’是sqlstate_value。在ERROR 1142(42000)中,1142是MySQL_error_code,'42000’是sqlstate_value。

# 定义“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';

定义处理程序

可以为SQL执行过程中发生的某种类型的错误定义特殊的处理程序。定义处理程序时,使用DECLARE语句的语法如下:

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

处理方式:处理方式有3个取值:CONTINUE、EXIT、UNDO。
	CONTINUE:表示遇到错误不处理,继续执行。
	EXIT:表示遇到错误马上退出。
	UNDO:表示遇到错误后撤回之前的操作。MySQL中暂时不支持这样的操作。
错误类型(即条件)可以有如下取值:
	SQLSTATE '字符串错误码':表示长度为5的sqlstate_value类型的错误代码;
	MySQL_error_code:匹配数值类型错误代码;
	错误名称:表示DECLARE ... CONDITION定义的错误条件名称。
	SQLWARNING:匹配所有以01开头的SQLSTATE错误代码;
	NOT FOUND:匹配所有以02开头的SQLSTATE错误代码;
	SQLEXCEPTION:匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码
	处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。
语句可以是
像“SET 变量=值”这样的简单语句,也可以是使用BEGIN...END编写的复合语句

定义处理程序的几种方式,代码如下:

#方法1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE';
#方法2:捕获mysql_error_value
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE';
#方法3:先定义条件,再调用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';
#方法4:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';
#方法5:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';
#方法6:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR';

测试:在存储过程中,定义处理程序,捕获sqlstate_value值,当遇到MySQL_error_code值为1048时,执行CONTINUE操作,并且将@proc_value的值设置为-1。

DELIMITER 
CREATE PROCEDURE UpdateDataNoCondition()
	BEGIN
		#定义处理程序
		DECLARE CONTINUE HANDLER FOR 1048 SET @proc_value = -1;
		SET @x = 1;
		UPDATE employees SET email = NULL WHERE last_name = 'Abel';
		SET @x = 2;
		UPDATE employees SET email = 'aabbel' WHERE last_name = 'Abel';
		SET @x = 3;
	END 
DELIMITER ;
0

评论区