NULL表示未知或缺失值,空字符串是长度为0的有效字符串;判断NULL必须用IS NULL/IS NOT NULL,空字符串可用= ''匹配;二者语义、存储、聚合及索引行为均不同,混用会导致查询漏数据、统计偏差与逻辑崩溃。

别指望 = NULL 能进分支,也别让 NULL 参与加减乘除——它不会报错,但会让结果静默变 NULL,后续逻辑全崩。
IF 条件里判断 NULL 为什么总不进分支
SQL 的三值逻辑决定了:IF @status = 'active' 遇到 @status 是 NULL 时,整个表达式返回 UNKNOWN,而 IF 只响应 TRUE,UNKNOWN 和 FALSE 都跳过分支。
- 错误写法:
IF @status = 'active' BEGIN ... END→@status为NULL时,分支完全不执行 - 正确写法:
IF @status IS NULL BEGIN ... END或IF @status = 'active' OR @status IS NULL BEGIN ... END(按业务是否需包含空值) - 想统一走等值逻辑?先转换:
DECLARE @norm_status VARCHAR(20) = COALESCE(@status, 'unknown'),再用IF @norm_status = 'active'
WHERE 中参数为 NULL 时如何跳过该条件
常见于可选搜索参数场景。核心是把“参数为空”和“字段匹配”拆成两个独立逻辑,用 OR 连接,避免整条条件被 UNKNOWN 拖垮。
- 安全模式:
WHERE (@name IS NULL OR name = @name) AND (@age IS NULL OR age = @age) - 千万别写:
WHERE name = ISNULL(@name, name)→ 表面简洁,但ISNULL(@name, name)会阻止索引使用 - 注意参数顺序:带
DEFAULT NULL的参数必须放在存储过程参数列表末尾,否则调用时跳过中间参数会报错expects parameter '@p2', which was not supplied
计算或拼接时遇到 NULL 导致结果全为 NULL 怎么办
NULL 参与算术、字符串连接、比较等操作,结果几乎总是 NULL。“未知 + 任何值 = 未知”,这不是 bug,是设计如此。
- 数值清洗:
SET @sum = @sum + COALESCE(@amount, 0),不能只补一个操作数 - 字符串兜底:
COALESCE(first_name, '') + ' ' + COALESCE(last_name, ''),任一为NULL就全崩 - 触发器中更危险:
CONCAT('ID:', id, '-', name)中任一字段为NULL,结果就是NULL,可能违反NOT NULL约束导致插入失败 - 跨库首选
COALESCE;若只跑 SQL Server,ISNULL类型更稳,但COALESCE(@x, 0)在 decimal 场景下可能升格精度,引发隐式截断
IN / NOT IN 里混入 NULL 为什么查不到数据
NOT IN (1, 2, NULL) 等价于 col != 1 AND col != 2 AND col != NULL,最后一项恒为 UNKNOWN,整个 AND 结果必为 UNKNOWN,WHERE 直接丢弃整行。
- 动态拼接时尤其危险:别直接拼
NOT IN (@list),若@list来自含NULL的表,结果集为空 - 替代方案一:
NOT EXISTS (SELECT 1 FROM @temp t WHERE t.val = col AND t.val IS NOT NULL) - 替代方案二:先清理再用,比如
WHERE col NOT IN (SELECT v FROM @temp WHERE v IS NOT NULL)
最常被忽略的点是:空字符串 '' 和 NULL 必须分开对待——它们语义不同、类型不同、索引行为也不同。业务上“未填”和“填了空”往往意味着完全不同的状态,混淆处理会掩盖真实数据问题。

















