必须勾选“比对存储过程”选项,Navicat才对比存储过程;默认不启用,同名过程逻辑不同也不会显示差异,需手动勾选并检查DEFINER、SQL SECURITY及兼容性。
结构同步必须勾选“比对存储过程”才生效
navicat 默认不对比存储过程,哪怕两个库同名过程逻辑不同,结构同步窗口也不会显示任何差异。这不是漏报,是功能默认关闭。
常见错误现象:你明明改了 sp_update_user 的参数,但结构同步结果里没出现“修改”标记,直接点“部署”也没生成 ALTER PROCEDURE 语句。
- 进入“工具 → 结构同步”后,在“比对选项”页,必须手动勾选
比对存储过程(MySQL/PostgreSQL/SQL Server 均支持) - Oracle 用户注意:对应选项叫
比对函数和比对过程,需分别勾选 - 勾选后,Navicat 才会读取
ROUTINE_DEFINITION字段做文本级比对——它不解析 SQL 逻辑,只比源码字符串是否一致 - 若过程含注释、空格、换行差异,也会被标为“修改”,这不是 bug,是设计如此
存储过程名相同但定义不同,Navicat 会标为“修改”而非“创建+删除”
和表、索引不同,Navicat 对存储过程采用“存在性 + 定义一致性”双判断:只要名字一样,就走 ALTER 路径;名字不同才走 CREATE/ DROP。
容易踩的坑:你把 sp_calc_total 重命名为 sp_calculate_total,旧过程还在目标库,新过程在源库——结构同步会同时标出“删除旧过程”和“创建新过程”,而不是“重命名”。它不识别语义等价性。
- 确认过程名是否完全一致(含大小写,尤其在 Linux MySQL 上区分大小写)
- 检查
DEFINER是否相同:比如DEFINER=`root`@`localhost`vsDEFINER=`admin`@`%`,会被当作定义不同 - MySQL 8.0+ 的
SQL SECURITY(DEFINER / INVOKER)不同也会触发“修改”标记 - 过程体开头的
DELIMITER不参与比对,但实际创建时若缺失或错位,会导致部署失败
DDL 比较面板里才能看清真实差异点
结构同步列表只告诉你“sp_sync_data 将被修改”,但不会告诉你哪一行变了。真正定位问题,得点开右侧 DDL 比较面板。
常见差异类型:
-
INOUT参数改成IN或反之,会被高亮显示 - 新增
DECLARE CONTINUE HANDLER块,整块内容会标黄 - MySQL 中
SELECT ... INTO和SET var = (SELECT ...)逻辑等价,但 Navicat 视为不同 - 过程末尾多一个分号
;或少一个,也会被识别为差异(尤其跨平台迁移时)
注意:DDL 面板里显示的是 Navicat 解析后的标准化 SQL,不是原始 CREATE 语句。比如它会把 CREATE PROCEDURE 统一转成大写,去掉多余空格——所以别拿这个输出去 diff 原始脚本。
跨库同步前务必检查兼容性限制
Navicat 生成的同步脚本不校验目标库是否支持该语法,尤其对存储过程这种强依赖版本特性的对象。
典型风险场景:
- MySQL 5.7 源库用了
JSON_CONTAINS(),目标库是 5.6 —— 同步脚本仍会生成,执行时报错FUNCTION JSON_CONTAINS does not exist - SQL Server 源库过程含
THROW,目标库是 2008R2(不支持)—— 脚本照常生成,运行失败 - PostgreSQL 源库用
LANGUAGE plpgsql,目标库未安装 plpgsql 扩展 —— 部署卡在 CREATE FUNCTION - Oracle 过程含
PRAGMA AUTONOMOUS_TRANSACTION,但目标用户权限不足 —— 不报语法错,报权限错
最稳妥的做法:先在目标库手动执行 SHOW CREATE PROCEDURE `xxx`(MySQL)或查询 ALL_SOURCE(Oracle),确认基础语法能跑通,再让 Navicat 生成变更脚本。











