Navicat“转储SQL文件”不可靠,因跳过WITH ENCRYPTION、参数默认值、EXECUTE AS、依赖对象及GO分隔符;应使用“对象信息→DDL”手动提取并检查完整性。

不能只靠右键“导出”或“转储SQL文件”——存储过程必须单独提取,否则容易漏掉依赖对象、参数默认值或加密状态。
为什么“转储SQL文件”对存储过程不可靠
Navicat 的「转储SQL文件」功能默认聚焦表结构和数据,对存储过程的处理极简:它只导出 CREATE PROCEDURE 语句,但会跳过以下关键内容:
• WITH ENCRYPTION 状态(加密过程导出后变成明文,且无法还原加密属性)
• 参数默认值(如 @p INT = 1 可能被简化为 @p INT)
• EXECUTE AS 执行上下文
• 依赖的用户自定义类型、函数或视图(不自动前置生成)
• 多语句批处理中的 GO 分隔逻辑(Navicat 导出脚本不保留 GO,导致重建失败)
正确做法:用“对象信息”+手动补全
这是目前最稳定、细节可控的方式:
• 在连接树中展开目标数据库 →「可编程性」→「存储过程」→ 右键目标过程 → 选择「对象信息」
• 切换到「DDL」标签页,全选并复制全部内容
• 粘贴后检查三处:
- 是否含 IF EXISTS ... DROP PROCEDURE(若需幂等部署,建议手动加上)
- 参数列表是否完整保留默认值和数据类型精度(如 DATETIME2(3))
- 若过程含 WITH ENCRYPTION,复制的内容已是解密后的明文——你无法通过 Navicat 导出“加密态脚本”,只能在目标库上重建后手动执行 ALTER PROCEDURE ... WITH ENCRYPTION
导出多个存储过程时的顺序与依赖问题
Navicat 不保证导出顺序,也不解析依赖。若过程 A 调用过程 B,而你先导入 A 再导入 B,会报错 Could not find stored procedure 'B':
• 不要用「转储SQL文件」批量导出所有过程——它按字母序拼接,毫无逻辑
• 正确路径是:
- 单独导出每个过程的 DDL,命名带序号(如 01_proc_B.sql、02_proc_A.sql)
- 合并前用文本工具全局搜索 EXEC 或 sp_executesql,人工梳理调用链
- 合并时确保被依赖过程在前,主过程在后,并在每段 DDL 前加 GO
• 注意:Navicat 的「运行SQL文件」不识别 GO,必须用 sqlcmd 或 SSMS 执行合并后的脚本
加密存储过程无法“原样导出”是硬限制
SQL Server 层面禁止读取加密过程的实际定义(即使 sysadmin 权限也仅能拿到占位符)。Navicat 调用的是 OBJECT_DEFINITION() 函数,该函数对加密对象返回 NULL ——所以你看到的“导出成功”,其实只是空脚本或错误提示。此时唯一可行动作是:
• 在源库用 sys.dm_exec_describe_first_result_set 获取参数元数据(仅结构,无逻辑)
• 或联系 DBA 提供原始创建脚本(如有存档)
• 切勿尝试用第三方解密工具,既违法又破坏审计合规性











