ERROR 1067报错源于目标库启用NO_ZERO_DATE等严格模式而源SQL含非法默认值,应先查SELECT @@sql_mode,再用SET SESSION临时移除问题项或修改my.cnf永久剔除NO_ZERO_DATE/NO_ZERO_IN_DATE并重启。
还原报 ERROR 1067:Invalid default value 怎么办
这是 mysql 严格模式(strict_trans_tables、no_zero_date、no_zero_in_date)和目标库实际 sql_mode 不一致的典型表现。比如源库允许 default '0000-00-00',而目标库启用了 no_zero_date,就会在 create table 阶段直接中断。
- 先查目标库当前值:
SELECT @@sql_mode;,重点看是否含NO_ZERO_DATE或NO_ZERO_IN_DATE - 临时解决(仅本次连接有效):
SET SESSION sql_mode = (SELECT REPLACE(@@session.sql_mode, 'NO_ZERO_IN_DATE,NO_ZERO_DATE', '')); - 永久生效需改配置文件(如
/etc/my.cnf的[mysqld]段),删掉那两个项,保留STRICT_TRANS_TABLES等其他安全项,然后重启 MySQL - Navicat 连接属性 → 「高级」页必须取消勾选「使用 MySQL 兼容模式」,否则它会偷偷加回
NO_ZERO_DATE
还原报 ERROR 1055:Expression #1 of SELECT list is not in GROUP BY clause
本质是目标库启用了 ONLY_FULL_GROUP_BY,但 SQL 文件里有不合规的 GROUP BY 语句(比如 SELECT id, name FROM t GROUP BY status)。这不是 Navicat 的问题,是 MySQL 5.7+ 默认行为。
- 临时禁用(慎用于生产):
SET SESSION sql_mode = (SELECT REPLACE(@@session.sql_mode, 'ONLY_FULL_GROUP_BY', '')); - 更推荐修 SQL:把 SELECT 字段和 GROUP BY 字段对齐,或改用聚合函数包裹非分组字段,例如
SELECT MAX(id), name FROM t GROUP BY name - 导出端就规避:Navicat 导出时在「高级」选项里勾选「兼容 MySQL 5.7」,它会自动绕开高版本语法
Navicat 自己加的 sql_mode 覆盖了你的设置
即使你改了全局 sql_mode 或执行了 SET SESSION,Navicat 在新建连接或开启新线程(如勾选了「在单独的线程中运行」)时,仍可能按自己的规则重置会话级模式。
- 检查 Navicat 连接属性 → 「高级」页:确认「初始化命令」框里没写死
SET sql_mode = ...类语句 - 还原大文件时别用「查询」窗口执行,改用右键连接 → 「运行 SQL 文件」,它更稳定且较少触发线程隔离问题
- 如果必须用「还原」功能,确保没勾选「在单独的线程中运行」——否则会话级设置不继承,只能靠配置文件方式
为什么 SET PERSIST 不总管用
MySQL 8.0.11+ 支持 SET PERSIST sql_mode = '...' 持久化变量,但前提是该变量被标记为可持久化。不是所有安装都默认开启此能力。
- 先查:
SHOW VARIABLES LIKE 'persisted_globals_load';,若值为OFF,说明持久化机制未启用,SET PERSIST会静默失败 - 启用需在配置文件加
persisted_globals_load = ON并重启,再执行SET PERSIST - 更稳妥的路径仍是改
my.cnf+ 重启,尤其在 Docker 或云数据库等受限环境里,SET PERSIST常被禁用
sql_mode 的实际生效链路完全不同。最容易被忽略的是「线程隔离」和「初始化命令」这两处隐式覆盖。











