我是SQL的新手,我需要做的是将2个.mdf数据库合并为一个。我使用SQL Server 2008 Manager-任务>导入/导出表进行了此操作。表和视图已成功复制,但是新数据库中没有存储过程。有什么办法吗?
Answers:
该代码将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
&@Name
:DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
较晚,但提供了更多可能有用的详细信息…
这是您可以利用优点和缺点进行操作的列表
使用SSMS生成脚本
第三方工具
系统视图
这是如何获取某个数据库中所有其他数据库中不存在的过程的列表
select *
from DB1.sys.procedures P
where P.name not in
(select name from DB2.sys.procedures P2)
我最初发现这篇文章是在寻找一种将存储过程从远程生产数据库复制到本地开发数据库的解决方案。在此线程中使用建议的方法成功完成之后,我意识到我变得越来越懒惰(或者足智多谋,无论您喜欢哪个),并希望将其自动化。我遇到了这个链接,该链接非常有用(谢谢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文件并重新创建存储过程。我希望其中的任何部分都会对某人有所帮助。
在Mgmt Studio中,右键单击原始数据库,然后右键单击“任务”,然后单击“生成脚本...”-按照向导进行操作。
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并执行它