私はSQLを初めて使用し、2つの.mdfデータベースを1つに結合する必要がありました。SQL Server 2008Managerを使用してこれを行いました-[タスク]>[テーブルのインポート/エクスポート]。テーブルとビューは正常にコピーされましたが、新しいデータベースにストアドプロシージャがありません。それを行う方法はありますか?
11 に答える
- データベースを右クリック
- タスク
- スクリプトを生成する
- スクリプト化するオブジェクトを選択します
- スクリプトからファイルへ
- ターゲットデータベースに対して生成されたスクリプトを実行する
このコードは、マスターデータベース内のすべてのストアドプロシージャをターゲットデータベースにコピーします。プロシージャ名でクエリをフィルタリングすることにより、必要なプロシージャだけをコピーできます。
@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
遅いものですが、役立つかもしれない詳細を提供します…</ p>
これが長所と短所でできることのリストです
SSMSを使用してスクリプトを生成する
- 長所:非常に使いやすく、デフォルトでサポートされています
- 短所:スクリプトが正しい実行順序になっていない可能性があり、ストアドプロシージャがセカンダリデータベースにすでに存在する場合はエラーが発生する可能性があります。実行する前に、必ずスクリプトを確認してください。
サードパーティのツール
- 長所:ApexSQL Diffなどのツール(これは私が使用しているものですが、RedGateやDevArtのツールのような他の多くのツールがあります)は、ワンクリックで2つのデータベースを比較し、すぐに実行できるスクリプトを生成します
- 短所:これらは無料ではありません(ただし、ほとんどのベンダーは完全に機能するトライアルを持っています)
システムビュー
- 長所:セカンダリサーバーに存在するストアドプロシージャを簡単に確認し、存在しないストアドプロシージャのみを生成できます。
- 短所:もう少しSQLの知識が必要です
別のデータベースには存在しない、あるデータベースのすべてのプロシージャのリストを取得する方法は次のとおりです。
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ファイルがあり、タスクスケジューラから呼び出されます。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ファイルを反復処理し、ストアドプロシージャを再作成します。これのどの部分も誰かに役立つことが証明されることを願っています。
使用する
select * from sys.procedures
すべての手順を表示します。
sp_helptext @objname = 'Procedure_name'
コードを取得するには
そして、それらすべてをループしてエクスポートコードを生成するための何かを構築するあなたの創造性:)
SSMSの「GenerateScripts...」機能を使用して、転送する必要のあるものをすべてスクリプト化できます。SSMSでソースデータベースを右クリックし、[スクリプトの生成...]を選択して、ウィザードに従います。次に、ストアドプロシージャのcreateステートメントを含む結果のスクリプトを実行します。
他の回答に示されているように、ストアドプロシージャのスクリプトを生成できます。スクリプトが生成されたら、次のsqlcmd
ようなターゲットDBに対してスクリプトを実行するために使用できます。
sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file>
もう1つのオプションは、SQL Server Integration Services(SSIS)を使用してストアドプロシージャを転送することです。SQLServerオブジェクトの転送タスクと呼ばれるタスクがあります。このタスクを使用して、次のアイテムを転送できます。
- テーブル
- ビュー
- ストアドプロシージャ
- ユーザー定義関数
- デフォルト
- ユーザー定義のデータ型
- 分配関数
- パーティションスキーム
- スキーマ
- アセンブリ
- ユーザー定義の集計
- ユーザー定義タイプ
- XMLスキーマコレクション
これは、 SQLServerオブジェクトの転送タスクのグラフィカルなチュートリアルです。
Mgmt Studioで、元のデータベースを右クリックし、[タスク]、[スクリプトの生成]の順にクリックします...-ウィザードに従います。
SELECT定義+char(13)+'GO' FROM MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures pON[s]。[object_id]=[p]。[object_id]WHEREp.name LIKE'何か% '"queryout" c:\ SP_scripts.sql -S MyInstance -T -t -w
spを取得して実行します
-- This program copies (CREATE OR ALTER) a single PROCEDURE from one database to another
declare @SourceDatabase nvarchar(50);
declare @SourceSchemaName nvarchar(50)
declare @TargetDatabase nvarchar(50);
declare @ProceduresName nvarchar(50);
declare @sql nvarchar(max)
set @SourceDatabase = N'Northwind' -- The name of the source database
set @SourceSchemaName = N'dbo' -- The name of Procedure SCHEME
set @ProceduresName = N'CustOrderHist' -- The name of Procedure
set @TargetDatabase = N'AdventureWorks' -- The name of the Target database
-- -------- - - -
-- If the PROCEDURE SCHEME does not exist, create it
set @sql = ' use [' +@TargetDatabase +'] ' +
' IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = ''' + @SourceSchemaName+''') '+
' BEGIN ' +
' EXEC('' CREATE SCHEMA '+ @SourceSchemaName +''') ' +
' END'
exec (@sql);
set @sql = ''
--
set @sql = @sql + ' use [' + @TargetDatabase +'] ;' +
' declare @sql2 nvarchar(max) ;' +
' SELECT @sql2 = coalesce(@sql2,'';'' ) + [definition] + '' ; '' ' +
' FROM ['+@sourceDatabase+'].[sys].[procedures] p ' +
' INNER JOIN ['+@sourceDatabase+'].sys.sql_modules m ON p.object_id = m.object_id '+
' where SCHEMA_NAME([schema_id]) = ''' +@SourceSchemaName +''' and [name] = N''' + @ProceduresName + ''' ; ' +
' set @sql2 = replace(@sql2,''CREATE PROCEDURE'',''CREATE OR ALTER PROCEDURE'')' +
' exec (@sql2)'
exec (@sql)