SQL Server-将存储过程从一个数据库复制到另一个数据库


Answers:


137
  • 右键单击数据库
  • 任务
  • 生成脚本
  • 选择您要编写脚本的对象
  • 脚本到文件
  • 针对目标数据库运行生成的脚本

嗨,谢谢您的快速回复。您能否解释一下如何针对目标数据库使用脚本。我是新来的。
2012年

1
@BarryKaye,如果他有30-40个存储过程怎么办?右键单击会不会有点慢?
rvphx 2012年

@Oak在SQL Management Studio中打开生成脚本文件。将连接更改为新的数据库。将文件最上方的行更改为“ Use DatabaseName”,然后执行。
Jaimal Chohan 2012年

哇。现在我以为我是唯一喜欢基于GUI的方法的人!!
rvphx 2012年

10
@RajivVarma-您只需对数据库执行一次此任务-而不是每个SP!如果勾选“存储过程”旁边的顶级复选框,则将它们全部选中-1单击。
巴里·凯

19

该代码将Master数据库中的所有存储过程复制到目标数据库,您可以通过过滤过程名称查询来仅复制所需的过程。

@sql定义为nvarchar(max),@ Name是目标数据库

DECLARE c CURSOR FOR 
   SELECT Definition
   FROM [ResiDazeMaster].[sys].[procedures] p
   INNER JOIN [ResiDazeMaster].sys.sql_modules m ON p.object_id = m.object_id

OPEN c

FETCH NEXT FROM c INTO @sql

WHILE @@FETCH_STATUS = 0 
BEGIN
   SET @sql = REPLACE(@sql,'''','''''')
   SET @sql = 'USE [' + @Name + ']; EXEC(''' + @sql + ''')'

   EXEC(@sql)

   FETCH NEXT FROM c INTO @sql
END             

CLOSE c
DEALLOCATE c

谢谢!...在注释中但未在代码中声明的是@sql@NameDECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
datalifenyc

有什么办法可以在不同的服务器上做到这一点吗?从服务器A到服务器B?
Rajaram1991

5

较晚,但提供了更多可能有用的详细信息…

这是您可以利用优点和缺点进行操作的列表

使用SSMS生成脚本

  • 优点:极易使用,默认情况下受支持
  • 缺点:脚本可能没有正确的执行顺序,并且如果辅助数据库上已经存在存储过程,则可能会出错。确保在执行之前检查脚本。

第三方工具

  • 优点:诸如ApexSQL Diff之类的工具(这是我使用的工具,但还有其他许多工具,例如Red Gate或Dev Art的工具)将一键比较两个数据库并生成可以立即执行的脚本
  • 缺点:这些不是免费的(尽管大多数供应商都提供了功能齐全的试用版)

系统视图

  • 优点:您可以轻松查看辅助服务器上存在哪些存储过程,并仅生成您没有的存储过程。
  • 缺点:需要更多的SQL知识

这是如何获取某个数据库中所有其他数据库中不存在的过程的列表

select *
from DB1.sys.procedures P
where P.name not in 
 (select name from DB2.sys.procedures P2)

5

我最初发现这篇文章是在寻找一种将存储过程从远程生产数据库复制到本地开发数据库的解决方案。在此线程中使用建议的方法成功完成之后,我意识到我变得越来越懒惰(或者足智多谋,无论您喜欢哪个),并希望将其自动化。我遇到了这个链接该链接非常有用(谢谢vincpa),我对此进行了扩展,生成了以下文件(schema_backup.ps1):

$server             = "servername"
$database           = "databaseName"
$output_path        = "D:\prod_schema_backup"
$login = "username"
$password = "password"

$schema             = "dbo"
$table_path         = "$output_path\table\"
$storedProcs_path   = "$output_path\stp\"
$views_path         = "$output_path\view\"
$udfs_path          = "$output_path\udf\"
$textCatalog_path   = "$output_path\fulltextcat\"
$udtts_path         = "$output_path\udtt\"

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")  | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")  | out-null
$srvConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$srvConn.ServerInstance = $server
$srvConn.LoginSecure = $false
$srvConn.Login = $login
$srvConn.Password = $password
$srv        = New-Object Microsoft.SqlServer.Management.SMO.Server($srvConn)
$db         = New-Object ("Microsoft.SqlServer.Management.SMO.Database")
$tbl        = New-Object ("Microsoft.SqlServer.Management.SMO.Table")
$scripter   = New-Object Microsoft.SqlServer.Management.SMO.Scripter($srvConn)

# Get the database and table objects
$db = $srv.Databases[$database]

$tbl            = $db.tables | Where-object { $_.schema -eq $schema  -and -not $_.IsSystemObject } 
$storedProcs    = $db.StoredProcedures | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$views          = $db.Views | Where-object { $_.schema -eq $schema } 
$udfs           = $db.UserDefinedFunctions | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$catlog         = $db.FullTextCatalogs
$udtts          = $db.UserDefinedTableTypes | Where-object { $_.schema -eq $schema } 

# Set scripter options to ensure only data is scripted
$scripter.Options.ScriptSchema  = $true;
$scripter.Options.ScriptData    = $false;

#Exclude GOs after every line
$scripter.Options.NoCommandTerminator   = $false;
$scripter.Options.ToFileOnly            = $true
$scripter.Options.AllowSystemObjects    = $false
$scripter.Options.Permissions           = $true
$scripter.Options.DriAllConstraints     = $true
$scripter.Options.SchemaQualify         = $true
$scripter.Options.AnsiFile              = $true

$scripter.Options.SchemaQualifyForeignKeysReferences = $true

$scripter.Options.Indexes               = $true
$scripter.Options.DriIndexes            = $true
$scripter.Options.DriClustered          = $true
$scripter.Options.DriNonClustered       = $true
$scripter.Options.NonClusteredIndexes   = $true
$scripter.Options.ClusteredIndexes      = $true
$scripter.Options.FullTextIndexes       = $true

$scripter.Options.EnforceScriptingOptions   = $true

function CopyObjectsToFiles($objects, $outDir) {
    #clear out before 
    Remove-Item $outDir* -Force -Recurse
    if (-not (Test-Path $outDir)) {
        [System.IO.Directory]::CreateDirectory($outDir)
    }   

    foreach ($o in $objects) { 

        if ($o -ne $null) {

            $schemaPrefix = ""

            if ($o.Schema -ne $null -and $o.Schema -ne "") {
                $schemaPrefix = $o.Schema + "."
            }

            #removed the next line so I can use the filename to drop the stored proc 
            #on the destination and recreate it
            #$scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name + ".sql"
            $scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name
            Write-Host "Writing " $scripter.Options.FileName
            $scripter.EnumScript($o)
        }
    }
}

# Output the scripts
CopyObjectsToFiles $tbl $table_path
CopyObjectsToFiles $storedProcs $storedProcs_path
CopyObjectsToFiles $views $views_path
CopyObjectsToFiles $catlog $textCatalog_path
CopyObjectsToFiles $udtts $udtts_path
CopyObjectsToFiles $udfs $udfs_path

Write-Host "Finished at" (Get-Date)
$srv.ConnectionContext.Disconnect()

我有一个.bat文件调用此文件,并从Task Scheduler中调用它。调用Powershell文件后,我有:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /Q "DROP PROCEDURE %f"

该行将通过目录,并删除将要重新创建的过程。如果这不是开发环境,那么我不希望以编程方式删除程序。然后,我将所有存储过程文件重命名为具有.sql:

powershell Dir d:\prod_schema_backup\stp\ | Rename-Item -NewName { $_.name + ".sql" }

然后运行:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /E /i "%f".sql

然后遍历所有.sql文件并重新创建存储过程。我希望其中的任何部分都会对某人有所帮助。


我喜欢这个 我必须每年编写一次从生产数据库中归档块的过程。我不想让SQL文件挂起,因为随着模式的发展它可能不会被更新,因此我将其调整为基于目标创建空的DB,而无需执行将文件写入磁盘的中间步骤(更多信息)。清理)。我想这可能是这个问题上最好,最可重复使用的答案,先生,先生!
史蒂夫·佩蒂弗

3

您可以使用SSMS的“生成脚本...”功能来脚本化您需要传输的内容。右键单击SSMS中的源数据库,选择“生成脚本...”,然后按照向导进行操作。然后运行结果脚本,该脚本现在将包含存储过程create语句。


3

使用

select * from sys.procedures

显示您的所有程序;

sp_helptext @objname = 'Procedure_name'

获取代码

和您的创造力来构建一些东西来遍历它们并生成导出代码:)


3

您可以生成存储过程脚本,如其他答案所示。生成脚本后,您可以使用sqlcmd它针对目标数据库执行脚本,例如

sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file> 

0

在Mgmt Studio中,右键单击原始数据库,然后右键单击“任务”,然后单击“生成脚本...”-按照向导进行操作。


0

SELECT定义+ char(13)+'GO'从MyDatabase.sys.sql_modules的INNER JOIN MyDatabase.sys.procedures p ON [s]。[object_id] = [p]。[object_id]其中p.name喜欢'Something% '“ queryout” c:\ SP_scripts.sql -S MyInstance -T -t -w

得到sp并执行它


这是一个非常好的解决方案,但是1)您应该指出需要文本或文件输出(不要在网格中显示结果,否则您将失去EOL字符); 2)似乎有8k的限制用于在SQL Server Management Studio中输出文本。
民建联

0

另一种选择是使用SQL Server Integration Services(SSIS)传输存储过程。有一个名为“传输SQL Server对象任务”的任务。您可以使用该任务来传输以下项目:

  • 桌子
  • 观看次数
  • 存储过程
  • 用户定义的功能
  • 默认值
  • 用户定义的数据类型
  • 分区功能
  • 分区方案
  • 模式
  • 装配体
  • 用户定义的聚合
  • 用户定义的类型
  • XML模式集合

这是传输SQL Server对象任务的图形教程

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.