2つのテーブルを1つのテーブルにレプリケーションす場合には以下のような手順で実施します。
1.一つのターゲットテーブルに対して、各ソーステーブルからレプリケーションを作成します。
2.ターゲットテーブルでのトランケートや結合を制御するため、各レプリケーションでスクリプトを設定します。
3.レプリケーションを一つのグループに設定します。
4.全てのレコードを削除し、ターゲットテーブルをクリーンアップします。
5.レプリケーションを実行します。



例として、以下のようなレプリケーションを行う場合をご紹介します。
MULTITEST1 > MULTITEST3のレプリケーションを作成します。
1.マッピング設定でID, NAME, COMPANYをマッピングします。
2.UNITにはvbNullをマップします。
3.レプリケーションを無効にし、ウィザードを完了します。
4.レプリケーションのプロパティを開きます。
5.スクリプトの使用にチェックを入れ、以下のスクリプトを追加します。
[vb]
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Namespace DBRS
Public Class ReplicationScript : Inherits IreplicationScript
Dim PrimaryKey As String
Dim Field As String
Dim Table2 As String
Public Overrides Sub Refresh_onBeforeTruncate(ByRef CancelTruncate As Boolean, ByRef Filter As String)
'リフレッシュ時のレコード削除を無効化
CancelTruncate = True
End Sub
Public Overrides Sub Record_onAfterMapping( recSource As DBMotoPublic.IRecord, recTarget As DBMotoPublic.IRecord, ByRef AbortRecord As Boolean, ByRef DisableReplication As Boolean)
Table2 = """asami"".MULTITEST2" 'もう一方のテーブル
PrimaryKey = "ID" '主キー
Field = "UNIT" 'vbNullをマップしたフィールド
'主キーが変更されていない場合
If recTarget.GetValueAfter(PrimaryKey) = Nothing Then
recTarget.SetValueAfter(Field, Nothing)
'主キーが変更されている場合(またはinsert)
Else
InterpolationFields (recTarget)
End If
End Sub
'補間するためにFieldの値を検索
Private Sub InterpolationFields (recTarget As IRecord)
Dim cmd As System.Data.IdbCommand
Dim rs As System.Data.IdataReader
Dim SQL As String
'Table2からPrimaryKeyのレコードを検索
SQL = "Select * From " + Table2 + " Where " + PrimaryKey + " = " & recTarget.GetValueAfter(PrimaryKey)
'レプリケーションのソース接続情報を取得
cmd = SourceConnection.CreateCommand
'コマンドにSQLクエリを代入
cmd.CommandText = SQL
'SQLを実行
rs = cmd.ExecuteReader
'FieldのvbNullを取得した値に置き換え
While rs.Read
recTarget.SetValueAfter(Field, rs(Field))
End While
rs.Close
End Sub
End Class
End Namespace
[/vb]
MULTITEST2 > MULTITEST3のレプリケーションを作成します。
1.マッピング設定でID, NAME, UNITをマッピングします。
2.COMPANYにはvbNullをマップします。
3.レプリケーションを無効にし、ウィザードを完了します。
4.レプリケーションのプロパティを開きます。
5.スクリプトの使用にチェックを入れ、以下のスクリプトを追加します。
[vb]
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Namespace DBRS
Public Class ReplicationScript : Inherits IreplicationScript
Dim PrimaryKey As String
Dim Field As String
Dim Table1 As String
Dim Table2 As String
Dim Table3 As String
Public Overrides Sub Refresh_onBeforeTruncate(ByRef CancelTruncate As Boolean, ByRef Filter As String)
CancelTruncate = True
End Sub
Public Overrides Sub Record_onAfterMapping( recSource As DBMotoPublic.IRecord, recTarget As DBMotoPublic.IRecord, ByRef AbortRecord As Boolean, ByRef DisableReplication As Boolean)
Table1 = """asami"".MULTITEST1" 'もう一方のソーステーブル
Table2 = """asami"".MULTITEST2" 'ソーステーブル
Table3 = "ASAMI.MULTITEST3" 'ターゲットテーブル
PrimaryKey = "ID" '主キー
Field = "UNIT" 'もう一方のレプリケーションでvbNullをマップしたフィールド
'insert,update,deleteでの場合分け
Select Case recTarget.OperationType
'insertの場合、ターゲットのFieldに対してupdateを実施
Case enmOperationType.Insert
UpdateFields(recTarget)
AbortRecord = True
'updateの場合
Case enmOperationType.Update
'主キーが変更されている場合、ターゲットの変更前のFieldをNullにupdate
If recTarget.GetValueAfter(PrimaryKey) <> recTarget.GetValueBefore(PrimaryKey) Then
SetNull(recTarget)
End If
'ターゲットのFieldに対してupdateを実施
UpdateFields(recTarget)
AbortRecord = True
'Deleteの場合
Case enmOperationType.Delete
'Fieldをnullにupdate
SetNull(recTarget)
AbortRecord = True
End Select
End Sub
'Fieldに対するupdate
Private Sub UpdateFields (recTarget As IRecord)
Dim SQL As String
SQL = "Update " + Table3 + " Set "
'FieldがNullの場合はNullにupdate
If recTarget.GetValueAfter(Field) = Nothing Then
SQL = SQL + " " + Field + " = Null "
'Fieldの値でupdateを実施
Else
SQL = SQL + " " + Field + " = '" + recTarget.GetValueAfter(Field) + "'"
End If
'主キーに変更がない場合は変更前の主キーのレコードをupdate
if recTarget.GetValueAfter("ID") = Nothing then
SQL = SQL + " Where " + PrimaryKey + " = '" + recTarget.GetValueBefore(PrimaryKey) + "'"
'主キーが変更されている場合は変更後の主キーのレコードをupdate
else
SQL = SQL + " Where " + PrimaryKey + " = '" + recTarget.GetValueAfter(PrimaryKey) + "'"
End if
AddLog ("UpdateFields SQL: " + SQL, 0)
Try
Dim cmd As System.Data.IdbCommand
cmd = TargetConnection.CreateCommand
cmd.CommandText = SQL
cmd.ExecuteNonQuery()
Catch Ex As System.Exception
AddLog (Table2 + ".*_onAfterFieldMapping (UpdateFields): Cannot update field UNIT on Table " + Table3 + " (" + Ex.Message + ")", 1)
End Try
End Sub
'FieldをNullにupdate
Private Sub SetNull (recTarget As IRecord)
Dim SQL As String
SQL = "Update " + Table3 + " Set " + Field + " = Null Where ID = '" + recTarget.GetValueBefore(PrimaryKey) + "'"
AddLog ("SetNull: " + SQL, 0)
Try
Dim cmd As System.Data.IdbCommand
cmd = TargetConnection.CreateCommand
cmd.CommandText = SQL
cmd.ExecuteNonQuery()
Catch Ex As System.Exception
AddLog (Table2 + ".*_onAfterFieldMapping (SetNull): Cannot update field UNIT on Table " + Table3 + " (" + Ex.Message + ")", 1)
End Try
End Sub
End Class
End Namespace
[/vb]
このようにスクリプトを使用することでターゲットテーブルの一つのレコードを2つのソーステーブルから作成可能です。
しかし、このスクリプトには以下のような制限もあります。
・リフレッシュ時には手動でのターゲットテーブルのレコード削除が必須
・MULTITEST1に存在しない主キーをMULTITEST2にinsertした場合、MULTITEST3にその情報は連携されない
等々
そのため、連携を行うテーブルに合わせてスクリプトをカスタマイズする必要があります。

RSSフィードを取得する