Navicat无“存在则更新、不存在则插入”一键开关,必须用「更新」模式并手动勾选主键或唯一索引字段为「匹配」,否则因缺失WHERE条件导致全表更新或Duplicate entry报错。

必须用「更新」模式 + 手动勾选匹配字段,Navicat 没有“存在则更新、不存在则插入”的一键开关,所谓自动更新其实是靠 MERGE(SQL Server)、INSERT ... ON DUPLICATE KEY UPDATE(MySQL)这类底层语句实现的,前提是你得告诉它“拿什么去判断存在”。
为什么选了“更新”还报 Duplicate entry?
Navicat 不会自动识别主键——它默认不生成 WHERE 条件,导致全表更新或误判所有行为“不存在”,全部走 INSERT。常见错误现象包括:
- 导入向导第 2 步(字段映射页)没点主键列右侧的「匹配」复选框(中文版),即使看起来高亮也不代表已生效
- 源数据里主键字段名是
user_id,目标表是uid,但没手动拖拽对齐,匹配失效 - 复合唯一索引(如
(tenant_id, external_id))只勾了一个字段,比对逻辑残缺
MySQL 下怎么让 INSERT 变成 UPSERT?
Navicat for MySQL 底层实际执行的是 INSERT ... ON DUPLICATE KEY UPDATE,但有硬性前提:
- 目标表必须有主键或唯一索引,否则语句直接报错
- 导入向导中操作模式必须设为
Update,不能是Insert - 「匹配」字段必须严格对应主键/唯一索引列,类型也要一致(比如
INTvsBIGINT不兼容) - 非匹配字段默认全开「更新」,若只想改部分字段(如仅同步
updated_at),需逐个关掉其他字段的更新开关
SQL Server 用户特别注意:没有 Skip 选项
「跳过重复记录」在 SQL Server 导入流程中是灰色且无效的,因为 SQL Server 没有 INSERT IGNORE 或等效语法。你必须走唯一路径:
- 操作模式强制改为
Update - 主键字段必须手动点击「匹配」,否则生成的
MERGE语句缺ON条件,变成全表覆盖 - 大数据量(>5 万行)时性能明显下降,建议拆分批次
- 若目标表有多个唯一约束(如
email和phone联合唯一),Navicat 不支持多字段匹配,得提前建视图或计算列收口
最容易被忽略的是字段值覆盖问题:比如只勾了 id 为匹配字段,但源数据中 status 列为空,Navicat 会把目标表原有值更新为 NULL。这不是 bug,是逻辑使然——它只管“按匹配字段找得到就更新”,不管你想保留哪些旧值。


















