Invalid default value for 'xxx' 错误源于MySQL 5.7+默认启用NO_ZERO_DATE和NO_ZERO_IN_DATE模式,禁止'0000-00-00'及'0000-00-00 00:00:00'作为DATETIME/DATE默认值,需改用CURRENT_TIMESTAMP()、'1000-01-01'或DEFAULT NULL。

Invalid default value for 'xxx' 错误怎么快速定位
这个报错几乎都发生在建表或 ALTER TABLE 时,核心原因是 MySQL 拒绝了你给 DATETIME 字段设置的默认值。不是语法写错,而是值本身被当前 SQL 模式判定为“非法”。最常见触发点是:DEFAULT '0000-00-00 00:00:00'、DEFAULT '0000-00-00',或者干脆没写默认值但字段又 NOT NULL。
为什么 DEFAULT CURRENT_TIMESTAMP 在 MySQL 5.6+ 还会报错
MySQL 5.6 开始支持 DATETIME 的 CURRENT_TIMESTAMP 默认值,但有两个隐藏条件:
- 必须显式带括号:
DEFAULT CURRENT_TIMESTAMP(),不带括号(CURRENT_TIMESTAMP)在某些版本(尤其是 5.7 早期或严格模式下)会被拒绝 - 如果同时定义多个
DATETIME字段都用CURRENT_TIMESTAMP(),部分旧版本会报错,尽管这在 8.0+ 已放开限制 - 字段不能是
NOT NULL且无默认值 —— 即使写了DEFAULT CURRENT_TIMESTAMP(),也要确认没漏掉NOT NULL冲突
修改 sql_mode 是最直接的解法,但要注意作用域
报错通常源于 NO_ZERO_DATE 和 NO_ZERO_IN_DATE 这两个模式项。它们禁止 '0000-00-00' 类零日期。临时解决可用:
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
但注意:SESSION 只对当前连接生效;GLOBAL 需要管理员权限,且新连接才继承。生产环境建议改配置文件(my.cnf 或 my.ini),在 [mysqld] 下加:
sql-mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
改完必须重启 MySQL 服务,否则不生效。
JDBC 应用连不上时,zeroDateTimeBehavior 很关键
即使数据库允许存 '0000-00-00 00:00:00',Java 的 mysql-connector-java 默认会抛 java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date。这不是 MySQL 报错,而是驱动层拦截。
解决方法是在 JDBC URL 里加参数:
jdbc:mysql://localhost:3306/db?zeroDateTimeBehavior=convertToNull
可选值有:exception(默认,直接炸)、round(转成 0001-01-01)、convertToNull(转成 NULL)。选哪个取决于业务能否接受空值或时间偏移。
真正麻烦的不是语法,是 sql_mode 和 JDBC 驱动这两层默认行为叠加导致的问题。改配置前先确认:你是想保留零日期语义,还是干脆换用 CURRENT_TIMESTAMP() 或 TIMESTAMP 字段 —— 后者在多数场景下更省心。


















