Sql server 将多个存储过程复制到其他数据库

Sql server 将多个存储过程复制到其他数据库,sql-server,loops,stored-procedures,Sql Server,Loops,Stored Procedures,在下面的场景中,我试图将数百个过程导入到其他数据库中 解决方案:SQL Server 来源 服务器:A 数据库:苹果 程序:SP1,SP2,SP3。。。SP100 目的地 服务器:B 数据库:橙色 我做的第一件事是在与两个数据库进行比较时只找到不存在的过程 为此,我使用了每个数据库中的信息和SCHEMA.ROUTINES,并在Excel中进行了比较 在找到要导入的过程列表后,我希望一次导入所有过程 然而,若我在一行文本中创建过程,它将保存一行,该行的可见性为零 因此,我使用sp_helptext

在下面的场景中,我试图将数百个过程导入到其他数据库中

解决方案:SQL Server

来源

服务器:A 数据库:苹果 程序:SP1,SP2,SP3。。。SP100 目的地

服务器:B 数据库:橙色 我做的第一件事是在与两个数据库进行比较时只找到不存在的过程

为此,我使用了每个数据库中的信息和SCHEMA.ROUTINES,并在Excel中进行了比较

在找到要导入的过程列表后,我希望一次导入所有过程

然而,若我在一行文本中创建过程,它将保存一行,该行的可见性为零

因此,我使用sp_helptext逐行复制每个文件。然后,创建如下的小查询:

create table #proceduretext (runquery varchar(max))
insert into #proceduretext
exec sp_helptext 'SP1'
insert into #proceduretext select 'go'
insert into #proceduretext
exec sp_helptext 'SP2'
insert into #proceduretext select 'go'
insert into #proceduretext
exec sp_helptext 'SP3'
insert into #proceduretext select 'go'
.
.
.
insert into #proceduretext
exec sp_helptext 'SP100'
insert into #proceduretext select 'go'
然后从临时表中选择,粘贴结果,运行

然而,上述措施仍然不够

请回答以下问题:

有没有办法为链接服务器使用信息\u SCHEMA.ROUTINES

如果问题1有答案,我如何在下面循环查询所有缺少的过程

insert into #proceduretext
    exec sp_helptext 'SP100'

insert into #proceduretext select 'go'

尝试使用比较工具,您可以下载试用版。非常好

使用链接服务器可以非常轻松地做到这一点。这是我为你准备的一个例子。从目标数据库中运行它,并将[GREGT580]更改为链接服务器的名称

USE tempdb;
GO

-- Copying from [GREGT580] to local server

SET NOCOUNT ON;

DECLARE @MissingProcedures TABLE
(
    MissingProcedureID int IDENTITY(1,1) PRIMARY KEY,
    SchemaName sysname,
    ProcedureName sysname,
    ProcedureDefinition nvarchar(max)
);

INSERT @MissingProcedures 
(
    SchemaName, ProcedureName, ProcedureDefinition
)

SELECT s.[name], p.[name], sm.definition
FROM [GREGT580].AdventureWorks.sys.procedures AS p
INNER JOIN [GREGT580].AdventureWorks.sys.schemas AS s
ON p.schema_id = s.schema_id
INNER JOIN [GREGT580].AdventureWorks.sys.sql_modules AS sm
ON sm.object_id = p.object_id 
WHERE NOT EXISTS (SELECT 1 
                  FROM sys.procedures AS pl
                  INNER JOIN sys.schemas AS sl
                  ON sl.schema_id = pl.schema_id
                  AND sl.[name] = s.[name] COLLATE DATABASE_DEFAULT 
                  AND pl.[name] = p.[name] COLLATE DATABASE_DEFAULT);

DECLARE @SchemaName sysname;
DECLARE @ProcedureName sysname;
DECLARE @ProcedureDefinition nvarchar(max);
DECLARE @Counter int = 1;

WHILE @Counter < (SELECT MAX(MissingProcedureID) FROM @MissingProcedures AS mp)
BEGIN
    SELECT @SchemaName = mp.SchemaName,
           @ProcedureName = mp.ProcedureName,
           @ProcedureDefinition = mp.ProcedureDefinition
    FROM @MissingProcedures AS mp
    WHERE mp.MissingProcedureID = @Counter;

    PRINT @ProcedureDefinition; -- Change to EXEC (@ProcedureDefinition) to create

    SET @Counter += 1;
END;
我让代码打印出程序,这样你就可以测试它了。将打印行更改为实际创建时显示的EXEC选项。请注意,如果它们很长,PRINT将截断它显示的内容,但EXEC可以


希望这对您有所帮助。

为什么不使用任务->生成脚本?请注意,我在tempdb中对其进行了测试。但请记住,当您在自己的数据库中运行USE语句时,请删除它。谢谢您的帮助,我编辑了最后一部分,以使用游标,因为从“定义”列中提取过程脚本会将其带到一行文本中,这对所有过程都不起作用。嘿,是的,实际上它并不起作用。这就是它在SSM和其他工具中的表现。你回到了最初的定义。光标不会有任何区别。有没有办法在这里发布图片?我很想解释这种情况非常简洁的解决方案,但我的试验结束了: