MySQL存储过程中判断NULL必须用IS NULL而非= NULL,因后者恒返回NULL;推荐COALESCE处理多层默认值,且需统一清洗输入、计算、插入各环节的NULL以避免静默错误。

存储过程中不能用 = NULL 判断 NULL
在 MySQL 存储过程中,= NULL 或 != NULL 永远返回 NULL(即逻辑假),不会命中任何分支。这是初学者最常踩的坑——写 IF my_col = NULL THEN,结果永远不执行。
必须改用 IS NULL 或 IS NOT NULL:
IF my_col IS NULL THEN SET result := 'missing'; ELSE SET result := my_col; END IF;
-
IS NULL是唯一安全、标准的 NULL 判定方式 -
ISNULL()函数虽存在,但它是IS NULL的别名,语义弱且易与 SQL Server 混淆,建议统一用IS NULL - 在
CASE表达式中同样适用:CASE WHEN col IS NULL THEN 'N/A' ELSE col END
COALESCE 比 IFNULL 更通用,适合多层 fallback
COALESCE 接收任意数量参数,从左到右返回第一个非 NULL 值;而 IFNULL 只支持两个参数。在存储过程里做默认值兜底时,COALESCE 更灵活:
SET display_name = COALESCE(input_name, user_profile.name, 'Guest', 'Anonymous');
- 当
input_name为NULL,尝试user_profile.name;若也为空,再 fallback 到字符串 - 所有参数类型需兼容(如混用字符串和数字会触发隐式转换,可能报错或截断)
- 注意:
COALESCE是 SQL 标准函数,在视图、函数、存储过程里行为一致;IFNULL是 MySQL 特有,跨数据库迁移时需替换
存储过程里 NULL 参与计算会导致整条表达式为 NULL
比如 SET total = price * qty;,只要 price 或 qty 是 NULL,total 就变成 NULL,后续判断或插入会出错。
正确做法是提前用 COALESCE 或 IFNULL 清洗:
SET total = COALESCE(price, 0) * COALESCE(qty, 0);
- 不要只处理一个字段:只写
COALESCE(price, 0) * qty,qty仍可能为NULL,结果还是NULL - 数值型字段建议补
0,字符串型建议补空字符串'',避免类型冲突 - 如果业务上
NULL代表“未知”而非“零”,补默认值前需确认语义是否合理
INSERT/UPDATE 语句中 NULL 处理要和存储过程逻辑对齐
存储过程里用 COALESCE(col, 0) 计算出值,但最终 INSERT 时又没控制源字段,可能导致数据不一致。例如:
INSERT INTO orders (amount) VALUES (COALESCE(@input_amount, 0));
这没问题;但若写成:
INSERT INTO orders (amount) VALUES (@input_amount);
而 @input_amount 在调用前未初始化或传入 NULL,就会存入 NULL,和前面计算逻辑脱节。
- 建议在存储过程入口就对关键输入参数做标准化:
SET @input_amount = COALESCE(@input_amount, 0); - 对
NOT NULL字段,务必在 INSERT 前确保值非NULL,否则触发约束错误 - 调试时可加
SELECT CONCAT('debug: ', @input_amount);快速验证变量状态
NULL 的传播性极强,一个没处理的 NULL 可能从参数传入、经计算、到条件判断、再到 INSERT,全程静默失效。存储过程里每处涉及变量参与运算或判断的地方,都要主动问一句:“它可能是 NULL 吗?我是否已明确处理?”











