coalesce是跨数据库兼容的null兜底方案,update中直接写default仅postgresql支持且需列明确定义默认值;mysql、sql server不支持该语法,会报错。

UPDATE语句里用COALESCE或CASE处理NULL
直接写 SET column = DEFAULT 在多数数据库里不生效——SQL标准不支持这种写法,MySQL、PostgreSQL、SQL Server 都会报错或忽略。真正可靠的方式是显式指定默认值,或者用函数把 NULL 映射过去。
最常用的是 COALESCE:它返回第一个非 NULL 的值,适合给字段“兜底”。比如字段定义为 status VARCHAR(10) DEFAULT 'pending',但表里已有 NULL,想批量补上:
UPDATE orders SET status = COALESCE(status, 'pending') WHERE status IS NULL;
如果默认值是数字、日期或需要动态计算(比如取当前时间),也一样适用:COALESCE(created_at, NOW())、COALESCE(price, 0)。
-
COALESCE是标准 SQL,所有主流数据库都支持 - 别用
ISNULL()(SQL Server 专用)或IFNULL()(MySQL 专用),跨库迁移时会出问题 - 注意:如果字段有
NOT NULL约束但没设默认值,先ALTER TABLE加约束或默认值,否则 UPDATE 后可能违反约束
用DEFAULT关键字只在特定场景有效
只有 PostgreSQL 支持在 UPDATE 中直接写 DEFAULT,且仅限该字段在表定义中明确声明了 DEFAULT 值:
UPDATE users SET last_login = DEFAULT WHERE last_login IS NULL;
但这不是“读取当前列的默认值”,而是让 PostgreSQL 按建表时的 DEFAULT 表达式重新计算一次(比如 NOW() 会变成当前时间,不是原默认值的时间)。MySQL 和 SQL Server 完全不认这个语法,会报错 ERROR 1064 或类似提示。
PostgreSQL 18.4 官方 Ubuntu 安装包现已发布,这是目前最新的稳定版本。推荐通过官方 APT 仓库安装:先执行 sudo apt update 更新索引,再运行 sudo apt install postgresql-18 即可完成部署。新版本引入了异步 I/O 子系统,在顺序扫描与 VACUUM 场景下性能提升显著,同时支持 UUID v7 原生生成函数与虚拟生成列。
- PostgreSQL 中可用,但行为依赖具体
DEFAULT定义(函数类默认值每次计算) - MySQL 中写
SET col = DEFAULT(col)仅在 8.0+ 支持,且必须确保列有显式DEFAULT,否则报错Unknown column 'DEFAULT(col)' in 'field list' - Oracle 不支持
DEFAULT关键字用于 UPDATE,只能靠显式值或NVL()
WHERE条件漏掉IS NULL容易全表误更新
这是线上事故高发点:有人写 UPDATE t SET x = COALESCE(x, 'val') 却忘了加 WHERE,结果把所有行都刷了一遍——即使原来不是 NULL,也会重复赋相同值,触发更新日志、主从延迟、触发器等副作用。
- 务必加上
WHERE column IS NULL,避免无谓更新 - 执行前先用
SELECT COUNT(*) FROM table WHERE column IS NULL确认影响行数 - 生产环境建议加
LIMIT(MySQL/PostgreSQL 支持)做防护,例如WHERE column IS NULL LIMIT 1000,分批跑 - 如果字段类型是
TEXT或大对象,COALESCE不影响性能;但对索引字段频繁更新可能引起页分裂,留意监控
ALTER COLUMN … SET DEFAULT 不影响已有数据
很多人以为给字段加了 DEFAULT 就自动修复历史 NULL,其实不会。ALTER TABLE ... SET DEFAULT 只改变后续 INSERT 的行为,对现有 NULL 记录完全没作用。
比如执行了:
ALTER TABLE products ALTER COLUMN category SET DEFAULT 'other';
之后新插入不填 category 的行会自动是 'other',但老的 NULL 还是 NULL,得靠前面说的 UPDATE 手动修正。
- PostgreSQL 中
SET DEFAULT不修改存储,只是元数据变更 - MySQL 的
ALTER TABLE ... MODIFY COLUMN ... DEFAULT ...同样只影响未来插入 - 想一劳永逸?得组合操作:先
ALTER加默认值,再UPDATE修存量,最后(可选)加NOT NULL约束










