sql server中未初始化变量参与运算结果恒为null,因含null的算术或字符串操作均返回null;必须显式初始化(如declare @var int = 0)或用isnull(@var, 0)包裹。

SQL Server 中 @var = @var + value 仍为 NULL?
因为 SQL Server 对 NULL 的算术运算结果始终是 NULL,哪怕另一侧是非空值。这不是 bug,是标准行为:任何含 NULL 的加减乘除都返回 NULL。
常见现象:@count 初始为 NULL,后续执行 SET @count = @count + 1,结果仍是 NULL,而非 1。
- 必须显式初始化:声明时就给默认值,例如
DECLARE @count INT = 0 - 或在每次累加前用
ISNULL(@count, 0)包裹,例如SET @count = ISNULL(@count, 0) + 1 - 不要依赖“变量已声明就等于 0”——未初始化的局部变量就是
NULL,不是 0
MySQL 存储过程里 SELECT ... INTO 赋值失败?
这是最易被忽略的隐式限制:SELECT ... INTO 要求查询**必须返回且仅返回一行**。若结果为空或超过一行,赋值直接静默失败(变量保持原值),不报错也不中断执行。
- 空结果 → 变量不变(不是设为
NULL,而是维持上次值或初始值) - 多行结果 → 报错
ERROR 1172 (42000): Result consisted of more than one row - 安全写法:先用
SELECT COUNT(*)验证,或改用SET var = (SELECT ...)(此时空结果返回NULL,多行仍报错) - 注意字段名与变量名冲突:如果
SELECT a FROM t INTO @a,而表t里真有列a,MySQL 会优先取列值而非赋值给变量,导致逻辑错乱
动态拼接 SQL 时 @sql = @sql + 'xxx' 突然变 NULL?
根本原因是:任意一端为 NULL,字符串拼接结果就是 NULL。哪怕 @sql 刚声明未赋值(即 NULL),第一次 SET @sql = @sql + 'WHERE...' 就让它永远卡死在 NULL。
- 必须在首次拼接前初始化,例如
DECLARE @sql NVARCHAR(MAX) = N'' - 或每次拼接都用
ISNULL(@sql, N''),例如SET @sql = ISNULL(@sql, N'') + N' AND id > 10' - 别信“我只拼一次”,只要逻辑分支中存在某条路径没初始化
@sql,后续所有拼接都失效 -
CONCAT()函数可自动把NULL当空字符串处理,但仅限 SQL Server 2012+;MySQL 5.7+ 也支持,但老版本得靠IFNULL()或COALESCE()
MySQL 存储过程中中文赋值变 NULL?
不是语法错,是字符集断层:存储过程内部变量默认继承 character_set_server,如果它是 latin1,而你传入 UTF-8 中文,就会被截断或转成问号,最终表现为 NULL 或乱码。
- 运行
SHOW VARIABLES LIKE 'character%';,重点看character_set_server和collation_server - 修改
my.cnf的[mysqld]段,加上character-set-server=utf8mb4和collation-server=utf8mb4_unicode_ci - 重启 MySQL;确认后还需检查数据库、表、字段是否也用了
utf8mb4,否则只是半截子修复 - 临时绕过:在拼接字符串前强制转换,例如
CONVERT('中文' USING utf8mb4),但治标不治本
变量赋值看似简单,真正难的是搞清“它此刻到底是什么值、从哪来、会被谁改”。尤其是跨数据库时,DECLARE 行为、NULL 处理、字符集继承这些细节全都不一样。别假设“和上次一样”,每次写新存储过程,先盯住初始化和空值路径。











