是。显式写null会绕过默认值,数据库将null作为实际值插入,完全忽略default定义;仅当字段未出现在insert列列表中时,才触发默认值填充。

INSERT INTO 时显式写 NULL 会绕过默认值吗?
会。只要在 INSERT 语句的列列表中包含该字段,并显式赋予 NULL,数据库就会把 NULL 当作实际值插入,完全忽略字段定义里的 DEFAULT(哪怕这个默认值是 0、'' 或 CURRENT_TIMESTAMP)。
- 这是 SQL 标准行为,MySQL、PostgreSQL、SQL Server 都一致
- 常见误判:以为 “带默认值 = 插入时自动填默认值”,其实只在「该字段未出现在 INSERT 列表中」时才触发默认值
- 如果表结构是
status VARCHAR(10) DEFAULT 'active',执行INSERT INTO t (id, status) VALUES (1, NULL),结果就是status为NULL,不是'active'
批量插入时怎么让部分行写 NULL、部分行用默认值?
必须拆开处理:想用默认值的行,不写该字段名;想写 NULL 的行,显式列出字段并赋 NULL。不能靠一条统一语句自动判断。
- 错误写法:
INSERT INTO t (id, status) VALUES (1, DEFAULT), (2, NULL)——DEFAULT关键字在 VALUES 里多数数据库不支持(PostgreSQL 支持,但 MySQL 不支持) - 正确做法是分两批:
INSERT INTO t (id) VALUES (1); -- status 自动取 DEFAULT
INSERT INTO t (id, status) VALUES (2, NULL); -- status 显式为 NULL
- 或者用
INSERT ... SELECT+CASE构造动态值(适合复杂逻辑),但要注意NULL和默认值不能混在同一列的 VALUES 列表里
用 LOAD DATA INFILE 或 COPY 批量导入时如何控制 NULL / DEFAULT?
这类命令不走常规 INSERT 语法,需靠字段映射和空值规则控制:
- MySQL 的
LOAD DATA INFILE:默认把空字符串或 \N 当作NULL,但前提是字段允许NULL;如果字段是NOT NULL DEFAULT 'x',\N 会报错,不会退化为默认值 - PostgreSQL 的
COPY:用NULL AS '\N'指定空值标记,同样不触发默认值,除非对应列在COPY的列列表中被跳过 - 安全做法:导入前清理数据,确保需要默认值的行在 CSV 中直接省略该列(列数减少),而不是填空或 \N
UPDATE 也能“批量插 NULL”,但和 INSERT 逻辑不同
UPDATE 没有默认值机制,所有赋值都直接生效。所以 UPDATE t SET status = NULL WHERE id IN (1,2,3) 就是明确把这三行的 status 设为 NULL,和字段有没有 DEFAULT 无关。
- 注意:如果字段是
NOT NULL,这条语句会失败,报错类似Column 'status' cannot be null - 和
INSERT的关键区别在于:UPDATE 总是覆盖,INSERT 的默认值只在“字段未出现”时兜底
字段是否允许 NULL、是否定义了 DEFAULT、你在语句里是否显式提到了它——这三个条件共同决定最终写入什么值,少一个都可能出人意料。











