vlambda博客
学习文章列表

MySQL声明变量以及赋值

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

  • 用户变量

    • SET 方式

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


    • SELECT 方式

      # 必须 :=SELECT @variable := expr

      • 示例

        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;
        +--------+-------+| salary | rowno |+--------+-------+| 100 | 1 || 200 | 2 || 300 | 3 |+--------+-------+
      • 没有问题,一切都和预期一样,然后我们加一个 WHERE 条件试试:

        SELECT salary, (@rowno := @rowno + 1) AS 'rowno'FROM employee, (SELECT @rowno := 0) rWHERE @rowno = 0;
        +--------+-------+| salary | rowno |+--------+-------+| 100 | 1 |+--------+-------+
      • 理论上来说,这是不应该返回数据的,但是它还就是返回了一条数据,就是 id 为 1 的那条。

      • 为什么呢?WHERE 条件使用的 @rowno 一直都是同一个值 0 ,它不会因为 SELECT 上修改了就实时响应 。要实现 WHERE 的功能需要改写成如下:

        SELECT salary, rownoFROM ( SELECT salary, (@rowno := @rowno + 1) AS 'rowno' FROM employee, (SELECT @rowno := 0) r) mWHERE rowno = 2;
        +--------+-------+| salary | rowno |+--------+-------+| 200 | 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%";