在MySQL/MariaDB中有好几种变量类型:用户自定义变量、系统变量、一般的临时变量(即本地变量,或称为局部变量)。

1.用户变量

用户变量是基于会话的,也是基于用户的,所以我觉得称之为会话变量更合适,但会话变量一般用来表示系统会话变量(后面会说明),所以还是称之为用户变量好了。

只有本用户才能引用自身的用户变量,其他用户无法引用,且当用户退出会话时,用户变量自动销毁。

用户变量使用"@"开头,用户变量可以直接赋值,无需事先声明。在引用未赋值的用户变量时,该变量值为null

有以下三种方式设置用户变量:

  1. set语句,此时可以使用"="或者":="操作符;
  2. select语句,此时只能使用":="格式赋值,因为除了set语句中,"="都会被视为比较操作符。;
  3. select ... into var_name from TABLE语句,此时要求select语句只能返回标量值,即单行数据。因此为了保险,select into var_name的时候,应尽量结合limit语句限制输出。
set @a1=1,@a2=3,@a3:=2;
select @a4:=@a1+@a3;
select 33,'abc' into @a5,@a6 from dual;

查看变量值可以使用select语句。

MariaDB [test]> select @a1,@a2,@a3,@a4,@a5,@a6,@a7;
+------+------+------+------+------+------+------+
| @a1  | @a2  | @a3  | @a4  | @a5  | @a6  | @a7  |
+------+------+------+------+------+------+------+
|    1 |    3 |    2 |    3 |   33 | abc  | NULL |
+------+------+------+------+------+------+------+

在mariadb 10.2.6中,引入了一张系统架构表information_schema.USER_VARIABLES,该表中记录了当前用户当前会话定义的用户变量信息。该信息架构表在mysql中没有。

MariaDB [test]> SELECT * FROM information_schema.USER_VARIABLES;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| a6            | abc            | VARCHAR       | utf8               |
| i             | 2              | INT           | utf8               |
| a5            | 33             | INT           | utf8               |
| a1            | 1              | INT           | utf8               |
| a4            | 3              | INT           | utf8               |
| a2            | 3              | INT           | utf8               |
| a3            | 2              | INT           | utf8               |
+---------------+----------------+---------------+--------------------+

2.系统变量

在MySQL/mariadb中维护两种系统变量:全局系统变量和会话系统变量。系统变量是用来设置MySQL服务运行属性和状态的。

全局系统变量使用global或者"@@global."关键字来设置。会话系统变量使用session或者"@@session."关键字来设置,其中session可以替换为Local,它们是同义词。如果省略这些关键字,则默认为session系统变量。设置global系统变量要求具有super权限。

-- 设置全局系统变量
set global sort_buffer_size=32M;
set @@global.sort_buffer_size=32M;
-- 设置会话系统变量
set session sort_buffer_size=32M;
set @@session.sort_buffer_size=32M;
set sort_buffer_size=32M;
-- 查看全局系统变量值
select @@global.sort_buffer_size;
show global variables like "sort_buffer%";
-- 查看会话系统变量,不能使用select sort_buffer_size
select @@session.sort_buffer_size;
select @@sort_buffer_size;
show [session] variables like "sort_buffer%";
-- 一次性设置多个变量,包括会话变量、全局变量以及用户变量
SET @x = 1, SESSION sql_mode = '';
SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;
SET @@global.sort_buffer_size = 1000000, @@local.sort_buffer_size = 1000000;
SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;

全局系统变量对全局有效,当有新的会话打开时,新会话会继承全局系统变量的值,所以设置全局系统变量之后新打开的会话都会继承设置后的值。设置全局系统变量对已经打开的连接无效,但是其他已经打开的连接可以查看到设置后的全局系统变量值。

系统变量按照是否允许在运行时修改,还分为动态变量和静态变量。能在运行过程中修改的变量称为动态变量,只能在数据库实例关闭状态下修改的变量称为静态变量或只读变量。动态变量使用set修改。如果在数据库实例运行状态下修改静态变量,则会给出错误。如:

set @@innodb_undo_tablespaces=3;
ERROR 1238 (HY000): Variable 'innodb_undo_tablespaces' is a read only variable

系统变量除了可以在运行中的环境下设置,还可以在配置文件中或者mysqld/mysqld_safe这样的命令行中设置,甚至mysql客户端命令行也可以传递。在配置文件中设置系统变量时,下划线或者短横线都允许,它们表示同一个意思。例如下面的两行配置是等价的:

innodb_file_per_table=1
innodb-file-per-table=1

3.局部变量

局部变量也称为本地变量,只能在begin...and语句块中生效。它不像用户变量,本地变量必须使用declare事先声明,所以declare也必须在begin...end中使用。

局部变量无论是声明还是调用的时候都不需要任何多余的符号(即不需要@符号),直接使用其名称var_name即可。

使用declare声明变量,可以一次性声明多个同类型的变量,需要时可有直接为其指定默认值,不指定时默认为null。

decalre var_name,... type [default value];

使用set为变量赋值。MySQL/mariadb中set支持一次性赋值多个变量。

在begin...end中的set是一般set语句的扩展版本,它既可以设置系统变量、用户变量,也可以设置此处的本地变量。

set var_name=expr,[var_name=expr1,...]

或者使用select...into语句从表中获取值来赋值给变量,但是这样的赋值行为要求表的返回结果必须是单列且单行的标量结果。例如下面的语句将col的列值赋值给var_name变量。

select col into var_name from table_name;

因为局部变量只能在begin...end中使用,所以此处使用存储过程的例子来演示。

DROP PROCEDURE IF EXISTS haha;
DELIMITER $$
CREATE PROCEDURE haha()
BEGINDECLARE a INT;SET a=1;SET @i:=2;SELECT a,@i;
END$$
DELIMITER ;CALL haha();a        @i
------  --------1         2

在MySQL中,begin...end只能定义在存储程序中,所以declare也只能定义在存储程序内。但在mariadb中,begin...end是允许定义在存储程序(存储函数,存储过程,触发器,事件)之外的,所以decalre也算是能够定义在存储程序之外吧。需要定义在存储程序之外时,使用 begin not atomic 关键字即可。例如:

delimiter $$
begin not atomicdeclare a int;set a=3;select a;
end$$

3.1 declare锚定其他对象的数据类型

在mariadb 10.3中(注意版本号,目前10.3版本还在测试中),declare语句允许在存储程序中使用TYPE OFROW TYPE OF 关键字基于表或游标来锚定数据类型。在mysql中不支持数据类型的锚定功能。

例如:

DECLARE tmp TYPE OF t1.a; -- 基于表t1中的a列获取数据类型
DECLARE rec1 ROW TYPE OF t1; -- 锚定表t1中行数据类型
DECLARE rec2 ROW TYPE OF cur1; -- 基于游标cur1获取行数据类型

通过其他对象来锚定本地变量的数据类型时,如果对象的数据类型改变,则本地数据类型也随之改变。这在某些时候非常有利于维护存储程序。

在定义存储程序时,不会检查declare锚定的对象是否存在。但在调用存储程序时,会先检查锚定对象是否存在。

当declare语句的锚定是基于表对象(不是游标)时,在调用存储程序的瞬间就会检查锚定的表是否存在,然后立刻声明该变量。因此:

  • (1).带有锚定功能的decalre语句可以定义在存储程序的任意位置;
  • (2).在存储程序中删除锚定的表对象,或者修改了锚定的表结构,都不会改变存储程序调用时声明的变量类型;
  • (3).所有带锚定功能的declare都是在存储程序调用之初被赋值的。

当declare语句的锚定是基于游标对象时,变量的数据类型是在执行变量声明语句时才获取到的。数据类型仅只锚定一次,之后不再改变。如果游标中的ROW TYPE OF变量是定义在一个循环之中,则数据类型在循环的开头就已经获取,且之后的循环不再改变。

示例:

create table t1(a int,b char(20));
drop procedure if exists haha;
delimiter $$
create procedure haha()
begindeclare x type of t1.a;set x=1;select x;
end$$
delimiter ;call haha();

MariaDB/MySQL中的变量相关推荐

  1. 如何在MySQL中声明变量?

    本文翻译自:How to declare a variable in MySQL? How to declare a variable in mysql, so that my second quer ...

  2. 中set无效是怎么回事_一起认识下,那些我们应该知道的mysql中的变量知识点

    前言: 这篇文章主要是认识一下mysql中的变量,本来是不准备整理的,但是发现后面的存储过程等等在实际用的时候还挺多. mysql里面的变量你可以和java中的变量进行对比理解.主要分为两种:系统变量 ...

  3. MySql中的变量定义

    根据mysql手册,mysql的变量分为两种:系统变量和用户变量.但是在实际使用中,还会遇到诸如局部变量.会话变量等概念.根据个人感觉,mysql变量大体可以分为四种类型: 一.局部变量. 局部变量一 ...

  4. 刘先森 MySql中的变量定义

    根据mysql手册,mysql的变量分为两种:系统变量和用户变量.但是在实际使用中,还会遇到诸如局部变量.会话变量等概念.根据个人感觉,mysql变量大体可以分为四种类型: 一.局部变量. 局部变量一 ...

  5. 在mysql中会话变量前面的字符是什么_在MySQL中仅使用会话变量仅对字符的首次出现执行搜索/替换...

    要仅对首次出现的位置执行搜索/替换,请使用CONCAT和REPLACE()方法. 查询如下以设置用户定义的会话变量-mysql> set @Sentence='Thks ks is a my s ...

  6. MySQL中变量的定义和变量的赋值使用(转)

    说明:现在市面上定义变量的教程和书籍基本都放在存储过程上说明,但是存储过程上变量只能作用于begin...end块中,而普通的变量定义和使用都说的比较少,针对此类问题只能在官方文档中才能找到讲解. 前 ...

  7. MySQL中变量的定义和变量的赋值使用

    MySQL中变量的定义和变量的赋值使用 前言 MySQL存储过程中,定义变量有两种方式: 1.使用set或select直接赋值,变量名以@开头 例如: set @var=1; 可以在一个会话的任何地方 ...

  8. mysql查询语句 变量_mysql查询语句中用户变量的使用

    先上代码吧 SELECT `notice`.`id` , `notice`.`fid` , `notice`.`has_read` , `notice`.`notice_time` , `notice ...

  9. MySql基础篇——变量、流程控制与游标

    一.变量 在mysql数据库中,变量分为系统变量以及用户自定义变量. 1.系统变量 1.1 介绍 系统变量由系统定义,属于服务器层面.启动mysql服务,生成mysql服务实例期间,mysql将为my ...

最新文章

  1. Python 爬虫框架Scrapy安装汇总
  2. 首批国家级一流本科专业公布,至少64所高校计算机相关专业入选,AI专业不够推荐资格...
  3. Docker创建springboot项目镜像pom及Dockerfile配置文件
  4. Android之获取设备的型号和手机厂商
  5. 32位linux系统支持多大内存吗,linux32位操作系统支持大内存
  6. 初探下一代SIEM核心技术发展趋势
  7. SQL数据库层面操作(DDL)
  8. Make jQuery throw error when it doesn't match an element
  9. Struts2的OGNL表达式
  10. Linux一键安装Aria2+Yaaw+FileManager实现BT磁力下载,并在线查看/观看
  11. 架构师害怕程序员知道的十项技能
  12. 怎么压缩PPT大小?PPT太大了怎么压缩?
  13. python圆形代码_python圆形函数
  14. ddr5和ddr4的区别 ddr5和ddr4性能差别
  15. 卷积学习与传统稀疏编码、ICA模型学习区别(逐步补充)
  16. android 电池检测软件,电池寿命检测软件下载-电池寿命检测 安卓版v2.7.0-PC6安卓网...
  17. 王浩:哥德尔思想概说
  18. 北京大学计算机学院保研名单,北京大学2011年保研名单汇总
  19. react-scripts的工作原理
  20. Android权限适配,动态申请权限

热门文章

  1. html中radio设置默认值
  2. 爱读掌阅java版_爱读掌阅app官方下载-爱读掌阅旧版本 - 超好玩
  3. 精彩回顾 | 客户体验官俱乐部(CEOC)首届主题论坛在深圳圆满落幕
  4. Gson系列1 --- Gson 序列化与反序列化 -- 数组 / 集合序列化
  5. SQL Server Management Studio管理数据库
  6. 用Nginx做端口转发(反向代理)
  7. PHP unlink的使用
  8. 原生js获取document_常见的原生javascript DOM操作
  9. python Pygame库介绍和使用,基本游戏开发
  10. excel文件下载下来损坏 js_使用Java / javascript和apache POI导出.xls文件时获取损坏的文件...