coalesce是标准sql中处理null更新的可靠方式,应配合where column is null使用以避免全表重写;case适用于多分支逻辑;直接set column = default在多数数据库不兼容,需按数据库特性选用coalesce、ifnull或isnull,并注意字段实际业务默认值与约束默认值可能不一致。

UPDATE语句中用COALESCE或CASE处理NULL
直接写 SET column = DEFAULT 在多数数据库里不生效——标准SQL不支持这种语法,MySQL、PostgreSQL、SQL Server各自有不同限制。真正可靠的做法是显式指定默认值,或借助函数把 NULL 映射为该列定义的默认逻辑值。
常见错误是写成 UPDATE table SET column = DEFAULT WHERE column IS NULL,这在 PostgreSQL 中合法但在 MySQL 和 SQL Server 中会报错或静默失败。
- PostgreSQL 支持
DEFAULT关键字,但仅限单列且不能和表达式混用;更稳妥的是用COALESCE(column, 'default_value') - MySQL 不支持
DEFAULT作为赋值表达式,必须写死值或用IFNULL(column, 'default_value') - SQL Server 可用
ISNULL(column, 'default_value'),但注意类型要严格匹配,否则隐式转换可能出错
确认字段实际默认值来源
数据库里“默认值”可能来自三处:建表时的 DEFAULT 约束、应用层逻辑、或业务文档约定。不能假设 DESCRIBE table 或 SHOW CREATE TABLE 显示的 DEFAULT 就是当前应填的值——比如一个 INT 字段定义了 DEFAULT 0,但业务上要求空值补 -1。
- 查约束:PostgreSQL 用
\d table_name,MySQL 用SELECT COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='xxx' AND COLUMN_NAME='yyy' - 注意
COLUMN_DEFAULT可能是NULL(表示无默认)、字符串如'0',或表达式如current_timestamp()—— 后者没法直接复用到 UPDATE 中 - 如果字段有
NOT NULL约束但没设DEFAULT,UPDATE 时填值就不是“恢复默认”,而是补业务规则值
批量更新时避免意外覆盖非NULL数据
最常踩的坑是漏写 WHERE 条件,导致全表更新。哪怕加了 WHERE column IS NULL,也要提防字段本身存的是空字符串 '' 或空白空格,它们不是 NULL,但业务上可能等价。
- 安全写法永远带
WHERE column IS NULL,且执行前先用SELECT COUNT(*) FROM table WHERE column IS NULL预估影响行数 - 需要同时处理
NULL和空字符串?用WHERE column IS NULL OR TRIM(column) = ''(注意TRIM在 SQLite 中叫TRIM(),MySQL 5.7+ 支持,旧版得用RTRIM(LTRIM(column))) - 某些场景下,
UPDATE ... LIMIT 100(MySQL)或UPDATE ... RETURNING *(PostgreSQL)能帮你验证效果再跑全量
JSON或数组字段的NULL处理要额外小心
当字段类型是 JSON(MySQL/PostgreSQL)或 ARRAY(PostgreSQL)时,NULL 和空结构体(如 '{}' 或 '[]')语义不同。直接用 COALESCE(col, '{}') 可能引发类型错误,因为 NULL 是未知类型,而字符串字面量不是合法 JSON 值。
- MySQL:用
COALESCE(col, CAST('{}' AS JSON))强制转为 JSON 类型 - PostgreSQL:用
COALESCE(col, '{}'::json)或COALESCE(col, to_jsonb('{}'::text)) - 别用
col = col || '{}'::json这类拼接操作来“兜底”,NULL || anything结果仍是NULL
NULL 的传播性和各数据库对空值的容忍度差异,比想象中更隐蔽。











