MySQL 5.7+默认拒绝'0000-00-00 00:00:00',因严格模式启用NO_ZERO_DATE和NO_ZERO_IN_DATE校验,该值违反格里高利历且被SQL模式主动拦截;解决需移除这两项并持久化至配置文件。

为什么0000-00-00 00:00:00会被拒绝
MySQL 5.7+ 默认启用严格模式,其中 NO_ZERO_DATE 和 NO_ZERO_IN_DATE 会直接拒绝 '0000-00-00' 这类“伪日期”。哪怕字段类型是 DATETIME,只要值含全零年月日或零时分秒(如 '0000-00-00 24:00:00'),就会触发 ERROR 1292。这不是格式问题,是 SQL 模式主动拦截。
临时生效:用 SET 修改当前会话或全局 sql_mode
执行以下命令可立即绕过校验(重启后失效):
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
或影响所有新连接:
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
-
NO_ZERO_DATE和NO_ZERO_IN_DATE必须从原值中彻底移除,不能只覆盖部分 - 执行前先查当前值:
SELECT @@sql_mode;或SELECT @@global.sql_mode; - 如果权限不足,
GLOBAL级修改会报错,此时只能改SESSION级
永久生效:在 my.ini 或 my.cnf 中配置
仅靠 SET 不够,MySQL 重启后恢复默认模式。必须编辑配置文件:
在 [mysqld] 段落下添加:
sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
- Windows 下通常是
C:\ProgramData\MySQL\MySQL Server X.X\my.ini - Linux 下常见路径为
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf - 改完必须重启 MySQL 服务:
net stop MySQL+net start MySQL(Windows)或systemctl restart mysqld(Linux) - 注意不要遗漏
STRICT_TRANS_TABLES—— 它保障事务表的基本完整性,去掉可能引发其他隐性问题
ALLOW_INVALID_DATES 能不能用
这个模式只对 DATETIME 有效,对 TIMESTAMP 列完全无效。比如插入 '2023-02-30 00:00:00' 可能通过,但 '0000-00-00 00:00:00' 仍被 NO_ZERO_DATE 拦截。它不是零日期的解法,而是放宽非法日(如 2 月 30 日)的校验,实际生产环境慎用。
真正要兼容历史数据里的零日期,核心就是干掉 NO_ZERO_DATE 和 NO_ZERO_IN_DATE,且必须落到配置文件里——临时 SET 只能救急,漏掉持久化配置,下次重启就回归报错。


















