MySQL局部变量未显式赋值时默认为NULL,是明确设计行为;声明时应使用DEFAULT指定确定初值(如DEFAULT 0或DEFAULT ''),避免逻辑判断、算术运算及WHERE条件中因NULL导致静默错误。

MySQL局部变量默认值就是NULL
MySQL中用DECLARE声明的局部变量,只要没显式赋值,初始值恒为NULL——这不是bug,是明确设计行为。它和用户变量(@var)一样,不初始化就等于NULL,且无法通过配置关闭。
为什么不能靠“未声明=未使用”来规避
常见误解是“我没写SET v_x = ...,那它应该不存在或报错”,但MySQL不这么处理:
-
DECLARE v_id INT;之后立即SELECT v_id;,结果就是NULL - 在
IF v_id > 10 THEN ...里,v_id为NULL会导致整个条件判定为UNKNOWN,直接跳过分支(不是进ELSE) - 参与算术运算如
SET v_total = v_id + 100;,结果仍是NULL(因为NULL + 100 = NULL)
哪些地方容易因这个NULL静默出错
最危险的是逻辑判断和聚合场景,表面无报错,结果却不对:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
WHERE id = v_id→ 实际变成WHERE id = NULL,永远不匹配(必须改用WHERE id v_id或先判空) -
INSERT INTO log (user_id) VALUES (v_id);→ 插入NULL,可能违反NOT NULL约束而报错 -
SELECT COUNT(*) FROM t WHERE status = v_status;→ 若v_status是NULL,整条语句查不到任何行,但也不会提示你参数为空
怎么安全初始化局部变量
别依赖“后面会赋值”,声明时就给确定初值:
- 数值类:
DECLARE v_count INT DEFAULT 0; - 字符串类:
DECLARE v_name VARCHAR(50) DEFAULT ''; - 时间类:
DECLARE v_at DATETIME DEFAULT NOW(); - 避免
DEFAULT NULL写法——它多余且易误导,DECLARE本身就不带默认值,DEFAULT只是显式重申
如果变量用途是接收查询结果,优先用SELECT ... INTO v_var,它会在无匹配行时把v_var设为NULL,这时你得立刻检查:IF v_var IS NULL THEN ...,而不是假设它“有值”。

















