1. 变量分类
类型 | 语法 | 作用域 | 定义方式 | 示例 |
---|---|---|---|---|
用户变量 | @var_name |
当前会话(连接)有效 | 通过 SET 或 SELECT 直接赋值 |
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. 常见问题
- 用户变量与查询顺序
在单条SQL中多次修改用户变量可能导致不可预测结果,因执行顺序依赖优化器。例如:
SELECT @a := @a + 1, id FROM table; -- 确保先初始化@a
建议预先通过SET初始化变量。
2. 变量命名冲突
用户变量在会话内共享,避免在存储过程中使用同名变量造成干扰。
3. 数据类型
用户变量类型由赋值决定,可动态转换:
SET @value = '100'; -- 字符串
SET @value = @value + 0; -- 转为整型
总结
-
用户变量:临时存储会话级数据,适用于行号生成、中间计算。
-
系统变量:配置服务器行为,区分全局和会话作用域。
-
局部变量:封装在存储过程中,保证逻辑隔离。