菜鸟笔记
提升您的技术认知

MySQL 变量

阅读 : 177

1. 变量分类

类型 语法 作用域 定义方式 示例
用户变量 @var_name 当前会话(连接)有效 通过 SETSELECT 直接赋值 SET @age = 25;
系统变量 @@global.var_name
@@session.var_name
全局或当前会话 服务器预定义,通过 SET 修改 SET GLOBAL max_connections=200;
局部变量 var_name(无 @ 符号) 存储过程/函数的 BEGIN...END 块内 在存储过程/函数中使用 DECLARE 声明 DECLARE total INT DEFAULT 0;

2. 用户变量

特点

  • @ 开头,无需声明,直接赋值即可使用。
  • 作用域:当前会话(客户端连接),关闭连接后失效。
  • 赋值方式
SET @var = 1;                          -- 直接赋值
SELECT @var := column FROM table;      -- 通过查询赋值
SELECT MAX(column) INTO @var FROM table; -- INTO 语法
  • 示例:生成行号
SET @row_num = 0;
SELECT (@row_num := @row_num + 1) AS row_number, name 
FROM users 
ORDER BY name;

注意事项

  • 变量类型动态决定,赋值后自动推断(如整数、字符串)。

  • 避免在复杂查询中依赖赋值顺序,可能导致结果不稳定。

3. 系统变量

分类

  • 全局变量(GLOBAL):影响整个MySQL服务器,需SUPER权限修改。

  • 会话变量(SESSION):仅影响当前会话,每个新会话继承全局变量值。

常用操作

-- 查看全局变量
SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
SELECT @@global.wait_timeout;

-- 查看会话变量
SHOW SESSION VARIABLES LIKE 'sort_buffer_size';
SELECT @@session.sort_buffer_size;

-- 修改全局变量(需权限)
SET GLOBAL max_connections = 500;

-- 修改会话变量
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';

持久化配置

  • 使用SET PERSIST使全局变量永久生效(MySQL 8.0+):
SET PERSIST max_connections = 500;  -- 保存到配置文件

4. 局部变量

  • 定义:在存储过程、函数或触发器中通过DECLARE声明。

  • 作用域:仅在BEGIN…END块内有效。

  • 示例:

DELIMITER //
CREATE PROCEDURE calculate()
BEGIN
  DECLARE total INT DEFAULT 0;  -- 局部变量
  SET total = 10 + 20;
  SELECT total;
END //
DELIMITER ;

5. 关键区别

特性 用户变量 (@var) 系统变量 (@@var) 局部变量 (var)
前缀 @ @@
作用域 会话级 全局/会话级 存储过程/函数块内
声明方式 无需声明 服务器预定义 DECLARE显式声明
生命周期 会话结束销毁 服务器重启重置(全局) 块结束销毁

6. 常见问题

  1. 用户变量与查询顺序
    在单条SQL中多次修改用户变量可能导致不可预测结果,因执行顺序依赖优化器。例如:
SELECT @a := @a + 1, id FROM table;  -- 确保先初始化@a

建议预先通过SET初始化变量。
2. 变量命名冲突
用户变量在会话内共享,避免在存储过程中使用同名变量造成干扰。
3. 数据类型
用户变量类型由赋值决定,可动态转换:

SET @value = '100';  -- 字符串
SET @value = @value + 0;  -- 转为整型

总结

  • 用户变量:临时存储会话级数据,适用于行号生成、中间计算。

  • 系统变量:配置服务器行为,区分全局和会话作用域。

  • 局部变量:封装在存储过程中,保证逻辑隔离。