MySQL 的变量分为四种: 局部变量 、 用户变量 、 会话变量 和 全局变量 ,其中局部变量只存在于函数和存储过程,这里很少了解。其中 会话变量 和 全局变量 在 MySQL 中统称为 系统变量 。html
顾名思义,就是用户定义的变量。如何定义变量呢?有两种方法:mysql
SET 方式sql
# 两种方式均可以 SET @variable = expr SET @variable := expr
SELECT 方式服务器
# 必须 := SELECT @variable := expr
用户变量定义备注:session
null
(可不定义变量直接使用,不会报错)select
中的 limit
语句等。SELECT @a = 0, @a := @a + 1;
,两列均可能是 0 。为用户变量赋值时,会先肯定表达式的值。如何理解,请看以下代码:函数
SET @m = 0; SET @m = 3, @n = @m; SELECT @n; # 0
做为变量,都是有做用域的,用户变量的做用是整个会话,即整个会话间都是有效的。这看起来不错,但要注意,当使用了链接池,自定义的用户变量又没有正确初始化,容易出现意想不到的问题。由于它实际上并无被销毁,依旧记录者上一次的结果。学习
咱们来一个简单的示例,实现一个序号的功能,表和数据以下:.net
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:code
SELECT salary, (@rowno := @rowno + 1) AS 'rowno' FROM employee, (SELECT @rowno := 0) r;
没有问题,一切都和预期同样,而后咱们加一个 WHERE 条件试试:htm
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;
实际上在 SELECT
的 WHERE
、 GROUP BY
和 ORDER 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%";
文章如有问题,欢迎在评论区中指正。
参考: