在 MySQL 数据库中,变量分为 系统变量 以及 用户自定义变量。
变量由系统定义,不是用户定义,属于 服务器 层面。启动MySQL服务,生成MySQL服务实例期间, MySQL将为MySQL服务器内存中的系统变量赋值,这些系统变量定义了当前MySQL服务实例的属性、特征。这些系统变量的值要么是编译MySQL时参数的默认值,要么是配置文件 (例如my.ini等)中的参数值。
系统变量分为全局系统变量(需要添加 global 关键字)以及会话系统变量(需要添加 session 关键字)
每一个MySQL客户机成功连接MySQL服务器后,都会产生与之对应的会话。会话期间,MySQL服务实例会在MySQL服务器内存中生成与该会话对应的会话系统变量,这些会话系统变量的初始值是全局系统变量值的复制。
注:
全局系统变量针对于所有会话(连接)有效,但不能跨重启。
会话系统变量仅针对于当前会话(连接)有效。会话期间,当前会话对某个会话系统变量值的修改,不会影响其他会话同一个会话系统变量的值。但它对全局系统变量的修改会影响其他会话。
- #查看所有全局变量
- SHOW GLOBAL VARIABLES;
-
- #查看所有会话变量
- SHOW SESSION VARIABLES;
-
- #查看满足条件的部分系统变量。
- SHOW GLOBAL VARIABLES LIKE '%标识符%';
-
- #查看满足条件的部分会话变量
- SHOW SESSION VARIABLES LIKE '%标识符%';
作为 MySQL 编码规范,MySQL 中的系统变量以 两个“@” 开头,其中“@@global”仅用于标记全局系统变量,“@@session”仅用于标记会话系统变量。“@@”首先标记会话系统变量,如果会话系统变量不存在, 则标记全局系统变量。
- #查看指定的系统变量的值
- SELECT @@global.变量名;
-
- #查看指定的会话变量的值
- SELECT @@session.变量名;
-
- #或者
- SELECT @@变量名;
方式1:修改MySQL 配置文件 ,继而修改MySQL系统变量的值(需要重启MySQL服务)
方式2:在MySQL服务运行期间,使用“set”命令重新设置系统变量的值
- #为某个系统变量赋值
- #方式1:
- SET @@global.变量名=变量值;
- #方式2:
- SET GLOBAL 变量名=变量值;
-
- #为某个会话变量赋值
- #方式1:
- SET @@session.变量名=变量值;
- #方式2:
- SET SESSION 变量名=变量值;
-
- 例如:
- SET GLOBAL max_connections = 1000;
用户变量是用户自定义的,作为 MySQL 编码规范,MySQL 中的用户变量以 一个“@” 开头。根据作用范围不同,又分为 会话用户变量 和 局部变量 。
会话用户变量:作用域和会话变量一样,只对 当前连接 会话有效。
局部变量:只在 BEGIN 和 END 语句块中有效。局部变量只能在 存储过程 和 函数 中使用。
1.定义
- #方式1:“=”或“:=”
- SET @用户变量 = 值;
- SET @用户变量 := 值;
-
- #方式2:“:=” 或 INTO关键字
- SELECT @用户变量 := 表达式 [FROM 等子句];
- SELECT 表达式 INTO @用户变量 [FROM 等子句];
2.查看
SELECT @用户变量
3.举例
- SET @a = 1;
- SELECT @a;
-
- SELECT @num := COUNT(*) FROM employees;
-
- SELECT AVG(salary) INTO @avgsalary FROM employees;
- SELECT @avgsalary;
定义:使用 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 DEFAULT 100;
-
- #赋值
- SET 变量名=值;
- SET 变量名:=值;
- SELECT 字段名或表达式 INTO 变量名 FROM 表;
2.查看
SELECT 局部变量名;
声明两个变量,求和并打印 (分别使用会话用户变量、局部变量的方式实现)
- #方式1:使用用户变量
- SET @m=1;
- SET @n=1;
- SET @sum=@m+@n;
- SELECT @sum;
-
- #方式2:使用局部变量
- DELIMITER //
- CREATE PROCEDURE add_value()
- BEGIN
- #局部变量
- DECLARE m INT DEFAULT 1;
- DECLARE n INT DEFAULT 3;
- DECLARE SUM INT;
- SET SUM = m+n;
- SELECT SUM;
- END //
- DELIMITER ;
定义条件是事先定义程序执行过程中可能遇到的问题;处理程序 定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。
定义条件和处理程序在存储过程、存储函数中都是支持的。
定义条件就是给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。
定义“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 错误类型 处理语句
-
- 1.处理方式:处理方式有3个取值:CONTINUE、EXIT、UNDO。
- CONTINUE :表示遇到错误不处理,继续执行。
- EXIT :表示遇到错误马上退出。
- UNDO :表示遇到错误后撤回之前的操作。MySQL中暂时不支持这样的操作。
- 2.错误类型(即条件)可以有如下取值:
- SQLSTATE '字符串错误码' :表示长度为5的sqlstate_value类型的错误代码;
- MySQL_error_code :匹配数值类型错误代码;
- 错误名称 :表示DECLARE ... CONDITION定义的错误条件名称。
- SQLWARNING :匹配所有以01开头的SQLSTATE错误代码;
- NOT FOUND :匹配所有以02开头的SQLSTATE错误代码;
- SQLEXCEPTION :匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;
- 3.处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。
- 语句可以是像“ 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';
创建一个名称为“InsertDataWithCondition”的存储过程,代码如下。 在存储过程中,定义处理程序,捕获sqlstate_value值,当遇到sqlstate_value值为23000时,执行EXIT操 作,并且将@proc_value的值设置为-1。
- #准备工作
- CREATE TABLE departments
- AS
- SELECT * FROM atguigudb.`departments`;
- ALTER TABLE departments
- ADD CONSTRAINT uk_dept_name UNIQUE(department_id);
-
- DELIMITER //
- CREATE PROCEDURE InsertDataWithCondition()
- BEGIN
- DECLARE duplicate_entry CONDITION FOR SQLSTATE '23000' ;
- DECLARE EXIT HANDLER FOR duplicate_entry SET @proc_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();
结果: