Navicat 17 同步虚拟列时会丢定义或报错,因其对 GENERATED COLUMN 支持不完整:常忽略该列、误判 STORED 列为普通列、漏生成 AS (...) STORED/VIRTUAL 子句;需关闭“Compare generated columns”和“Include column comments”选项,并建议用 SHOW CREATE TABLE 手动补全 DDL。
Navicat 17 同步虚拟列时为什么会丢定义或报错
navicat 17 对 generated column(虚拟列)的支持仍不完整:它可能完全忽略该列,也可能把 stored 列误判为普通列,更常见的是在生成 ddl 时漏掉 as (...) stored/virtual 子句,导致目标表缺失计算逻辑。mysql 5.7+ 才真正支持虚拟列,而 navicat 默认导出行为仍按老版本兼容逻辑走,不会主动识别和保留 generated always as 表达式。
必须关掉的两个同步选项
在结构同步向导的「Options」→「Advanced」里,以下两项必须取消勾选:
-
Compare generated columns:勾选后 Navicat 会尝试比对,但实际生成的 ALTER 语句常语法错误(如漏括号、双引号包裹表达式);关掉它,至少避免生成非法 SQL -
Include column comments:虚拟列若带 COMMENT,Navicat 易将其与生成表达式混在一起解析,引发ERROR 3819;即使你没写注释,也建议关掉以防意外注入
替代方案:用 SHOW CREATE TABLE 手动补全虚拟列
Navicat 同步后,目标表结构里虚拟列大概率只剩一个空字段(类型对但无 AS 定义)。此时别重跑同步,直接手动修复:
- 在源库执行
SHOW CREATE TABLE `order_summary`;,复制整段输出 - 找到类似
total_amount decimal(10,2) GENERATED ALWAYS AS (price * qty) STORED COMMENT '总价'的行 - 在目标库执行
ALTER TABLE `order_summary` DROP COLUMN total_amount;(先删空列) - 再执行
ALTER TABLE `order_summary` ADD COLUMN total_amount decimal(10,2) GENERATED ALWAYS AS (price * qty) STORED;
注意:若虚拟列表达式含函数(如 JSON_EXTRACT)、子查询或跨表引用,Navicat 基本无法同步——这类列必须全程手工维护 DDL。
为什么不能依赖“预览 SQL”检查虚拟列
Navicat 17 的「Preview SQL」界面在涉及虚拟列时存在显示缺陷:它可能把 ADD COLUMN 语句渲染成普通字段,不标出 GENERATED 关键字,甚至把整个 AS 表达式截断在省略号里。你看到的“干净”脚本,实际执行时大概率失败。最可靠的方式是导出 SQL 文件后,用文本编辑器搜索 GENERATED 或列名,确认表达式是否完整出现。











