mysql错误1067是sql层面报错,主因是not NULL的datetime/timestamp字段设default null或使用’0000-00-00’等零日期;5.7+默认严格模式(strict_trans_tables)加强校验,需改默认值为current_timestamp或调整sql mode。

MySQL错误1067:Invalid default value for ‘xxx’
这个错误不是服务启动失败的系统级报错(那是windows服务1067),而是执行 CREATE TABLE 或 ALTER TABLE 时触发的SQL层面报错,核心原因是字段默认值不合法——最常见的是给 NOT NULL 的 DATETIME 或 TIMESTAMP 字段设了 DEFAULT NULL,或者用了已废弃的零日期(如 '0000-00-00')。
为什么严格模式下会报1067,而旧版本不报?
MySQL 5.7+ 默认启用严格SQL模式(STRICT_TRANS_TABLES),此时对默认值校验变严。关键点:
-
TIMESTAMP字段若声明NOT NULL,却指定DEFAULT NULL→ 直接报1067 -
DATETIME在 5.7.5+ 不再隐式接受'0000-00-00'作为默认值,除非显式关闭NO_ZERO_DATE - 即使字段允许 NULL,
DEFAULT '0000-00-00 00:00:00'也会被拒绝(除非 SQL mode 中移除了NO_ZERO_DATE)
快速修复:改默认值 or 调整SQL mode
优先推荐改表结构,避免依赖宽松模式:
- 把
DEFAULT NULL改成有效时间,例如:DEFAULT CURRENT_TIMESTAMP(TIMESTAMP/5.6.5+DATETIME支持) - 把
NOT NULL去掉,如果业务允许该字段为空 - 用
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP替代固定零值 - 临时绕过(不推荐生产):启动时加参数
--sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"并去掉NO_ZERO_DATE,但会掩盖数据质量问题
检查当前SQL mode和日期行为
运行这条语句确认实际生效的模式:
SELECT @@sql_mode;
重点关注是否含 STRICT_TRANS_TABLES、NO_ZERO_DATE、NO_ZERO_IN_DATE。再查零日期是否被禁用:
SELECT @@sql_mode LIKE '%NO_ZERO_DATE%';
如果返回 1,说明零日期已被禁止——这时任何含 '0000-00-00' 的默认值都会触发1067。迁移老表时最容易漏掉这点,尤其从5.6升级到8.0后。