mysql 5.7+报err 1067是因为默认启用no_zero_date和no_zero_in_date模式,禁止'0000-00-00'类零日期作为默认值;临时方案为会话级修改sql_mode,永久修复需修改配置文件并重启服务,或改用合法默认值如'1000-01-01'、current_timestamp。

为什么MySQL 5.7+建表时date/datetime默认值报Err 1067
根本不是语法写错,而是 MySQL 5.7 默认启用了 NO_ZERO_DATE 和 NO_ZERO_IN_DATE 模式。这两个选项直接禁止 '0000-00-00'(DATE)和 '0000-00-00 00:00:00'(DATETIME/TIMESTAMP)作为合法默认值——哪怕字段允许 NULL 或是旧脚本里沿用多年的写法,都会触发 Invalid default value for 'xxx' 错误。
临时绕过:会话级修改sql_mode(仅限调试)
适合 Navicat 手动执行、命令行快速验证,但不适用于自动化脚本或应用连接:
-
SET SESSION sql_mode = REPLACE(@@sql_mode, 'NO_ZERO_DATE,NO_ZERO_IN_DATE', '');—— 注意逗号和空格必须严格匹配当前值,否则替换失败 - 该设置只对当前连接生效;PHP/Java 应用新建连接不会继承,Navicat 导入 SQL 文件也通常不复用该会话
- 不能解决
CURRENT_TIMESTAMP在DATETIME上报错的问题:5.7 要求显式声明DEFAULT CURRENT_TIMESTAMP,且不能与NOT NULL DEFAULT '0000-00-00 00:00:00'并存
永久修复:改配置文件并重启MySQL服务
这才是生产环境唯一可靠的方式,改错位置或漏重启都会白忙:
- Linux:编辑
/etc/my.cnf或/etc/mysql/my.cnf,在[mysqld]段下添加:sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" - Windows:修改
my.ini的[mysqld]段,同上一行配置 - macOS:若无
/etc/my.cnf,从/usr/local/mysql/support-files/my-default.cnf复制一份并重命名,再修改 - 改完必须重启服务:
sudo systemctl restart mysql(Linux)、服务管理器(Win/mac),仅 reload 不生效
更安全的替代方案:不用零日期,改用合法默认值
不碰 sql_mode 更稳妥,尤其当团队已有严格模式依赖其他功能时:
- DATE 字段用
DEFAULT '1000-01-01'或业务可接受的兜底日期(如'2000-01-01') - DATETIME/TIMESTAMP 字段优先用
DEFAULT CURRENT_TIMESTAMP,但注意:DATETIME类型从 5.6.5 起才支持该语法,且必须显式写出,不能省略DEFAULT - 避免
NOT NULL DEFAULT '0000-00-00'这类组合——它在 5.7+ 下永远失败,无论sql_mode如何设置
NOT NULL 和零日期、或者以为 SET GLOBAL 能一劳永逸——这些是线上恢复中最常卡住的三个点。











