select @@variable_name 或 show session variables like 'name' 均可查当前会话变量值,前者精准快捷,后者需明确加 session 修饰符以防混淆;set session variable_name = value 为推荐写法,显式限定作用域且立即生效。

怎么查当前会话的变量值
直接用 SELECT @@variable_name 或 SHOW VARIABLES LIKE 'name' 都能查,但行为不同:SELECT @@sql_mode 查的是会话级值(优先返回会话覆盖后的),而 SHOW VARIABLES LIKE 'sql_mode' 默认显示会话值,但容易误以为是全局值——它其实取决于你有没有用 GLOBAL 修饰符。
常见误区:执行 SHOW VARIABLES 不加 LIKE 会返回全部变量,结果太多难定位;更推荐用 SHOW SESSION VARIABLES LIKE 'autocommit' 明确限定作用域。
-
SELECT @@autocommit—— 最快,适合单个变量快速验证 -
SHOW SESSION VARIABLES WHERE Variable_name = 'character_set_client'—— 支持 WHERE,比 LIKE 更精准 - 别用
SHOW VARIABLES看完就关,容易把 SESSION 和 GLOBAL 混在一起记错
修改会话变量的正确写法
用 SET 命令改,但必须分清 SESSION(或省略)、GLOBAL、@var 三类赋值目标。改会话变量不加修饰符默认就是 SESSION 级,但显式写上 SESSION 更安全,避免未来 MySQL 版本变更默认行为。
例如 SET autocommit = 0 和 SET SESSION autocommit = 0 效果一样,但前者在某些客户端(如旧版 MySQL Workbench)里可能被错误解析为全局操作。
- 支持表达式:比如
SET SESSION sort_buffer_size = 2 * 1024 * 1024 - 部分变量只读:如
@@version、@@hostname,设了会报错Variable 'version' is a read only variable - 字符串变量要加引号:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'
哪些会话变量改了立刻生效但有隐藏限制
像 autocommit、sql_mode、time_zone 这类改完当前连接立刻起效,但要注意它们不会继承到新连接——每个新连接都按全局配置或用户默认值初始化。
典型坑点:character_set_client、collation_connection 看似可设,但实际受客户端连接参数(如 charset 参数或 SET NAMES)更高优先级影响,单独设其中一个可能被覆盖。
-
SET NAMES utf8mb4实际等价于同时设character_set_client、character_set_results、character_set_connection,比逐个 SET 更可靠 -
max_execution_time只对后续 SELECT 生效,已运行的语句不受影响 - 事务中改
sql_mode不会影响当前语句校验逻辑,只影响之后的语句
怎么确认变量真被改成功了
别只信 SET 命令没报错,得立刻查一遍。尤其在自动化脚本或连接池场景下,中间可能被复用连接重置过变量。
推荐组合:先 SET SESSION xxx = yyy,紧接着 SELECT @@xxx 对比输出。如果值没变,八成是变量名拼错、权限不足(如普通用户不能设 sql_log_bin),或者该变量根本不可动态设置。
- 权限检查:执行
SELECT CURRENT_USER(),再查SHOW GRANTS,确认是否有SYSTEM_VARIABLES_ADMIN(MySQL 8.0+)或SUPER权限 - 变量是否动态:查
INFORMATION_SCHEMA.SESSION_VARIABLES(MySQL 8.0.16+)或官方文档,静态变量只能重启生效 - 连接池干扰:Druid、HikariCP 默认重置会话变量,需配置
connectionInitSql或sessionInitSql
改会话变量不是“设完就完”,真正麻烦的是跨连接一致性、连接复用时的变量残留、以及和客户端编码参数的耦合。这些地方不盯紧,查半天数据乱码或超时,最后发现只是 character_set_results 被悄悄重置了。











