SQL Server 存储过程导出需勾选“Include IF NOT EXISTS”“Script permissions”“Script extended properties”;MySQL 需处理 DELIMITER、DEFINER 及 SQL SECURITY;PostgreSQL 须合并 pg_dump 主体与 GRANT 语句。

SQL Server 存储过程怎么导出成可执行脚本
直接用 sqlcmd 或 SSMS 生成的脚本常漏掉权限、依赖对象或 SET 选项,导致恢复后执行报错。关键不是“能不能导”,而是“导出来的脚本能原样跑起来”。
-
sqlcmd -S server -d db -Q "EXEC sp_helptext 'proc_name'" -o proc.sql只导定义,不带创建语句头和结尾分号,粘贴进新库会语法错误 - SSMS 的“生成脚本”向导里必须手动勾选:
Types of data to script设为Schema only,Script DROP and CREATE设为Script DROP and CREATE,否则可能生成DROP但没CREATE - 真正稳妥的做法是用
sys.dm_exec_describe_first_result_set配合OBJECT_DEFINITION拼接——但日常迁移用 SSMS 更快,前提是把这三项设对:Include IF NOT EXISTS、Script permissions、Script extended properties
MySQL 存储过程导出后在新实例执行失败的常见原因
MySQL 的存储过程不像函数能直接 SHOW CREATE PROCEDURE 一气呵成,DELIMITER 切换和 DEFINER 权限是两个高频断点。
-
SHOW CREATE PROCEDURE proc_name输出里带DEFINER=`user`@`host`,目标库没这个用户?执行直接报ERROR 1449 (HY000): The user specified as a definer does not exist - 导出脚本开头没写
DELIMITER $$,中间又出现分号(比如SELECT …… ;),MySQL 会把过程体截断,只建个空壳 - 如果源库是 MySQL 5.7,目标库是 8.0,注意
SQL SECURITY默认值变了,显式写上SQL SECURITY DEFINER或SQL SECURITY INVOKER更稳
跨数据库迁移时,存储过程里的表名 / 库名硬编码怎么处理
直接搜替换 old_db.table_name → new_db.table_name 很危险:可能误改注释、字符串字面量,或漏掉三段式引用(如 [old_db].[schema].[table])。
- 先用正则找真实引用:
b(old_db).(dbo|public).w+(SQL Server)或`old_db`.w+(MySQL),比全文替换准得多 - 如果过程里大量用
EXEC('……')或CONCAT('SELECT * FROM', @db_name, '.t'),这种动态拼库名的逻辑无法靠脚本自动迁移,必须人工核对执行上下文 - 更可持续的做法是:迁移前把所有库名抽象成变量或配置表,过程里用
(SELECT db_name FROM config WHERE key = 'target_db')替代硬编码——虽然改代码多花半小时,但下次迁移省半天
PostgreSQL 函数 / 过程导出后权限丢失怎么办
pg_dump 默认不导函数权限,pg_dump -s 只导结构,pg_dump -O 虽去掉 owner 但不补 GRANT,结果就是函数存在,但普通用户调用报 permission denied for function xxx。
- 必须加
--no-owner --no-privileges导出主体,再单独用pg_dump -s --section=pre-data提取GRANT语句,合并到主脚本末尾 - 如果目标库角色名和源库不一致(比如源用
app_user,目标叫webapp),别硬改 dump 文件,用psql -c "GRANT EXECUTE ON FUNCTION func_name TO webapp;"补授权更可控 - 注意 PostgreSQL 14+ 的
PROCEDURE和旧版FUNCTION权限模型不同,CALL语句需要EXECUTE权限,但过程本身还受USAGEon schema 约束——少一层都会静默失败
最麻烦的从来不是导出命令敲不对,而是过程里嵌了 OPENROWSET、SELECT …… INTO OUTFILE 或 pg_notify 这类强依赖环境的调用。这类逻辑没法靠脚本自动适配,得一行行看它到底在和谁通信、往哪写文件、权限卡在哪一级——迁移前先 grep 这几个关键词,比事后 debug 快十倍。