navicat导入sql遇duplicate entry报错,因默认不跳过主键/唯一键冲突;“出错后继续”仅对解析错误有效,对error 1062无效;推荐改insert into为insert ignore或on duplicate key update,并注意外键检查与数据质量。

Navicat 导入 SQL 脚本时提示 Duplicate entry,说明脚本里有重复主键或唯一键的 INSERT INTO 语句,而 Navicat 默认不跳过、不覆盖、不询问——它直接报错中断。想快速跳过,不能靠“出错继续”这种模糊选项,得明确控制插入行为。
为什么“出错后继续”不管用
这个选项只在「导入向导」第 2 步「运行查询」页存在,且仅对解析错误(比如字段名不存在、类型不匹配)生效;对 ERROR 1062: Duplicate entry 完全无效。数据同步(Data Sync)界面压根没有该开关,所谓“高级设置里勾选”是常见误传。
- 它不改变 SQL 语义,只是让 Navicat 忽略某些语法级 warning
- 遇到主键冲突时仍会抛出 ERROR 并终止执行
- 即使勾选了,日志里也不会告诉你哪几条被跳过,无法审计
真正有效的跳过方式:改 INSERT 为 INSERT IGNORE
这是最直接、可控、可追溯的做法。Navicat 不提供一键替换,但导出 SQL 后手动处理两分钟就能搞定:
- 在还原/同步向导最后一步,勾选「保存为 SQL 文件」而非直接执行
- 用文本编辑器打开生成的
.sql文件,全局搜索INSERT INTO `(注意反引号) - 全部替换成
INSERT IGNORE INTO `(保留反引号和空格) - 导入前在目标库执行
SET FOREIGN_KEY_CHECKS = 0;,导入完再执行SET FOREIGN_KEY_CHECKS = 1;
注意:INSERT IGNORE 会静默跳过所有违反 PRIMARY KEY 或 UNIQUE 约束的行,但也会掩盖其他问题(如字段截断、字符集不兼容),仅建议用于已知数据质量干净的场景。
如果需要以新数据为准,用 ON DUPLICATE KEY UPDATE
当你要保留旧记录主键,但更新部分字段(比如状态、时间戳),INSERT IGNORE 就不够用了。必须手动改写成 ON DUPLICATE KEY UPDATE:
- 例如原语句:
INSERT INTO users (id, name, updated_at) VALUES (105, 'Alice', '2026-09-07'); - 改为:
INSERT INTO users (id, name, updated_at) VALUES (105, 'Alice', '2026-09-09') ON DUPLICATE KEY UPDATE name = VALUES(name), updated_at = VALUES(updated_at); - 复合唯一索引需确保所有字段都参与匹配,否则 UPDATE 不会触发
- 别用
REPLACE INTO:它本质是 DELETE + INSERT,会重置自增 ID、触发外键级联删除、清空ON UPDATE CURRENT_TIMESTAMP字段
容易被忽略的关键点
很多问题不是出在“怎么跳过”,而是出在“为什么会有重复”:
- 检查导出脚本是否含
AUTO_INCREMENT = N—— 若 N 小于目标表当前最大主键,下一条插入必冲突 - 确认目标表是否真有主键或唯一索引;没有约束,
INSERT IGNORE就不会生效 - SQL 文件若含
CREATE TABLE,Navicat 会先建表再插数据,此时“忽略重复项”开关根本不可用 - Mac 连 MySQL 8.0+ 时,若认证插件是
caching_sha2_password,Skip duplicate key errors选项可能失效











