错误。default关键字在update中可用,但支持度因数据库而异:postgresql和sql server完全支持,mysql 8.0+支持,sqlite不支持;它会重新求值默认表达式(如now()),且仅适用于已明确定义default的列。

DEFAULT 关键字不能用于 UPDATE 语句批量重置字段值——这是 SQL 标准的硬性限制,直接写 UPDATE table SET col = DEFAULT 在绝大多数数据库(如 MySQL、PostgreSQL、SQL Server)中会报错或被忽略。
为什么 UPDATE ... SET col = DEFAULT 不工作
SQL 标准里,DEFAULT 是一个上下文关键字,只在 INSERT 语句(含 VALUES 或 DEFAULT VALUES)和列定义(CREATE TABLE)中合法。它不是表达式,不支持在 UPDATE 的 SET 子句中作为右值使用。MySQL 8.0+ 虽然文档提过实验性支持,但实际仍报 ERROR 1064;PostgreSQL 明确拒绝;SQL Server 完全不识别。
- 常见错误信息:
ERROR: syntax error at or near "DEFAULT"(PostgreSQL) - 误以为能用是因为混淆了
INSERT INTO t(col) VALUES (DEFAULT)的写法 - 即使某版本“看似成功”,也往往只是把
DEFAULT当作未定义标识符,最终设为NULL或触发隐式转换,不可靠
真正可行的批量重置方案
必须显式写出默认值,或通过查询系统表/视图动态构造。没有银弹,需按数据库类型选择:
- 如果字段有明确默认值(比如
status VARCHAR(20) DEFAULT 'active'),直接写死:UPDATE users SET status = 'active' WHERE ... - 如果默认值是函数(如
NOW()、CURRENT_TIMESTAMP),需调用对应函数:UPDATE logs SET created_at = NOW() - PostgreSQL 可查
pg_attrdef获取定义:SELECT pg_get_expr(adbin, adrelid) FROM pg_attrdef WHERE adrelid = 'mytable'::regclass AND adnum = (SELECT attnum FROM pg_attribute WHERE attname = 'col' AND attrelid = 'mytable'::regclass)
,但结果需解析,不适合简单场景 - MySQL 无等效系统视图直接取默认表达式,
INFORMATION_SCHEMA.COLUMNS的COLUMN_DEFAULT字段只存字面值,不支持函数
用 INSERT ... ON CONFLICT 或 MERGE 曲线救国(仅限特定场景)
当目标是“按主键重置某些行的字段为默认值”,且你有一份主键列表时,可绕过 UPDATE 限制:
- PostgreSQL(推荐):
INSERT INTO t(pk, col) VALUES (1, DEFAULT), (2, DEFAULT) ON CONFLICT (pk) DO UPDATE SET col = EXCLUDED.col—— 这里DEFAULT生效,因为是在INSERT的VALUES子句中 - SQL Server:
MERGE的WHEN MATCHED THEN UPDATE SET col = DEFAULT语法不合法;但可用VALUES (DEFAULT)构造源数据再 join - 这种写法本质是“用插入逻辑驱动更新”,维护成本高,仅适用于小批量、主键明确的修复任务
最稳妥的做法永远是:查表结构确认默认值 → 手动写进 UPDATE 语句。别指望 DEFAULT 在 UPDATE 中自动展开,所有试图让数据库“猜你想设什么”的操作,最后都得回过头来验证结果是否真符合定义。











