where中null判断失效因null非值而是缺失标记,须用is null;trim/replace无法处理unicode控制符;类型转换失败在mysql非严格模式下静默变null;update漏写精确where条件易误更新全表。

WHERE 条件里写 NULL 判断会失效?
常见错误现象:WHERE column = NULL 返回空结果,哪怕表里明明有 NULL 值
SQL 里 NULL 不是值,而是“缺失标记”,不能用 = 或 != 比较。所有涉及 NULL 的等值判断都会返回 UNKNOWN,而 WHERE 只接受 TRUE。
- 用
IS NULL或IS NOT NULL替代= NULL - 聚合函数如
COUNT(column)自动跳过NULL,但COUNT(*)不跳 —— 这常被误用来“查空行数” - 连接时
ON a.id = b.id若任一为NULL,该行直接不匹配,不是“匹配失败”,是“不参与连接”
字符串清洗:TRIM 和 REPLACE 够用吗?
使用场景:处理用户输入、CSV 导入、爬虫数据中混杂的空格、不可见字符(如 \t、\r、零宽空格)
TRIM() 只去首尾空格(默认空格,可指定字符),REPLACE() 能换指定子串,但两者都对 Unicode 控制符、全角空格、BOM 头无能为力。
- PostgreSQL 可用
REGEXP_REPLACE(col, '[\u200B-\u200D\uFEFF]+', '', 'g')清零宽字符 - MySQL 8.0+ 支持
REGEXP_REPLACE();老版本只能靠应用层或自定义函数 - 别用
REPLACE(col, ' ', '')清空格——它会把字段内正常空格也干掉,破坏语义
类型转换失败导致整列变 NULL?
错误现象:CAST(age_str AS INTEGER) 后整列变 NULL,但只有一两行是非法值
多数数据库(如 PostgreSQL、SQL Server)在类型转换失败时默认抛错;但 MySQL 在非严格模式下会静默转成 0 或 NULL,且不报任何提示,极易掩盖脏数据。
- PostgreSQL 推荐用
col::INTEGER+NULLIF()组合:例如NULLIF(TRIM(age_str), '')::INTEGER - MySQL 开启严格模式(
STRICT_TRANS_TABLES)让转换失败立刻报错,而不是吞掉异常 - 避免用
CONVERT()或CAST()直接套原始字段,先用REGEXP_LIKE()(MySQL 8.0+/PostgreSQL)筛出合法格式再转
UPDATE 时 WHERE 条件漏写主键,全表被改?
真实踩坑场景:开发环境跑完 UPDATE user SET status = 'active',发现 20 万用户全激活了
没有 WHERE 的 UPDATE / DELETE 是高危操作,但更危险的是 WHERE 写得不精确,比如用 WHERE name = '张三' —— 名字重复太常见。
- 执行前先用
SELECT COUNT(*)验证条件命中行数,尤其涉及JOIN或子查询时 - 在事务里操作:
BEGIN; UPDATE ...; SELECT ROW_COUNT(); ROLLBACK;(MySQL)或SELECT pg_affected_rows()(PostgreSQL) - 别依赖 IDE 的“安全更新模式”,它只拦没
WHERE,不拦弱条件;真正安全的是主键/唯一索引字段 + 明确值
phone 字段,你以为只是空格多,结果发现混着 +86、86-、(010)、138****1234 四种格式,还夹着“暂无”“不详”“/”。这种得先 GROUP BY 看分布,再分策略处理,没法一条 SQL 搞定。










