Navicat 16 不处理 Git 分支合并冲突,执行合并后的 SQL 文件失败主因是语义冲突:重复建表、列名冲突、BOM 导致卡死、USE 多次切换库错位;须在 Git 阶段预筛 DDL 差异,合并时删冗余 USE、统一分隔符、加 IF NOT EXISTS,执行时取消“遇错停止”并勾选“先 USE”。

Navicat 16 本身不参与 Git 分支合并,也不会解析或处理 Git 冲突 —— 所谓“Navicat 解决 DDL 冲突”是常见误解。真正要处理的,是 Git 合并后生成的 SQL 文件(如 schema.sql 或 init.sql)在 Navicat 中执行时报错的问题。
为什么 Navicat 执行合并后的 SQL 文件会失败?
Git 合并冲突解决后,开发者常手动拼接多个分支的 DDL 脚本(比如 A 分支建了 users_v2 表,B 分支改了 users 表结构),但没清理冗余或校准语义,导致 Navicat 执行时直接报错:
-
ERROR 1050 (42S01): Table 'users' already exists—— 两个分支都含CREATE TABLE users -
ERROR 1060 (42S21): Duplicate column name 'status'—— 同一表被两次ADD COLUMN - 无报错卡死 —— 混入带 BOM 的 UTF-8 文件,Navicat 解析阻塞
-
Unknown database 'xxx'—— 合并时保留了多个USE db1;、USE db2;,后续语句执行库错位
合并前:用 Git 工具预筛 DDL 冲突点
别等合并完再打开 Navicat —— 在 Git 阶段就要识别高危 DDL 变更:
- 对
*.sql文件启用git diff --no-index对比分支间建表/改表语句差异 - 用
grep -n "CREATE TABLE\|ALTER TABLE\|DROP TABLE" *.sql快速定位各脚本中 DDL 密集区 - 检查
IF NOT EXISTS是否统一:A 分支用CREATE TABLE IF NOT EXISTS,B 分支直写CREATE TABLE→ 合并后可能因顺序错乱触发重复建表 - 确认所有脚本开头的字符集声明一致:
SET NAMES utf8mb4;(不是utf8)且只出现一次
合并中:删 USE、统一分隔符、加条件判断
手动合并 SQL 文件时,必须做三件事,否则 Navicat 执行必崩:
- 只保留第一个
USE database_name;,删掉后续所有同名USE;跨库操作改用全限定名,如INSERT INTO db2.logs SELECT * FROM db1.events; - 所有存储过程/函数定义前,统一声明
DELIMITER $$,结尾用$$,避免 Navicat 把过程体误切为多条语句 - 对可能重复的 DDL 加保护:把
CREATE TABLE users改成CREATE TABLE IF NOT EXISTS users,把ADD COLUMN x INT改成ALTER TABLE users ADD COLUMN IF NOT EXISTS x INT(MySQL 8.0.19+ 支持)
执行时:Navicat 设置必须调,否则白忙活
即使 SQL 文件已干净,Navicat 默认配置仍会中断执行:
- 在「运行 SQL 文件」对话框中,取消勾选「停止执行遇到错误时」 —— 否则一条
Duplicate column就停住,后面几十个INSERT全不跑 - 务必勾选「执行每个语句前先执行 USE 语句」 —— 让 Navicat 自动补上缺失的库上下文,防止跨库对象找不到
- 若文件含大量
INSERT IGNORE或REPLACE INTO,检查是否漏替换成INSERT ... ON DUPLICATE KEY UPDATE,否则主键冲突时静默跳过,业务数据就丢了 - 大文件(>20MB)提前在 Navicat「选项 → 环境 → SQL 执行超时时间」设为
600秒以上,避免超时中断
真正难的不是语法层面的冲突,而是语义层面的覆盖:比如 A 分支把 email VARCHAR(100) 改成 VARCHAR(255),B 分支在同一列上加了 NOT NULL,合并后你只留了长度没留约束,上线就炸。每次合并完,用文本工具扫一眼 CREATE TABLE 和 ALTER TABLE 的分布密度,比什么都管用。


















