资讯专栏INFORMATION COLUMN

MySQL 之变量

rainyang / 3499人阅读

摘要:为用户变量赋值时,会先确定表达式的值。作为变量,都是有作用域的,用户变量的作用是整个会话,即整个会话间都是有效的。注意要想更改全局变量,必须具有权限。

MySQL 之变量

MySQL 的变量分为四种: 局部变量用户变量会话变量全局变量 ,其中局部变量只存在于函数和存储过程,这里不多了解。其中 会话变量全局变量 在 MySQL 中统称为 系统变量

用户变量 基本

顾名思义,就是用户定义的变量。如何定义变量呢?有两种方法:

SET 方式

# 两种方式都可以
SET @variable = expr
SET @variable := expr

SELECT 方式

# 必须 :=
SELECT @variable := expr

用户变量定义备注:

未定义变量的初始值为 null(可不定义变量直接使用,不会报错)

变量名对大小写不敏感

变量不能在要求字面值的地方使用,比如 select 中的 limit 语句等。

调用用户变量的表达式的计算顺序实际上是未定义的,如 SELECT @a = 0, @a := @a + 1;,两列都可能是 0 。

为用户变量赋值时,会先确定表达式的值。如何理解,请看如下代码:

SET @m = 0;
SET @m = 3, @n = @m;
SELECT @n; # 0

虽然用户变量的类型可以动态修改,但不建议这么操作,因为在交接代码的时候你可能会有生命危险:p。

作为变量,都是有作用域的,用户变量的作用是整个会话,即整个会话间都是有效的。这看起来不错,但要注意,当使用了连接池,自定义的用户变量又没有正确初始化,容易出现意想不到的问题。因为它实际上并没有被销毁,依旧记录者上一次的结果。

示例

我们来一个简单的示例,实现一个序号的功能,表和数据如下:

CREATE TABLE employee (
   id int primary key,
   salary int not null
);

INSERT INTO employee VALUES(1, 100);
INSERT INTO employee VALUES(2, 200);
INSERT INTO employee VALUES(3, 300);

根据之前学习的内容,我们可以很快的写出如下 SQL:

SELECT salary, (@rowno := @rowno + 1) AS "rowno"
FROM employee, (SELECT @rowno := 0) r;

没有问题,一切都和预期一样,然后我们加一个 WHERE 条件试试:

SELECT salary, (@rowno := @rowno + 1) AS "rowno"
FROM employee, (SELECT @rowno := 0) r
WHERE @rowno = 0;

理论上来说,这是不应该返回数据的,但是它还就是返回了一条数据,就是 id 为 1 的那条。
为什么呢? WHERE 条件使用的 @rowno 一直都是同一个值 0 ,它不会因为 SELECT 上修改了就实时响应 。要实现
WHERE 的功能需要改写成如下:

SELECT salary, rowno
FROM (
    SELECT salary, (@rowno := @rowno + 1) AS "rowno"
    FROM employee, (SELECT @rowno := 0) r
) m
WHERE rowno = 2;

实际上在 SELECTWHEREGROUP BYORDER BY 中用户变量都不会按预期操作,它使用的是旧值,不会实时修改。

系统变量 会话变量

会话变量为服务器为每个客户端连接维护的变量。在客户端连接时,使用相应全局变量的当前值对客户端的会话变量进行初始化。

顾名思义,会话变量的作用域就是一个会话 Session 咯。如何为会话变量设置值呢?如下:

set session var_name = value;
set @@session.var_name = value;
set var_name = value;

注意,只能为现有的会话变量设置值,不能创建新的会话变量。那如何获取会话变量呢?如下:

show session variables;
# 以上代码会把所有会话变量罗列出来,可通过 like 进行过滤
show session variables LIKE "%var%";
全局变量

全局变量会影响服务器整体操作。但是一旦重启,这些设置会被重置。注意要想更改全局变量,必须具有SUPER权限。

它的设置和会话变量的设置是类似的:

set global var_name = value;
set @@global.var_name = value;

全局变量也不能新增变量,只能修改已有的。而获取全局变量的操作也是和会话变量类似:

show session variables;
show global variables like "%var%";

文章若有问题,欢迎在评论区中指正。


参考:

深入MySQL用户自定义变量:使用详解及其使用场景案例

mysql用户变量和set语句

9.4 User-Defined Variables

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/17874.html

相关文章

  • MySQL内核技术“pthead局部变量

    摘要:使用了称之为的一系列文件和结构来进行监控。的使用就像一个全局变量,哪个线程都可以用,但是实际上对应了线程内部的变量值,可以参见该例。规定,线程存储变量必须要先初始化。 MySQL使用了称之为psi/pfs的一系列文件和结构来进行performance监控。Psi全称为performance schema interface,pfs全称为performance storage。 该机制使...

    KnewOne 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<