首页 > 数据库 >mysql8.0变量

mysql8.0变量

时间:2024-01-05 19:32:10浏览次数:38  
标签:SET 变量 会话 mysql8.0 MySQL DECLARE SELECT

1、变量

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

1.1、系统变量

1.1.1、系统变量分类

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

系统变量分为全局系统变量(需要添加global关键字)以及会话系统变量(需要添加session关键字),有时也把全局系统变量简称为全局变量,
有时也把会话系统变量称为local变量。如果不写,默认会话级别。
静态变量(在MySQL服务实例运行期间它们的值不能使用set动态修改)属于特殊的全局系统变量。
每一个MySQL客户机成功连接MySQL服务器后,都会产生与之对应的会话。
会话期间,MySQL服务实例会在MySQL服务器内存中生成与该会话对应的会话系统变量,这些会话系统变量的初始值是全局系统变量值的复制。
如下图:

mysql8.0变量_系统变量

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

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

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

1.1.2、查看系统变量

1、查看所有或部分系统变量
#查看所有全局变量
SHOWGLOBALVARIABLES;

#查看所有会话变量
SHOWSESSIONVARIABLES;或
SHOWVARIABLES;

#查看满足条件的部分系统变量。
SHOWGLOBALVARIABLESLIKE'%标识符%';

#查看满足条件的部分会话变量
SHOWSESSIONVARIABLESLIKE'%标识符%';

2、查看指定系统变量
作为MySQL编码规范,MySQL中的系统变量以两个“@”开头,其中“@@global”仅用于标记全局系统变量,“@@session”仅用于标记会话系统变量。
“@@”首先标记会话系统变量,如果会话系统变量不存在,则标记全局系统变量。

#查看指定的系统变量的值
SELECT@@global.变量名;

#查看指定的会话变量的值
SELECT@@session.变量名;
#或者
SELECT@@变量名;

3、修改系统变量的值
有些时候,数据库管理员需要修改系统变量的默认值,以便修改当前会话或者MySQL服务实例的属性、特征。具体方法:
方式1:修改MySQL配置文件,继而修改MySQL系统变量的值(该方法需要重启MySQL服务)
方式2:在MySQL服务运行期间,使用“set”命令重新设置系统变量的值

#为某个系统变量赋值
#方式1:
SET@@global.变量名=变量值;
#方式2:
SETGLOBAL变量名=变量值;

#为某个会话变量赋值
#方式1:
SET@@session.变量名=变量值;
#方式2:
SETSESSION变量名=变量值;

1.2、用户变量

1.2.1、用户变量分类

用户变量是用户自己定义的,作为MySQL编码规范,MySQL中的用户变量以一个“@”开头。根据作用范围不同,又分为会话用户变量和局部变量
    会话用户变量:作用域和会话变量一样,只对当前连接会话有效
    局部变量:只在BEGIN和END语句块中有效。局部变量只能在存储过程和函数中使用

1.2.2、会话用户变量

1、变量的定义
#方式1:“=”或“:=”
SET@用户变量=值;
SET@用户变量:=值;

#方式2:“:=”或INTO关键字
SELECT@用户变量:=表达式[FROM等子句];
SELECT表达式INTO@用户变量[FROM等子句];

2、查看用户变量的值(查看、比较、运算等)
SELECT@用户变量

SELECT @num := COUNT(*) FROM employees;
SELECT @num;
SELECT AVG(salary) INTO @avgsalary FROM employees;
SELECT @avgsalary;
SELECT@big; #查看某个未声明的变量时,将得到NULL值

1.2.3、局部变量

定义:可以使用DECLARE语句定义一个局部变量
作用域:仅仅在定义它的BEGIN...END中有效
位置:只能放在BEGIN...END中,而且只能放在第一句

BEGIN
    #声明局部变量
    DECLARE 变量名1 变量数据类型 [DEFAULT 变量默认值];
    DECLARE 变量名2,变量名3,... 变量数据类型 [DEFAULT 变量默认值];#为局部变量赋值
    SET 变量名1 = 值;
    SELECT 值 INTO 变量名2 [FROM 子句];
    #查看局部变量的值
    SELECT 变量1,变量2,变量3;
END

1.定义变量
DECLARE 变量名 类型 [default值]; #如果没有DEFAULT子句,初始值为NULL
DECLARE myparam INT DEFAULT100;

2.变量赋值
方式1:一般用于赋简单的值
SET变量名=值;
SET变量名:=值;
方式2:一般用于赋表中的字段值
SELECT 字段名或表达式 INTO 变量名 FROM 表;

3.使用变量(查看、比较、运算等)
SELECT 局部变量名;
#举例:
DELIMITER //
CREATE PROCEDURE test_var()
BEGIN
	#1、声明局部变量
	DECLARE a INT DEFAULT 0;
	DECLARE b INT ;
	#DECLARE a,b INT DEFAULT 0;
	DECLARE emp_name VARCHAR(25);
	#2、赋值
	SET a = 1;
	SET b := 2;
	SELECT last_name INTO emp_name FROM employees WHERE employee_id = 101;
	#3、使用
	SELECT a,b,emp_name;	
END //
DELIMITER ;
#调用存储过程
CALL test_var();

#举例1:声明局部变量,并分别赋值为employees表中employee_id为102的last_name和salary
DELIMITER//
CREATE PROCEDURE set_value()
BEGIN
    DECLARE emp_name VARCHAR(25);
    DECLARE sal DOUBLE(10,2);
    SELECT last_name,salary INTO emp_name,sal FROM employees
    WHERE employee_id=102;
    SELECT emp_name,sal;
END//
DELIMITER;

#举例2:声明两个变量,求和并打印 (分别使用会话用户变量、局部变量的方式实现)
#方式1:使用会话用户变量
SET @v1 = 10;
SET @v2 := 20;
SET @result := @v1 + @v2;
#查看
SELECT @result;

#方式2:使用局部变量
DELIMITER //
CREATE PROCEDURE add_value()
BEGIN
	#声明
	DECLARE value1,value2,sum_val INT;
	#赋值
	SET value1 = 10;
	SET value2 := 100;
	SET sum_val = value1 + value2;
	#使用
	SELECT sum_val;
END //
DELIMITER ;

举例3:创建存储过程“different_salary”查询某员工和他领导的薪资差距,并用IN参数emp_id接收员工id,用OUT参数dif_salary输出薪资差距结果。
DELIMITER //
CREATE PROCEDURE different_salary(IN emp_id INT,OUT dif_salary DOUBLE)
BEGIN
	#分析:查询出emp_id员工的工资;查询出emp_id员工的管理者的id;查询管理者id的工资;计算两个工资的差值
	#声明变量
	DECLARE emp_sal DOUBLE DEFAULT 0.0; #记录员工的工资
	DECLARE mgr_sal DOUBLE DEFAULT 0.0; #记录管理者的工资
	DECLARE mgr_id INT DEFAULT 0; #记录管理者的id
	#赋值
	SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
	SELECT manager_id INTO mgr_id FROM employees WHERE employee_id = emp_id;
	SELECT salary INTO mgr_sal FROM employees WHERE employee_id = mgr_id;
	SET dif_salary = mgr_sal - emp_sal;
END //
DELIMITER ;

#调用存储过程
SET @emp_id := 103;
SET @dif_sal := 0;
CALL different_salary(@emp_id,@dif_sal);

SELECT @dif_sal;

1.2.4、对比会话用户变量与局部变量

mysql8.0变量_变量名_02

2、定义条件与处理程序

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

2.1、案例分析

#错误代码: 1364
#Field 'email' doesn't have a default value
INSERT INTO employees(last_name)
VALUES('Tom');

DESC employees;

#错误演示:
DELIMITER //
CREATE PROCEDURE UpdateDataNoCondition()
	BEGIN
		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 ;

#调用存储过程
#错误代码: 1048
#Column 'email' cannot be null
CALL UpdateDataNoCondition();
SELECT @x;

可以看到,此时@x变量的值为1。结合创建存储过程的SQL语句代码可以得出:
在存储过程中未定义条件和处理程序,且当存储过程中执行的SQL语句报错时,MySQL数据库会抛出错误,并退出当前SQL逻辑,不再向下继续执行。

2.2、定义条件

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

定义条件使用DECLARE语句,语法格式如下:
DECLARE错误名称CONDITION FOR 错误码(或错误条件)
错误码的说明:
MySQL_error_code和sqlstate_value都可以表示MySQL的错误。
    MySQL_error_code是数值类型错误代码。
    sqlstate_value是长度为5的字符串类型错误代码。
    
例如,在ERROR1418(HY000)中,1418是MySQL_error_code,'HY000'是sqlstate_value。
例如,在ERROR1142(42000)中,1142是MySQL_error_code,'42000'是sqlstate_value。

举例1:定义“Field_Not_Be_NULL”错误名与MySQL中违反非空约束的错误类型是“ERROR1048(23000)”对应。
#使用MySQL_error_code
DECLAREField_Not_Be_NULLCONDITIONFOR1048;
#使用sqlstate_value
DECLAREField_Not_Be_NULLCONDITIONFORSQLSTATE'23000';

举例2:定义"ERROR1148(42000)"错误,名称为command_not_allowed。
#使用MySQL_error_code
DECLAREcommand_not_allowedCONDITIONFOR1148;
#使用sqlstate_value
DECLAREcommand_not_allowedCONDITIONFORSQLSTATE'42000';

2.3、定义处理程序

可以为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错误代码;
    NOTFOUND:匹配所有以02开头的SQLSTATE错误代码;
    SQLEXCEPTION:匹配所有没有被SQLWARNING或NOTFOUND捕获的SQLSTATE错误代码;
处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是像“SET变量=值”这样的简单语句
也可以是使用BEGIN...END编写的复合语句。

定义处理程序的几种方式,代码如下:
#方法1:捕获sqlstate_value
DECLARECONTINUEHANDLERFORSQLSTATE'42S02'SET@info='NO_SUCH_TABLE';
#方法2:捕获mysql_error_value
DECLARECONTINUEHANDLERFOR1146SET@info='NO_SUCH_TABLE';
#方法3:先定义条件,再调用
DECLAREno_such_tableCONDITIONFOR1146;
DECLARECONTINUEHANDLERFORNO_SUCH_TABLESET@info='NO_SUCH_TABLE';
#方法4:使用SQLWARNING
DECLAREEXITHANDLERFORSQLWARNINGSET@info='ERROR';
#方法5:使用NOTFOUND
DECLAREEXITHANDLERFORNOTFOUNDSET@info='NO_SUCH_TABLE';
#方法6:使用SQLEXCEPTION
DECLAREEXITHANDLERFORSQLEXCEPTIONSET@info='ERROR';

2.4、案例解决

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

#重新定义存储过程,体现错误的处理程序
DELIMITER //
CREATE PROCEDURE UpdateDataNoCondition()
	BEGIN
		#声明处理程序
		#处理方式1:
		DECLARE CONTINUE HANDLER FOR 1048 SET @prc_value = -1;
		#处理方式2:
		#DECLARE CONTINUE HANDLER FOR sqlstate '23000' SET @prc_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 ;

#调用存储过程:
CALL UpdateDataNoCondition();

#查看变量:
SELECT @x,@prc_value;

案例二:
DROP PROCEDURE IF EXISTS InsertDataWithCondition;
重新定义存储过程(考虑到错误的处理程序)

DELIMITER //
CREATE PROCEDURE InsertDataWithCondition()
	BEGIN		
		#处理程序
		#方式1:
		#declare exit handler for 1062 set @pro_value = -1;
		#方式2:
		#declare exit handler for sqlstate '23000' set @pro_value = -1;
		#方式3:
		#定义条件
		DECLARE duplicate_entry CONDITION FOR 1062;
		DECLARE EXIT HANDLER FOR duplicate_entry SET @pro_value = -1;
		SET @x = 1;
		INSERT INTO departments(department_name) VALUES('测试');
		SET @x = 2;
		INSERT INTO departments(department_name) VALUES('测试');
		SET @x = 3;
	END //
DELIMITER ;

#调用
CALL InsertDataWithCondition();

SELECT @x,@pro_value;

练习

#无参有返回
#1. 创建函数get_count(),返回公司的员工个数
DELIMITER //
CREATE FUNCTION get_count() RETURNS INT
BEGIN
    DECLARE c INT DEFAULT 0;#定义局部变量
    SELECT COUNT(*) INTO c#赋值
    FROM employees;
    RETURN c;
END //
DELIMITER ;
#调用
SELECT get_count();

#有参有返回
#2. 创建函数ename_salary(),根据员工姓名,返回它的工资
DELIMITER //
CREATE FUNCTION ename_salary(emp_name VARCHAR(15))
RETURNS DOUBLE
BEGIN
    SET @sal=0;#定义用户变量
    SELECT salary INTO @sal #赋值
    FROM employees
    WHERE last_name = emp_name;
    RETURN @sal;
END //
DELIMITER ;
#调用
SELECT ename_salary('Abel');

#3. 创建函数dept_sal() ,根据部门名,返回该部门的平均工资
DELIMITER //
CREATE FUNCTION dept_sal(dept_name VARCHAR(15))
RETURNS DOUBLE
BEGIN
    DECLARE avg_sal DOUBLE ;
    SELECT AVG(salary) INTO avg_sal
    FROM employees e
    JOIN departments d ON e.department_id = d.department_id
    WHERE d.department_name=dept_name;
    RETURN avg_sal;
END //
DELIMITER ;
#调用
SELECT dept_sal('Marketing');

#4. 创建函数add_float(),实现传入两个float,返回二者之和
DELIMITER //
CREATE FUNCTION add_float(value1 FLOAT,value2 FLOAT)
RETURNS FLOAT
BEGIN
    DECLARE SUM FLOAT;
    SET SUM=value1+value2;
    RETURN SUM;
END //
DELIMITER ;

#调用
SET @v1 := 12.2;
SET @v2 = 2.3;
SELECT add_float(@v1,@v2);

标签:SET,变量,会话,mysql8.0,MySQL,DECLARE,SELECT
From: https://blog.51cto.com/u_13236892/9117163

相关文章

  • MySQL8.0 PG数据库 SQLServer Oracle数据库 数据库忘记密码 处理方法
    MySQL8.0分为rpm方式和tar.gz安装方式不同而不同需要修改/etc/my.conf配置文件.注意如果是rpm包的话就在这个路径下面修改增加内容skip-grant-tables注意修改完需要重启数据库rpm包安装的方式重启方法为:systemctlrestartmysqld然后可以无密码登录数据mysql-uro......
  • 网络攻防技术——环境变量和Set-UID攻击
    实验6:环境变量与set-uid实验实验内容:本实验室的学习目标是让学生了解环境变量如何影响程序以及系统行为。环境变量是一组动态命名值,可以影响正在运行的进程将在计算机上运行。大多数操作系统都使用它们,因为它们是1979年引入Unix。尽管环境变量会影响程序行为,但它们是如何实现的......
  • mysql8.0存储过程和存储函数的查看、修改、删除
    5、存储过程和存储函数的查看、修改、删除5.1、查看创建完之后,怎么知道我们创建的存储过程、存储函数是否成功了呢?MySQL存储了存储过程和函数的状态信息,用户可以使用SHOWSTATUS语句或SHOWCREATE语句来查看,也可直接从系统的information_schema数据库中查询。这里介绍3种方法。......
  • Python 中的变量如何定义和使用
    Python是一种解释性语言,它使用动态类型系统,这意味着变量的类型不需要在定义时显式指定,而是根据变量的值来推断其类型。在Python中,变量可以存储各种类型的数据,如字符串、整数、浮点数、布尔值、列表、元组、字典等。本文将介绍Python中变量的定义和使用,包括变量命名规则、变量赋值、......
  • mysql8.0大小写的坑
    这两天又被mysql8.0大小写的问题坑到了,看下面的报错:chown:cannotaccess'./proc/38/fd/6':Nosuchfileordirectorychown:cannotaccess'./proc/38/fd/7':Nosuchfileordirectorychown:cannotaccess'./proc/38/fdinfo/4':Nosuchfileordire......
  • 【Azure APIM】APIM 策略语句如何读取请求头中所携带的Cookie信息并保存为变量
    问题描述需要在APIM策略中对请求所携带的Cookie中的token值进行JWT验证,如果获取Cookie中的值并且作为变量保存,然后在JWT验证中使用呢? 问题解答第一步:获取Cookie中的Token值使用C#语句@(context.Request.Headers.GetValueOrDefault("cookie","").Split(';').Select(x=>x.Trim(......
  • mysql8.0存储函数
    4、存储函数的使用4.1、语法分析学过的函数:LENGTH、SUBSTR、CONCAT等语法格式CREATEFUNCTION函数名(参数名参数类型,...)RETURNS返回值类型[characteristics...]BEGIN函数体#函数体中肯定有RETURN语句END说明:1、参数列表:指定参数为IN、OUT或INOUT只对PROCE......
  • mysql8.0存储过程
    1、存储过程概述1.1、理解含义:存储过程的英文是StoredProcedure。它的思想很简单,就是一组经过预先编译的SQL语句的封装。执行过程:存储过程预先存储在MySQL服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令,服务器端就可以把预先存储好的这一系列SQL......
  • Shell特殊参数变量
    1.Shell变量1.1.本地变量定义shell变量,变量不需要加美元符`$`本地变量只在用户当前shell生存期中有效,如:1.2.变量定义1.2.1 变量名要求:字母、数字、下划线组成、可以是字母或是下划线开头,如:waynewayne_123......
  • 鸿蒙自定义弹窗中的变量如何传递给页面
    鸿蒙自定义弹窗中的变量如何传递给页面作者:坚果团队:坚果派公众号:“大前端之旅”团队介绍:坚果派由坚果创建,团队拥有8个华为HDE,3个HSD,以及若干其他领域的三十余位万粉博主运营。本人为华为HDE、中国计算机学会CCF专业会员、OpenHarmony布道师、开发者联盟优秀讲师、2023年开源之夏......