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

我是SQL新手,我需要做的是将2个.mdf数据库合并为一个。 我这样做使用SQL Server 2008pipe理器 – 任务>导入/导出tables.the表和视图复制成功,但在新的数据库中没有存储过程。 有没有办法做到这一点?

  • 右键点击数据库
  • 任务
  • 生成脚本
  • select你想要脚本的对象
  • 脚本到文件
  • 对目标数据库运行生成的脚本

此代码将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 

晚一点,但提供更多细节,可能是有用的…

这里列出了你可以做的优点和缺点

使用SSMS生成脚本

  • 优点:非常容易使用和默认支持
  • 缺点:脚本可能不是正确的执行顺序,如果存储过程已经存在于辅助数据库中,则可能会出错。 确保在执行之前查看脚本。

第三方工具

  • 优点:诸如ApexSQL Diff (这是我使用的工具,但也有许多其他工具,如Red Gate或Dev Art的工具)会比较两个数据库,并生成脚本,您可以立即执行
  • 缺点:这些不是免费的(尽pipe大多数供应商都有一个全function的试用版)

系统视图

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

以下是如何获取某个数据库中所有不在另一个数据库中的过程的列表

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

我最初发现这个职位寻找解决scheme从我的远程生产数据库复制存储过程到我的本地开发数据库。 在这个线程中成功使用了build议的方法之后,我意识到我变得越来越懒惰(或者足智多谋,无论你喜欢什么),并希望自动化。 我遇到了这个链接 ,这被certificate是非常有用的(谢谢你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文件调用此,并从任务计划程序调用。 在调用Powershell文件之后,我有:

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

该行将通过目录并放弃将要重新创build的过程。 如果这不是一个开发环境,我不喜欢以这种方式程序化地删除程序。 然后我重命名所有的存储过程文件有.sql:

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

然后运行:

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

然后遍历所有.sql文件并重新创build存储过程。 我希望这个任何部分都能certificate对某人有帮助。

您可以使用SSMS的“生成脚本…”function来编写任何您需要传输的脚本。 右键单击SSMS中的源数据库,select“生成脚本…”,然后按照向导。 然后运行您的结果脚本,现在将包含存储过程创build语句。

使用

 select * from sys.procedures 

显示您的所有程序;

 sp_helptext @objname = 'Procedure_name' 

获取代码

和你的创造力来build立一些东西循环通过他们都生成导出代码:)

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

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

在Mgmt Studio中,右键单击原始数据库,然后单击任务,然后生成脚本… – 按照向导。

SELECT定义+ char(13)+'GO'FROM MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures p ON [s]。[object_id] = [p]。[object_id] WHERE p.name LIKE'Something% '“查询”c:\ SP_scripts.sql -S MyInstance -T -t -w

得到sp并执行它