Syniti Data Replication (旧DBMoto)でのスクリプトの書き方④:レプリケーションスクリプト


前回に引き続き、 Syniti Data Replication (旧DBMoto) でのスクリプトの書き方をご紹介、今回はその中でもレプリケーションスクリプトの基本的な使用方法をご紹介します。

レプリケーションスクリプトではレプリケーション中に発生した特定のイベントに対する動作を定義できます。。

  • Visual Basic .NETの標準関数およびMicrosoft.VisualBasic名前空間関数またはC#の
    標準関数のいずれかを使用できます。
  • グローバルスクリプトで定義されたユーザー関数
  • 特定のレプリケーションスクリプトイベント、メソッド、およびプロパティ。

レプリケーションスクリプトエディタを使用して、レプリケーション中に特定のイベントが発生したときに実行されるスクリプトを記述します。スクリプトは、エディタの上部にあるドロップダウンリストから選択した1つ以上の関数で構成する必要があります。

※使用する言語(VBまたはC#)はメタデータ内で統一されている必要があり、デフォルトはC#です。変更する場合はグローバルスクリプトのエディタにて変更します。

ドロップダウンから、以下のレプリケーションイベントを選択できます。

レプリケーションイベント

カテゴリイベント種類説明
RefreshonBeforeTruncate
onAfterTruncate
onBeforeRefresh
onAfterRefresh
onPrepareRefresh
Writer
Writer
Writer
Writer
Reader
リフレッシュでのみ利用可能なイベントです。
ターゲットテーブルの削除前後、ターゲットテーブルへの挿入前後、リフレッシュ処理の前のタイミングで実施されるスクリプトを記述できます。
LogReaderonPrepareMirroring
onBeforeMirroring
onAfterMirroring
onReceiverChanged
Reader
Reader
Reader
Reader
ミラーリングとシンクロナイゼーションでのみ利用可能なイベントです。ミラーリングセッションの開始前、トランザクションログの読み取り前後でのスクリプトを記述できます。
onReceiverChangedは、System i / iSeries / AS400でのレプリケーションにのみ適用され、レシーバーが変更されたときに発生するイベントです。
RecordonBeforeMapping
onAfterMapping
onBeforeExecute
onAfterExecute
Reader
Reader
Writer
Writer
レプリケーション時のソーステーブル上レコードとターゲットテーブル上レコードの対応づけ前後、ターゲットテーブルへの変更前後でのスクリプトを記述できます。
ReplicationonConflict
onLateConflict
Reader
Reader
シンクロナイゼーション時に発生したコンフリクト前後でのスクリプトを記述できます。

例えば、レプリケーション時のターゲットテーブルに対するSQL  (INSERT, UPDATE or DELETE) 操作に合わせてスクリプトを記述するのであれば以下のように行います。

1.レプリケーションスクリプトエディタでドロップダウンからRecord、onAfterMappingを選択します。これによりイベント時の動作を上書きするための空の関数が挿入されます。

2.Record_onAfterMappingではIRecordメソッドを使用して、対応付けされたソーステーブル上レコード、ターゲットテーブル上レコードを参照できます。

using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;    
namespace DBRS
  {
   public class ReplicationScript : IReplicationScript
     {
      public override void Record_onAfterMapping(DBMotoPublic.IRecord recSource, 
	       DBMotoPublic.IRecord recTarget, ref bool AbortRecord)
         {
            switch(recTarget.OperationType)
               {
                  case enmOperationType.Insert:
                    if (recTarget.GetValueAfter("SID") == null)
                       {
                          recTarget.SetValueAfter("NAME", null);
                        }
                    else
                        { 
	                    //UpdateSTUDENTFields 
			    (recTarget);
                        }
                        break;
                 case enmOperationType.Update:
                     if (recTarget.GetValueAfter("SID") == null)
                         {
                            recTarget.SetValueAfter("NAME", null);
                         }
                     else if(recTarget.GetValueBefore("SID") == null)
                         {
                            //Field SID was null and now it has a value 
                            //UpdateSTUDENTFields 
	                     (recTarget);
			  }
                     else if(recTarget.GetValueBefore("SID") != recTarget.GetValueAfter("SID"))
                         {
			     //Field SID has changed
                            //UpdateSTUDENTFields 
	                     (recTarget);
			  }
                     break;
                 } 
              }    
        }
   }

この例では、ターゲットテーブルにInsertするときSIDフィールドがNullなら、NameをNullに変更、SIDに値が入っていればそのまま、UpdateするときにUpdate後のSIDフィールドがNullなら、NameをNullに変更、Null以外の場合にはそのまま、処理を行うようにスクリプトを記述しています。

※C#を使用している場合、グローバルスクリプトで定義済みの関数を使用するには、関数名の前にGlobalScriptを付けて下記のように関数が定義されているクラスを識別します。

GlobalScript.AddLog("The current record has been inserted: " + s, 0);

※通常スクリプト内で使用できるフィールドはマッピング設定で対応付けされたカラムのみです。対応付けされていないカラムの値を使用する場合は、レプリケーションプロパティダイアログのマッピング設定にて対象カラムに対して「未マッピング使用」を設定する必要があります。

※複数のイベントがアクセスする必要のあるオブジェクトが存在する場合には注意が必要です。ReaderとWriterのイベント(ソースDBからの読み取り関連イベントとターゲットDBへの書き込み関連イベント)両方がアクセスするオブジェクトに関してロックを行うようにスクリプトに記述する必要があります。

※関数ジェネレータを使用して関数を定義し、スクリプト内で使用することもできます。この時、一覧にはグローバルスクリプトで作成した関数も表示されます。

※ライブラリをスクリプト内のインポートのリストに追加する場合、リファレンスダイアログから追加可能です。

このようにレプリケーションごとにスクリプトを記述し、より柔軟にデータを転送することも可能です。グローバルスクリプトと同様に本ブログでもいくつかサンプルをご紹介していますので、こちらもご参照いただければ幸いです。

関連したトピックス

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください