mysql中SET语句赋值与变量设置的基础操作

来源:这里教程网 时间:2026-02-28 20:45:43 作者:

SET 语句设置用户变量时必须用
@
前缀

MySQL 中

SET
赋值分两类:系统变量(如
sql_mode
)和用户变量(自定义,以
@
开头)。不加
@
直接写变量名,MySQL 会当成系统变量或报错——比如
SET myvar = 1
会提示
Unknown system variable 'myvar'

正确写法是
SET @myvar = 1
SET @myvar := 1
=
:=
SET
语句中等价,但在
SELECT
中只有
:=
是赋值操作符
用户变量作用域是当前会话,断开连接后自动销毁

SET 修改全局/会话级系统变量需明确作用域前缀

autocommit
max_connections
这类系统变量,直接
SET max_connections = 200
默认修改的是当前会话值;要改全局,必须显式加
GLOBAL
SESSION
(后者可省略)。

仅影响当前连接:
SET SESSION sort_buffer_size = 4*1024*1024
影响所有新连接(需 SUPER 权限):
SET GLOBAL max_connections = 500
查看当前值:
SELECT @@sort_buffer_size
(会话)或
SELECT @@GLOBAL.max_connections
某些变量只读,例如
version
,执行
SET version = 'x'
会报错
Variable 'version' is a read only variable

用户变量在 SELECT 中赋值容易混淆
=
:=

SELECT
里用
=
是比较操作符,不是赋值。如果写成
SELECT @sum = @sum + value FROM t
,结果全是
0
1
(布尔判断),而不是累加。

SELECT @sum := @sum + value FROM t;
必须用
:=
才能赋值
首次使用前建议初始化:
SET @sum := 0
,否则
@sum
NULL
,后续计算结果全为
NULL
这种写法常用于模拟窗口函数(如累计求和),但不可靠:MySQL 不保证
SELECT
的行处理顺序,除非配合
ORDER BY
显式排序

SET 不能跨语句复用表达式结果,临时表或 CTE 更可靠

有人想用

SET @val = (SELECT COUNT(*) FROM users); SELECT @val, @val * 2;
看似可行,但若中间穿插了其他
SELECT ... INTO @var
或触发器,
@val
可能被意外覆盖。更麻烦的是,存储过程里多个
SET
之间没有隐式事务保护。

复杂逻辑建议改用临时表:
CREATE TEMPORARY TABLE tmp AS SELECT COUNT(*) c FROM users;
MySQL 8.0+ 推荐用 CTE:
WITH t AS (SELECT COUNT(*) c FROM users) SELECT c, c*2 FROM t;
用户变量不适合并发场景——两个会话同时
SET @id = ...
互不影响,但若依赖变量做业务逻辑(如生成单号),极易出错

变量生命周期短、无类型、易被覆盖,这些特性决定了它只适合简单会话内临时传递值。真要持久或结构化,别硬扛。

相关推荐