テーブル一括作成やマッピングをカスタマイズ:グローバルスクリプト[Syniti Replicate]


Syniti Replicateでは以下のよう特定スキーマ間でレプリケーションを一括で複数作成することができます。

この一括作成時にはソースとターゲットのスキーマを指定すると、どのようにテーブルを対応付けするかといったことも指定できます。

この際に存在しないテーブルに関してはデフォルトですと自動的に、同一の構成でターゲットテーブルも作成、マッピングを行いますが、以下のような対応が必要になる場合があります。

  • ソーステーブルとは異なるデータ型やサイズをターゲットテーブルでは使用したい
  • ソーステーブルにはない、カラムを追加したい
  • ターゲットテーブルへのマッピングをカスタマイズしたい

このようなケースではグローバルスクリプトで独自にルールを定義し、それを上記の右下「テーブルルールを作成」や「マッピングルール」で指定して使用することで対応できます。

ターゲットテーブル作成時にデータ型、サイズ変更など

グローバルスクリプトのICreateTableRuleイベントでテーブル作成時の独自ルールを作成できます。

aTargetFieldsで作成される予定のターゲットテーブル上のフィールド情報(デフォルトではソースと同様)を取得でき、これを変更することでカラム名やデータ型を変更できます。

サンプル:varcharの場合、カラム名末尾に_targetを追加、nvarcharに変更後、サイズを1.5倍に

using System;
using System.Data;
using System.Collections.Generic;
using DBMotoPublic;
using DBMotoScript;

namespace DBRS
{
    public class GlobalScript : IGlobalScript
    {
    }

    public class MappingRule : IMappingRule
    {
    }

    public class CreateTableRule : ICreateTableRule
    {        
	//この属性がGUI上での選択時に表示されます。
        [CreateTableRuleAttribute("ChangeTypeAndSize", "varcharの場合、カラム名末尾に_targetを追加、nvarcharに変更後、サイズを1.5倍に")]
        public bool ChangeTypeAndSize(List<ColumnClass> aTargetFields)
        {
            //カラムの型が、varcharかどうか判定
            for (int i=0; i<aTargetFields.Count; i++)
            {
                if(aTargetFields[i].TypeName=="varchar")
                {
                    //カラム名の末尾に_targetを追加
                    aTargetFields[i].Name=aTargetFields[i].Name+"_target";
                    //nvarcharへ変更
                    aTargetFields[i].TypeName="nvarchar";
                    //サイズを1.5倍に
                    aTargetFields[i].Size=(int)(aTargetFields[i].Size*1.5);
                }
            }
            return true;
        }
    }

    public class GlobalEvents : IGlobalEvents
    {
    }

}

ソーステープルの構成:

ターゲットテーブル作成時に作成したスクリプトのルールを設定した場合:

元々varcharであった「電話番号」のフィールドのみ、フィールド名が「電話番号_target」に、型はnvarcharに、サイズは1.5倍されています。

スクリプトで使用しているColumnClassは以下のようにフィールド(カラム)の定義情報を保持しています。

public class ColumnClass
{
        //カラム名
	public string Name;
        //カラムのCCSID(IBM系の場合)
	public int CCSID;
        //カラムの型名
	public string TypeName;
        //カラムのサイズ
	public int Size;
        //カラムの精度
	public int Precision;
        //カラムのスケール
	public int Scale;
        //nullであれば通常のカラム、数字を指定すると主キー、値が小さい順に主キーとして指定
	public int PrimaryKeyPos;
        //TrueならばNullを許可
	public bool AllowNull;
        //カラムのデフォルト値
	public string Default;
}

ターゲットフィールド側のColumnClassを変更することで、自動作成されるターゲットテーブルの定義を変更しています。

カラムの追加

同様にICreateTableRuleでColumnClassで定義を作成し、aTargetFieldsにInsertまたはAddしてカラムを追加できます。

using System;
using System.Data;
using System.Collections.Generic;
using DBMotoPublic;
using DBMotoScript;

namespace DBRS
{
    public class GlobalScript : IGlobalScript
    {	
    }

    public class MappingRule : IMappingRule
    {
    }

        [CreateTableRuleAttribute("Audit Table New", "監査用のカラムを追加")]
        public bool MyCustomAuditTable (List<ColumnClass> aTargetFields)     
        {         
            ColumnClass colClass;
            //レプリケーションされたトランザクションのIDを記録するカラムを作成
            colClass = new ColumnClass();
              colClass.Name = "TID";
              colClass.AllowNull = true;
              colClass.TypeName = "varchar";
              colClass.Size = 50;
            //2番目に追加
            aTargetFields.Insert(1,colClass);

            //レプリケーションされたトランザクションのタイムスタンプを記録するカラムを作成
            colClass = new ColumnClass();
             colClass.Name = "TTS";
              colClass.AllowNull = true;
              colClass.TypeName = "datetime2";
            //最後に追加
            aTargetFields.Add(colClass);

            //レプリケーションされたトランザクションのユーザIDを記録するカラムを作成
            colClass = new ColumnClass();
              colClass.Name = "UserID";
              colClass.AllowNull = true; 
              colClass.TypeName = "varchar";
              colClass.Size = 20;
            //最後に追加
            aTargetFields.Add(colClass);

            return true;
        }


    public class GlobalEvents : IGlobalEvents
    {
    }
}

ソーステープルの構成:

ターゲットテーブル作成時に作成したスクリプトのルールを設定した場合:

マッピングのカスタマイズ

カラムを追加した場合などには、それに合わせてマッピングも調整する必要があります。これも自動化する場合には以下のようにIMappingRuleで独自ルールを作成します。

using System;
using System.Data;
using System.Collections.Generic;
using DBMotoPublic;
using DBMotoScript;

namespace DBRS
{
    public class GlobalScript : IGlobalScript
    {	
    }

    public class MappingRule : IMappingRule
    {
        [MappingRuleAttribute("Map For Audit Table", "監査用のカラムにマッピングを追加")]
        public bool AuditTableMapping (bool bIsForth, string sSourceName, int iSourceOrdinal, 
        string sSourceType, bool bIsSourcePrimaryKey, bool bIsSourceNullable, 
        int iSourceSize, short sSourcePrecision, short sSourceScale, string sTargetName, 
        int iTargetOrdinal, string sTargetType, bool bIsTargetPrimaryKey, bool bIsTargetNullable,
        int iTargetSize, short sTargetPrecision, short sTargetScale, 
        ref System.Text.StringBuilder sExpression)
        {
            //カラム名がTTSの場合、関数でトランザクションタイムスタンプを指定
            if (String.Compare(sTargetName, "TTS", true) == 0)
            {
                sExpression.Append("[!TransactionTS]");
                return true;
            }
            //カラム名がTIDの場合、関数でトランザクションIDを指定
            else if (String.Compare(sTargetName, "TID", true) == 0)
            {
                sExpression.Append("[!TransactionID]");
                return true;
            }
            //カラム名がUserIDの場合、関数でユーザIDを指定
            else if (String.Compare(sTargetName, "UserID", true) == 0)
            {
                sExpression.Append("[!UserID]");
                return true;
            }
            //上記以外の場合、ソースのカラム名と一致するカラム名にマッピング
            else
            return String.Compare(sSourceName, sTargetName, true) == 0;
        }
    }
...

このルールを使用してマッピングすると自動的に監査用カラムが関数にマッピングされます。

この状態でレプリケーションを行うと以下のようにミラーリングで連携されたものはその際のトランザクションのID、タイムスタンプ、ユーザIDが記録されます。

このように、ICreateTableRuleでテーブル作成のルールをIMappingRuleでカラムのマッピングルールを定義することで、同一構成でなくともまとめてレプリケーションを設定するといった対応も可能です。

また、デフォルトで使用するルールはデータベース接続に対して設定でき、これを変更することで、いちいち選択しなおさなくともルールを適用できます。

関連したトピックス

コメントを残す

メールアドレスが公開されることはありません。

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