MySQL 变量详解:系统变量与自定义变量的使用
MySQL 中的变量是存储数据的容器,分为系统变量(MySQL 内置,控制数据库行为)和自定义变量(用户定义,用于查询或存储过程中传递数据)。合理使用变量可简化操作、提升脚本灵活性。本文详细解析两类变量的定义、使用及区别。
系统变量:控制 MySQL 运行行为
系统变量是 MySQL 预定义的变量,用于配置数据库的运行参数(如连接数、缓存大小等),分为全局变量(影响所有会话)和会话变量(仅影响当前会话)。
系统变量的分类与作用
| 类型 |
作用范围 |
生效时机 |
示例 |
| 全局变量 |
所有会话(连接) |
重启 MySQL 或通过 SET GLOBAL 修改后生效 |
max_connections(最大连接数) |
| 会话变量 |
当前会话(连接) |
会话启动时继承全局变量,SET SESSION 修改后立即生效 |
autocommit(自动提交开关) |
查看系统变量
(1)查看所有系统变量
1 2 3 4 5
| SHOW GLOBAL VARIABLES;
SHOW SESSION VARIABLES;
|
(2)过滤查询特定变量
使用 LIKE 匹配变量名(支持通配符 %):
1 2 3 4 5
| SHOW GLOBAL VARIABLES LIKE '%timeout%';
SHOW SESSION VARIABLES LIKE 'character_set_%';
|
(3)查询单个变量的值
通过 @@ 符号访问变量:
1 2 3 4 5 6
| SELECT @@GLOBAL.max_connections;
SELECT @@SESSION.autocommit; SELECT @@autocommit;
|
修改系统变量
(1)修改全局变量
1 2 3 4 5
| SET GLOBAL max_connections = 1000;
SET @@GLOBAL.max_connections = 1000;
|
- 注意:
- 全局变量修改后,新会话会生效,已有会话不受影响。
- 部分变量需重启 MySQL 才能生效(如
innodb_buffer_pool_size),可通过 SHOW VARIABLES 确认是否生效。
(2)修改会话变量
1 2 3 4 5 6 7 8
| SET SESSION autocommit = 0;
SET @@SESSION.autocommit = 0;
SET autocommit = 0;
|
- 注意:会话变量修改仅对当前连接有效,断开连接后失效。
自定义变量:用户定义的数据容器
自定义变量是用户在查询或存储过程中定义的变量,用于临时存储数据,分为用户变量(会话级别)和局部变量(存储过程 / 函数内有效)。
用户变量(会话级别)
用户变量在当前会话内有效,可跨 SQL 语句使用,声明时需加 @ 前缀。
(1)声明与赋值
用户变量无需提前声明类型,赋值时自动确定类型,支持三种赋值方式:
1 2 3 4 5 6 7 8 9
| SET @user_var1 = 100; SET @user_var2 := 'hello';
SELECT @user_var3 := 3.14;
SELECT COUNT(*) INTO @user_var4 FROM users;
|
(2)使用用户变量
1 2 3 4 5 6 7 8
| SELECT @user_var1, @user_var2;
SELECT * FROM orders WHERE total > @user_var1;
SET @sum_var = @user_var1 + @user_var3;
|
(3)特点
- 作用范围:当前会话(连接),其他会话不可见。
- 生命周期:会话结束后自动销毁。
- 无需声明类型,灵活但缺乏类型检查。
局部变量(存储过程 / 函数内)
局部变量仅在定义它的 BEGIN...END 代码块(如存储过程、函数)中有效,需显式声明类型。
(1)声明与赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DELIMITER // CREATE PROCEDURE test_local_var() BEGIN DECLARE var1 INT; DECLARE var2 VARCHAR(50) DEFAULT 'default'; SET var1 = 200; SET var2 := 'local variable'; SELECT var1, var2; END // DELIMITER ;
CALL test_local_var();
|
(2)特点
- 作用范围:仅在声明它的
BEGIN...END 块内有效(如存储过程执行结束后失效)。
- 必须声明类型(如
INT、VARCHAR),有类型检查。
- 声明位置:必须在代码块的最开头(
DECLARE 语句需放在所有 SQL 语句之前)。
用户变量与局部变量的区别
| 特性 |
用户变量 |
局部变量 |
| 声明前缀 |
需加 @(如 @var) |
不加前缀(如 var) |
| 声明位置 |
会话中任意位置 |
仅在 BEGIN...END 块开头 |
| 作用范围 |
当前会话 |
所在的代码块(如存储过程) |
| 类型检查 |
无(自动推断) |
有(需显式声明类型) |
| 使用场景 |
跨语句传递数据 |
存储过程 / 函数内临时计算 |
变量使用的注意事项
- 系统变量的权限:
- 修改全局变量需要
SUPER 权限,普通用户只能查看。
- 会话变量通常无需特殊权限,用户可修改自己会话的变量。
- 自定义变量的性能:
- 用户变量在复杂查询中可能导致优化器无法有效优化,建议仅用于简单场景。
- 局部变量在存储过程中性能较好,适合复杂逻辑中的数据传递。
- 变量名冲突:
- 避免自定义变量与系统变量同名(如
@max_connections 可能与全局变量混淆)。
- 局部变量名避免与表字段名重名,否则可能导致查询歧义