Navicat定时任务不支持“忽略重复项”,因其后台批处理不加载UI配置,固定执行裸INSERT或TRUNCATE+全量插入,无法触发INSERT IGNORE;必须改用LOAD DATA INFILE配合ON DUPLICATE KEY UPDATE等数据库原生命令实现可控去重。
Navicat定时任务不走“忽略重复项”逻辑
定时任务根本不会读取你在手动导入时勾选的「忽略重复项」选项——这个开关只在图形向导的字段映射页生效,而定时任务运行的是后台批处理脚本,压根不加载 ui 层的任何配置。它既不生成 insert ignore,也不检查主键/唯一索引冲突,而是直接执行裸 insert。结果就是:哪怕目标表已有唯一约束,重复数据照样报错中断,或(更危险地)在部分失败后静默跳过后续行,导致你以为成功、实际漏数。
“追加模式”在定时任务里形同虚设
你在手动导入时选「追加」+「忽略重复项」才触发去重,但定时任务创建时,“导入模式”下拉菜单里根本没有「追加」这个选项——它默认固定为「清空后导入」或「替换」,具体取决于你保存任务时的快照状态。即使你改过一次,下次编辑任务再点「确定」,Navicat 会悄悄还原成初始模式,且不提示。这意味着:
- 定时任务实际执行的是
TRUNCATE TABLE+ 全量插入,完全无视已有数据 - 若源 CSV 本身含重复行,它们会在单次导入中被原样插入多次
- 没有事务回滚保护,中途失败可能导致表处于半清空状态
替代方案必须绕开 Navicat 定时导入
真要稳定去重,得把逻辑下沉到数据库侧,用可控 SQL 替代图形界面:
用 LOAD DATA INFILE + ON DUPLICATE KEY UPDATE(MySQL)或 MERGE INTO(Oracle)显式定义冲突策略。例如:
LOAD DATA INFILE '/data/orders.csv'
INTO TABLE orders
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(@id, @name, @amount)
SET id = @id,
name = @name,
amount = @amount,
updated_at = NOW()
ON DUPLICATE KEY UPDATE amount = VALUES(amount), updated_at = NOW();
注意:ON DUPLICATE KEY UPDATE 要求目标表存在 PRIMARY KEY 或 UNIQUE 索引;VALUES() 引用的是本次 INSERT 中的原始值,不是当前行旧值。
最容易被忽略的陷阱:CSV 文件自身带重复
很多人以为“去重”是数据库的事,却没检查源文件。Excel 另存为 CSV 时可能保留隐藏筛选行、合并单元格残留、或自动补全空行;用脚本拼接多个 CSV 时未去重就直接合并。这些重复在 Navicat 手动导入时可能因人工校验被发现,但定时任务无人值守,只会忠实地把每行都插一遍。务必在调度前用 sort -u(Linux)或 Get-Unique(PowerShell)预处理源文件,或在 SQL 中加 GROUP BY 子查询做中间清洗。











