前回がファイル・フォルダの同期だったので今回はデータベースの同期にチャレンジ。ただ、やろうと思うと結構難しいところがでてくる(異種DBとか)ので、今回はダンプファイルからリストアよろしく、親DBの内容を子DBに単純コピーする程度でやってみた。
ちと長めになるけどこんなソース。
Private Sub DbSync()
Const SCOPE_NAME As String = "SCOPE1"
Const SCHEMA_NAME As String = "" '"Sync"
Const PREFIX_NAME As String = "Sync"Dim sourceProvider As New SqlSyncProvider
Dim destinationProvider As New SqlSyncProviderDim srcStr As New SqlConnectionStringBuilder
Dim desStr As New SqlConnectionStringBuilder
With srcStr
.DataSource = "TESTSERVER"
.InitialCatalog = "TESTDB"
.PersistSecurityInfo = True
.IntegratedSecurity = True
End With
With desStr
.DataSource = "TESTSERVER"
.InitialCatalog = "TESTDB2"
.PersistSecurityInfo = True
.IntegratedSecurity = True
End WithUsing srcConn As New SqlConnection(srcStr.ToString)
Using desConn As New SqlConnection(desStr.ToString)
'変更追跡用テーブルを生成
Dim serverScope As New DbSyncScopeDescription(SCOPE_NAME)
'対象テーブル一覧の取得
Dim query As String = "SELECT NAME, OBJECT_ID FROM SYS.TABLES"
Using sqlAdapter As New SqlDataAdapter(query, srcConn)
Using tblSet As New DataTable
sqlAdapter.Fill(tblSet)
For Each child As DataRow In tblSet.Rows
If child.Item(0).ToString.Contains(PREFIX_NAME) Then Continue ForDim targetTable As DbSyncTableDescription = _
‘同期の設定
SqlSyncDescriptionBuilder.GetDescriptionForTable(child.Item(0).ToString, srcConn)
serverScope.Tables.Add(targetTable)
Next
End Using
End Using
Dim serverConfig As New SqlSyncScopeProvisioning(serverScope)
With serverConfig
.ObjectSchema = SCHEMA_NAME
.ObjectPrefix = PREFIX_NAMEIf Not .ScopeExists(SCOPE_NAME, srcConn) Then
.SetCreateTableDefault(DbSyncCreationOption.Skip)
.Apply(srcConn)
End IfEnd With
Dim clientScope As DbSyncScopeDescription = _
SqlSyncDescriptionBuilder.GetDescriptionForScope(SCOPE_NAME, PREFIX_NAME, SCHEMA_NAME, srcConn)
Dim clientConfig As New SqlSyncScopeProvisioning(clientScope)
With clientConfig
.ObjectSchema = SCHEMA_NAME
.ObjectPrefix = PREFIX_NAMEIf Not .ScopeExists(SCOPE_NAME, desConn) Then
.Apply(desConn)
End If
End WithWith sourceProvider
.ScopeName = SCOPE_NAME
.ObjectPrefix = PREFIX_NAME
.ObjectSchema = SCHEMA_NAME
.Connection = srcConn
End With
With destinationProvider
.ScopeName = SCOPE_NAME
.Connection = desConn
.ObjectPrefix = PREFIX_NAME
.ObjectSchema = SCHEMA_NAME
End With
‘同期処理の実行
Dim syncAgent As New SyncOrchestrator
With syncAgent
.RemoteProvider = sourceProvider
.LocalProvider = destinationProvider
.Direction = SyncDirectionOrder.Download
.Synchronize()
End WithEnd Using
End Using
MessageBox.Show("DBの同期が終了しました。", My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
とりあえずこのくらいのロジックで、DB間にてレコードの同期を取ることができた。
気を付けるのは、レコード間の同期を取るために専用のテーブルやトリガ、ストアドプロシージャが必要になるんだけど、それはSqlSyncScopeProvisioning.Applyメソッド呼び出し時に作成してくれる。この時このサンプルのようにスキーマを設定していないと、同一スキーマに作成される=同一権限の人にはテーブルやらがたくさん増えて見える、ことになるのが注意。スキーマを予め用意しておけば、切り離して見ることができるのでそれがベター、というかベストだろうねぇ。
残念ながらスキーマまでは作成してくれませんw
0 件のコメント:
コメントを投稿