15 Oracle GoldenGate処理のカスタマイズ

この章では、Oracle GoldenGate処理をカスタマイズする方法について説明します。

内容は次のとおりです。

15.1 SQLEXECを使用したコマンド、ストアド・プロシージャおよび問合せの実行

Oracle GoldenGateのSQLEXECパラメータによって、ExtractおよびReplicatでデータベースと通信し、次の処理を実行できます。

  • データベース・コマンド、ストアド・プロシージャまたはSQL問合せの実行によるデータベース機能の実行、結果の返却(SELECT文)またはDML操作の実行(INSERTUPDATEDELETE)が可能です。

  • プロシージャから出力パラメータを取得してFILTER句またはCOLMAP句に入力できます。

ノート:

SQLEXECは最小限のグローバリゼーション・サポートを提供します。ソース・キャプチャのキャプチャ・パラメータ・ファイルでSQLEXECを使用するには、ソース.prmファイルのクライアント文字セットが同じであるか、ソース・データベースの文字セットのスーパーセットであることを確認します。

15.1.1 SQLEXECを使用した処理の実行

SQLEXECによって、Oracle GoldenGateではデータベースのネイティブSQLを使用してカスタム処理命令を実行できるため、Oracle GoldenGateとデータベース両方の機能が拡張されます。

  • ストアド・プロシージャおよび問合せを使用して、データベースを対象とするデータの選択または挿入、データの集計、データの非正規化または正規化、あるいは入力にデータベース操作を必要とする他の任意の機能を実行できます。Oracle GoldenGateでは、入力を取得するストアド・プロシージャと出力を生成するストアド・プロシージャがサポートされます。

  • データベース・コマンドを発行して、Oracle GoldenGate処理を効率化するために必要なデータベース機能を実行できます(ターゲット表に対するトリガーを無効化して、その後再度有効化するなど)。

15.1.2 SQLEXECの使用

SQLEXECパラメータは、次の方法で使用できます。

  • TABLE文またはMAP文の句として

  • ExtractまたはReplicatのパラメータ・ファイルのルート・レベルに存在するスタンドアロン・パラメータとして

15.1.3 TABLE文またはMAP文内でのSQLEXECの実行

TABLE文またはMAP文内で使用する場合、SQLEXECでパラメータを受け渡したり、受け入れたりすることができます。プロシージャおよび問合せに使用できますが、データベース・コマンドには使用できません。

構文

この構文は、TABLE文またはMAP文内でプロシージャを実行します。

SQLEXEC (SPNAME sp_name,
[ID logical_name,]
{PARAMS param_spec | NOPARAMS})
引数 説明
SPNAME

ストアド・プロシージャを実行するための句を開始する必須キーワード。

sp_name

実行するストアド・プロシージャの名前を指定します。

ID logical_name

プロシージャの論理名を定義します。このオプションを使用して、TABLE文またはMAP文内でプロシージャを複数回実行します。プロシージャを1回のみ実行する場合は不要です。

PARAMS param_spec |
NOPARAMS

プロシージャでパラメータを受け入れるかどうかを指定します。これらのオプションのいずれかを使用する必要があります(「入力パラメータと出力パラメータの使用」を参照)。

構文

この構文は、TABLE文またはMAP文内で問合せを実行します。

SQLEXEC (ID logical_name, QUERY ' query ',
{PARAMS param_spec | NOPARAMS})
引数 説明
ID logical_name

問合せの論理名を定義します。問合せの結果から値を抽出するには、論理名が必要です。ID logical_nameは、問合せによって戻される列値を参照します。

QUERY ' sql_query '

データベースに対して実行するSQL問合せの構文を指定します。これにより、SELECT文を使用して結果を戻すか、INSERT文、UPDATE文またはDELETE文を使用してデータベースを変更することが可能になります。問合せは、一重引用符で囲み、全体を1行で記述する必要があります。大/小文字が区別されるオブジェクト名を、データベースに格納されているとおりに指定します。たとえば、Oracleの大/小文字が区別される名前の場合は引用符で囲みます。

SQLEXEC 'SELECT "col1" from "schema"."table"'
PARAMS param_spec |
NOPARAMS

問合せでパラメータを受け入れるかどうかを定義します。これらのオプションのいずれかを使用する必要があります(「入力パラメータと出力パラメータの使用」を参照)。

現在のデータベースではなく、異なるデータベースにある表で問合せを実行する場合は、異なるデータベース名を表で指定する必要があります。データベース名および表名の間の区切り記号はコロン(:)にする必要があります。使用例を次に示します。

select col1 from db1:tab1
select col2 from db2:schema2.tab2
select col3 from tab3
select col3 from schema4.tab4

15.1.4 スタンドアロン文としてのSQLEXECの実行

ExtractまたはReplicatのパラメータ・ファイルでスタンドアロン・パラメータ文として使用する場合、SQLEXECは、ストアド・プロシージャ、問合せまたはデータベース・コマンドを実行できます。この場合、このパラメータを特定の表に関連付ける必要はなく、一般的なSQL操作を実行するために使用できます。たとえば、Oracle GoldenGateのデータベース・ユーザー・アカウントがアイドル時にタイムアウトされるように構成されている場合、SQLEXECを使用して、Oracle GoldenGateが見かけ上アイドル状態とならないように、定義した間隔で問合せを実行できます。別の例としては、SQLEXECを使用して、ターゲット・トリガーの無効化などの重要なデータベース・コマンドを発行できます。スタンドアロンのSQLEXEC文では、入力パラメータを受け入れることや、出力パラメータを戻すことはできません。

パラメータ構文 目的
SQLEXEC 'call procedure_name()'

ストアド・プロシージャの実行

SQLEXEC 'sql_query'

問合せの実行

SQLEXEC 'database_command'

データベース・コマンドの実行

引数 説明
'call
procedure_name ()'

実行するストアド・プロシージャ名を指定します。文は一重引用符で囲む必要があります。

例:

SQLEXEC 'call prc_job_count ()'
'sql_query'

実行する問合せ名を指定します。問合せは、全体を1行で記述し、一重引用符で囲む必要があります。

大/小文字の区別されるオプション名を、データベースに格納されているとおりに指定します。たとえば、大/小文字が区別されるOracleオブジェクト名の場合は二重引用符で囲みます。

SQLEXEC 'SELECT "col1" from "schema"."table"'
'database_command'

実行するデータベース・コマンドを指定します。データベースにとって有効なコマンドである必要があります。

SQLEXECには、処理動作、メモリー使用およびエラー処理を制御するためのオプションがあります。詳細は、『Oracle GoldenGateリファレンス』を参照してください。

15.1.5 入力パラメータと出力パラメータの使用

Oracle GoldenGateでは、TABLE文またはMAP文内のSQLEXECで実行されるプロシージャまたは問合せを対象として入力値と出力値を受け渡すためのオプションを提供しています。

15.1.5.1 入力パラメータへの値の受渡し

ストアド・プロシージャまたは問合せ内の入力パラメータにデータ値を渡すには、SQLEXECPARAMSオプションを使用します。

構文

PARAMS ([OPTIONAL | REQUIRED] param = {source_column | function}
[, ...] )

説明:

  • OPTIONALは、SQLの実行にパラメータ値が必要ないことを示します。必要なソース列がデータベース操作で見つからない場合、またはソース列が見つからないために列変換ファンクションを完了できない場合でも、SQLは実行されます。

  • REQUIREDは、パラメータ値が存在している必要があることを示します。パラメータ値が存在しない場合、SQLは実行されません。

  • paramは次のいずれかとなります。

    • ストアド・プロシージャの場合、ストアド・プロシージャ内の入力を受け付ける任意のパラメータ名(参照表の列など)です。

    • Oracle問合せの場合、問合せの任意の入力パラメータの名前(先頭のコロンを除く)です。たとえば、:param1の場合は、PARAMS句ではparam1と指定します。

    • Oracle以外の問合せの場合はpn (nは1から始まるパラメータの番号)です。たとえば、パラメータが2個の問合せでは、paramエントリはp1およびp2です。

  • {source_column | function}は、プロシージャへの入力を提供する列またはOracle GoldenGate変換関数です。

15.1.5.2 出力パラメータへの値の受渡し

ストアド・プロシージャまたは問合せからの値を入力値としてFILTER句またはCOLMAP句に渡すには、次の構文を使用します。

構文

{procedure_name | logical_name}.parameter

説明:

  • procedure_nameは、ストアド・プロシージャの実際の名前です。この引数は、現在のOracle GoldenGateプロセスの有効期間中にプロシージャを1回実行する場合にのみ使用します。

  • logical_nameは、SQLEXECIDオプションで指定した論理名です。この引数は、問合せを実行する場合、またはストアド・プロシージャを複数回実行する場合に使用します。

  • parameterは、パラメータの名前またはRETURN_VALUE (戻り値を抽出する場合)です。

15.1.5.3 パラメータを使用するSQLEXECの例

これらの例では、入力パラメータと出力パラメータを使用するストアド・プロシージャと問合せを使用します。

ノート:

プロシージャまたは問合せにパラメータが含まれる場合、追加のSQLEXECオプションを使用できます。SQLEXECの詳細は、『Oracle GoldenGateリファレンス』を参照してください。

例15-1 ストアド・プロシージャを使用するSQLEXEC

この例では、SQLEXECを使用して、コードに基づいて説明を戻す問合せを実行するLOOKUPというストアド・プロシージャを実行します。その後、NEWACCT_VALという名前のターゲット列に結果をマップします。

CREATE OR REPLACE PROCEDURE LOOKUP
(CODE_PARAM IN VARCHAR2, DESC_PARAM OUT VARCHAR2)
BEGIN
    SELECT DESC_COL
    INTO DESC_PARAM
    FROM LOOKUP_TABLE
    WHERE CODE_COL = CODE_PARAM
END;

MAP文の内容:

MAP sales.account, TARGET sales.newacct, &
  SQLEXEC (SPNAME lookup, PARAMS (code_param = account_code)), &
    COLMAP (newacct_id = account_id, newacct_val = lookup.desc_param);

SQLEXECは、LOOKUPストアド・プロシージャを実行します。SQLEXEC句内のPARAMS (code_param = account_code)文では、code_paramをプロシージャ・パラメータとして識別し、account表のaccount_code列から入力値を受け入れます。

Replicatでは、列マップを実行する前にLOOKUPストアド・プロシージャが実行されるため、COLMAP句によりその結果を抽出してnewacct_val列にマップできます。

例15-2 問合せを使用するSQLEXEC

この例では、前述の例で使用されているものと同じロジックを実装していますが、ストアド・プロシージャのかわりにSQL問合せを実行し、列マップで@GETVAL関数を使用します。

問合せは1行である必要があります。また、Oracle GoldenGateのパラメータ文を複数の行に分割する場合、行末にアンパサンド(&)が必要です。

Oracleデータベースの問合せ:

MAP sales.account, TARGET sales.newacct, &
SQLEXEC (ID lookup, &
QUERY 'select desc_col desc_param from lookup_table where code_col = :code_param', &
PARAMS (code_param = account_code)), &
COLMAP (newacct_id = account_id, newacct_val = &
@getval (lookup.desc_param));

Oracle以外のデータベースの問合せ:

MAP sales.account, TARGET sales.newacct, &
SQLEXEC (ID lookup, &
QUERY 'select desc_col desc_param from lookup_table where code_col = ?', &
PARAMS (p1 = account_code)), &
COLMAP (newacct_id = account_id, newacct_val = &
@getval (lookup.desc_param));

15.1.6 SQLEXECエラーの処理

SQLEXECを実装する場合に考慮する必要のあるエラー状態には、次の2つのタイプがあります。

  • 列マップで、ソース・データベースの操作から欠落している列が必要とされる場合。これは、データベースで、すべての列の値でなく、変更された列の値だけが記録される場合の更新操作で発生する可能性があります。デフォルトでは、必要な列が欠落している場合、またはOracle GoldenGate列変換関数で列の欠落状態が発生した場合には、ストアド・プロシージャは実行されません。その後、ストアド・プロシージャから出力パラメータを抽出しようとすると、COLMAP句またはFILTER句で列の欠落状態が発生します。

  • データベースでエラーが生成された場合。

15.1.6.1 紛失した列値の処理

@COLTEST関数を使用して、渡されたパラメータの結果をテストし、必要に応じて欠落値を埋めるために列の代替値をマップします。別の方法として、列値を使用できるようにするため、TABLEパラメータのFETCHCOLSオプションまたはFETCHCOLSEXCEPTオプションを使用して、ログに存在しない値をデータベースからフェッチできます。列をフェッチするかわりに、該当する列のサプリメンタル・ロギングを有効化できます。

15.1.6.2 データベース・エラーの処理

SQLEXEC句のERRORオプションを使用して、Oracle GoldenGateに次のいずれかの方法でレスポンスするように指示します。

表15-1 ERRORオプション

アクション 説明
IGNORE

Oracle GoldenGateに、ストアド・プロシージャまたは問合せに関連するすべてのエラーを無視させ、処理を継続させます。どのパラメータ抽出の結果も、列の欠落状態となります。これはデフォルトです。

REPORT

ストアド・プロシージャまたは問合せに関連するすべてのエラーが破棄ファイルにレポートされるようにします。このレポートは、エラーの原因の追跡に役立ちます。ここには、エラーの説明と、プロシージャまたは問合せとやり取りしたパラメータの値の両方が含まれます。Oracle GoldenGateで、エラーのレポート後、処理が続けられます。

RAISE

Replicatのパラメータ・ファイルに指定されたREPERRORパラメータの設定によるルールに従ってエラーを処理します。Oracle GoldenGateは、エラーを処理する前に、現在のTABLE文またはMAPに関連付けられた他のストアド・プロシージャまたは問合せの処理を継続します。

FINAL

実行方法はRAISEとほぼ同じですが、プロシージャまたは問合せに関連付けられたエラーが発生すると、残りのすべてのストアド・プロシージャおよび問合せは省略されます。エラー処理は、エラーの直後にコールされます。

FATAL

プロシージャまたは問合せに関連するエラーを検出したときに、即座にOracle GoldenGateを異常終了させます。

15.1.7 SQLEXECのその他のガイドライン

次のSQLEXECガイドラインに従ってください。

  • TABLEまたはMAPの1つのエントリで、最大20のプロシージャまたは問合せを実行できます。これらは、パラメータ文にリストされている順序で実行されます。

  • SQLEXEC句よりも先に、Oracle GoldenGateユーザーのデータベース・ログイン情報を指定する必要があります。データベース・タイプおよび構成済の認証方式に応じて、Extractパラメータ・ファイルでSOURCEDBと、USERIDまたはUSERIDALIASパラメータの、いずれかまたは両方を使用するか、Replicatパラメータ・ファイルでTARGETDBと、USERIDまたはUSERIDALIASパラメータの、いずれかまたは両方を使用します。

  • SQLは、Oracle GoldenGateユーザーによって実行されます。このユーザーは、ストアド・プロシージャを実行し、RDBM提供のプロシージャをコールする権限を持っている必要があります。

  • ストアド・プロシージャまたは問合せ内のデータベース操作は、元のトランザクションと同じコンテキストでコミットされます。

  • SQLEXECを使用して主キー列の値を更新しないでください。SQLEXECを使用してキー列の値を更新すると、元のキー値が使用できなくなるため、Replicatプロセスで後続の更新操作または削除操作を実行できなくなります。キー値を変更する必要がある場合、元のキー値を別の列にマップして、TABLEパラメータまたはMAPパラメータのKEYCOLSオプションを使用してその列を指定できます。

  • DB2では、Oracle GoldenGateはODBCのSQLExecDirect関数を使用してSQL文を動的に実行します。つまり、接続先のデータベース・サーバーは、文を動的に準備できる必要があります。ODBCは、実行のたびに(リクエストされる間隔で)SQL文を準備します。通常は、このことがOracle GoldenGateユーザーの問題になることはありません。詳細は、IBM DB2のドキュメントを参照してください。

  • SQLEXECは、パススルー・モードのデータ・ポンプExtractによって処理されるオブジェクトに対して使用しないでください。

  • SQLEXEC文中のオブジェクト名はすべて、データベースに応じて、2つまたは3つの部分からなる完全修飾名である必要があります。

  • SQLEXECのストアド・プロシージャまたは問合せの影響を受けるすべてのオブジェクトは、SQLの実行前に適切な構造で存在している必要があります。したがって、これらのオブジェクトの構造に影響するDDL (CREATEALTERなど)は、SQLEXECの実行前に実行される必要があります。

  • 単独SQLEXEC文によって影響を受けるすべてのオブジェクトは、Oracle GoldenGateプロセスの起動前に存在している必要があります。このため、DDLサポートは、これらのオブジェクトに対して無効にする必要があります。そうしないと、SQLEXECのプロシージャまたは問合せが実行される前に、DDL操作によって構造が変更されたり、オブジェクトが削除されたりする可能性があります。

15.2 Oracle GoldenGateマクロを使用した作業の簡略化および自動化

パラメータ・ファイルでOracle GoldenGateマクロを使用すると、パラメータ、コマンドおよび変換関数を構成して再利用できるため、一般的なタスクを実行する際に入力する必要のあるテキストの量を減らすことができます。マクロとは、格納されている処理ステップのセットをOracle GoldenGateパラメータ・ファイルから呼び出すことを可能にする組込みの自動化ツールです。マクロには、頻繁に使用するパラメータ文の単純なセットを含めることも、パラメータ置換、計算または変換が連続する複雑な組合せを含めることもできます。1つのマクロから他のマクロを呼び出すことができます。よく使用するマクロをライブラリに格納すると、個別にマクロを呼び出さずにそのライブラリを呼び出すことができます。

Oracle GoldenGateマクロは、次のパラメータ・ファイルと連携して動作します。

  • DEFGEN

  • Extract

  • Replicat

マクロは、パススルー・モードのデータ・ポンプExtractによって処理される表のデータを操作するために使用しないでください。

マクロの使用は、次の2つのステップで行います。

マクロの定義

マクロの呼出し

内容は次のとおりです。

15.2.1 マクロの定義

Oracle GoldenGateマクロを定義するには、パラメータ・ファイルでMACROパラメータを使用します。MACROでは、必要な入力パラメータを定義し、マクロにより実行する処理を定義します。

構文

MACRO #macro_name
PARAMS (#p1, #p2 [, ...])
BEGIN
macro_body
END;

表15-2 マクロ定義の引数

引数 説明
MACRO

必須。Oracle GoldenGateマクロ定義の開始を指定します。

#macro_name

マクロ名。マクロおよびパラメータ名は、マクロ文字で開始する必要があります。デフォルトのマクロ文字は、番号記号(#)です(#macro1#param1など)。

マクロまたはパラメータ名は、文字や数字(あるいはその両方)を含む1語にできます。アンダースコア文字(_)やハイフン(-)などの特殊文字を使用できます。マクロ名の例として、#mymacro#macro1#macro_1#macro-1#macro$などがあります。パラメータ名の例として、#sourcecol#s#col1#col_1などがあります。

解析エラーを回避するため、マクロ名の最初の文字としてマクロ文字を使用することはできません。たとえば、##macroは無効です。必要な場合、MACROCHARパラメータを使用してマクロ文字を変更できます。Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。

マクロ名とパラメータ名では、大/小文字は区別されません。引用符内のマクロ名またはパラメータ名は、無視されます。

PARAMS (#p1, #p2)

入力パラメータのオプション定義。パラメータ名のカンマ区切りリストを指定して、カッコで囲みます。入力値を置換するマクロ本体で、各パラメータを参照する必要があります。各パラメータを個別の行にリストすると読みやすくなります(必ず開きカッコと閉じカッコを使用してパラメータ・リストを囲んでください)。詳細は、「パラメータを含むマクロの呼出し」を参照してください。

BEGIN

マクロ本文を開始します。マクロ本文の前に指定する必要があります。

macro_body

マクロ本体。本体は、マクロにより実行される関数を定義する構文の文です。マクロ本体には、次のタイプの文を含めることができます。

  • 次のような単純なパラメータ文:

    COL1 = COL2
  • 次のようなパラメータ置換を含む複雑なパラメータ文:

    MAP #o.#t, TARGET #o.#t, KEYCOLS (#k), COLMAP (USEDEFAULTS); 
  • 次のような他のマクロの呼出し:

    #colmap (COL1, #sourcecol)
END;

マクロ定義を終了します。定義の末尾にはセミコロンが必要です。

パラメータを含むマクロ定義の例を次に示します。この場合、マクロでは、所有者、表およびKEYCOLS列の名前に解決される入力パラメータを含むMAP文のベース構文を提供することによって、オブジェクトおよび列のマッピングのタスクを簡略化します。

MACRO #macro1  
PARAMS ( #o, #t, #k )  
BEGIN  
MAP #o.#t, TARGET #o.#t, KEYCOLS (#k), COLMAP (USEDEFAULTS); 
END; 

パラメータを定義していないマクロの例を次に示します。頻繁に使用するパラメータのセットを実行します。

MACRO #option_defaults
BEGIN
GETINSERTS
GETUPDATES
GETDELETES
INSERTDELETES
END;

15.2.2 マクロの呼出し

この項では、マクロの呼出し方法について説明します(マクロを定義するには、「マクロの定義」を参照してください)。

マクロを呼び出すには、パラメータ・ファイル内のマクロの実行場所に次の構文を使用します。

構文

[target =] macro_name (val[, ...])
[target =] macro_name (val | {val, val, ...}[, ...])

表15-3 マクロを呼び出すための構文要素

引数 説明

target =

オプションです。マクロ処理の結果の割当て先またはマップ先のターゲットを指定します。たとえば、targetを使用して、COLMAP文でターゲット列を指定できます。次に示す#make_dateマクロの呼出しでは、列DATECOL1がターゲットであり、マクロ結果にマップされます。

DATECOL1 = #make_date (YR1, MO1, DAY1)

ターゲットがない場合、#make_dateを呼び出すための構文は次のとおりです。

#make_date (YR1, MO1, DAY1)

macro_name

呼び出されるマクロの名前(例: #make_date)。

( val[, ...])

パラメータ入力値。このコンポーネントは、マクロがパラメータを定義しているかどうかにかかわらず必須です。マクロがパラメータを定義している場合、MACROパラメータ内のパラメータ定義に対応する順序で入力値のカンマ区切りリストを指定し、リストをカッコで囲みます。マクロがパラメータを定義していない場合、中に何もない開きカッコと閉じカッコを指定します。この構文の詳細は、次を参照してください。

パラメータを含むマクロの呼出し

入力パラメータのないマクロの呼出し

( val | {val, val, ...} )[, ...]

パラメータ入力値。このコンポーネントは、マクロがパラメータを定義しているかどうかにかかわらず必須です。マクロがパラメータを定義している場合、MACROパラメータ内のパラメータ定義に対応する順序で入力値のカンマ区切りリストを指定し、リストをカッコで囲みます。複数の値を1つのパラメータに渡すには、それらをカンマで区切り、リストを中カッコで囲みます。マクロがパラメータを定義していない場合、中に何もない開きカッコと閉じカッコを指定します。この構文の詳細は、次を参照してください。

パラメータを含むマクロの呼出し

入力パラメータのないマクロの呼出し

15.2.2.1 パラメータを含むマクロの呼出し

パラメータを含むマクロを呼び出すには、call文で、マクロの実行時にこれらのパラメータを置換する入力値を指定する必要があります。表15-3の構文を参照してください。

マクロ・パラメータの有効な入力は、マクロ文字(デフォルトは#)で始まる次のいずれかです。

  • プレーン・テキストまたは引用テキストの単一値(#macro (#name, #address, #phone)#macro (#"name", #"address", #"phone")など)。

  • 中カッコで囲まれたカンマ区切りの値リスト(#macro1 (SCOTT, DEPT, {DEPTNO1, DEPTNO2, DEPTNO3})など)。指定されたパラメータの値のブロックを置換できるようにすると、マクロ定義とOracle GoldenGate構成のユーザビリティの柔軟性が向上します。

  • 他のマクロの呼出し(#macro (#mycalc (col2, 100), #total)など)。この例では、入力値がcol2および100#mycalcマクロが呼び出されます。

Oracle GoldenGateでは、次のルールに従ってマクロ本体のパラメータ値が置換されます。

  1. マクロ・プロセッサは、マクロ本体を読み取って、PARAMS文に指定されたパラメータ名のインスタンスを検索します。

  2. パラメータ名が出現するたびに、呼出し時に指定された対応するパラメータ値が置換されます。

  3. パラメータ名がPARAMS文に出現しない場合、マクロ・プロセッサは、その項目が別のマクロの呼出しになっているかどうかを評価します。(「マクロからの他のマクロの呼出し」を参照)。呼出しが成功した場合、ネストされたマクロが実行されます。失敗した場合、マクロ全体が失敗します。

例15-3 パラメータを使用したMAP文の移入

次のマクロ定義は、解決が必要な3つのパラメータを指定しています。これらのパラメータは、MAP文の表所有者名(パラメータ#o)、表名(パラメータ#t)およびKEYCOLS列名(パラメータ#k)を置換します。

MACRO #macro1  PARAMS ( #o, #t, #k )  BEGIN  MAP #o.#t, TARGET #o.#t, KEYCOLS (#k), COLMAP (USEDEFAULTS); END; 

MAP文の表にKEYCOLS列が1つのみ必要である場合、次の構文を使用して#macro1を呼び出すことができます。この構文では、1つのみの値で#kパラメータを解決できます。

#macro1 (SCOTT, DEPT, DEPTNO1)

2つのKEYCOLS列が必要な表のマクロを呼び出すには、次のように中括弧を使用して、列名に必要な両方の値を囲みます。

#macro1 (SCOTT, DEPT, {DEPTNO1, DEPTNO2})

DEPTNO1値およびDEPTNO2値は、#tパラメータを解決するための1つの引数として渡されます。この方法で、中括弧の内側に追加の値を使用して、3つ以上のKEYCOLSのある表を処理できます。

例15-4 マクロを使用した変換の実行

この例では、マクロで#year#monthおよび#dayの各パラメータを定義して、独自仕様の日付書式を変換します。

MACRO #make_date
PARAMS (#year, #month, #day)
BEGIN
@DATE ('YYYY-MM-DD', 'CC', @IF (#year < 50, 20, 19), 'YY', #year, 'MM', #month, 'DD', #day)
END;

マクロはCOLMAP句で呼び出されます。

MAP sales.acct_tab, TARGET sales.account,
COLMAP
(
targcol1 = sourcecol1,
datecol1 = #make_date(YR1, MO1, DAY1),
datecol2 = #make_date(YR2, MO2, DAY2)
);

マクロは次のように展開されます。

MAP sales.acct_tab, TARGET sales.account,
COLMAP
(
targcol1 = sourcecol1,
datecol1 = @DATE ('YYYY-MM-DD', 'CC', @IF (YR1 < 50, 20, 19),'YY', YR1, 'MM', MO1, 'DD', DAY1),
datecol2 = @DATE ('YYYY-MM-DD', 'CC', @IF (YR2 < 50, 20, 19),'YY', YR2, 'MM', MO2, 'DD', DAY2)
);
15.2.2.2 入力パラメータのないマクロの呼出し

入力パラメータのないマクロを呼び出すには、call文で入力値のない開きカッコと閉じカッコ(#macro ())を指定します。

次のマクロは、入力パラメータなしで定義されています。本体には頻繁に使用するパラメータが含まれています。

MACRO #option_defaults
BEGIN
GETINSERTS
GETUPDATES
GETDELETES
INSERTDELETES
END;

このマクロは次のように呼び出されます。

#option_defaults ()
IGNOREUPDATES
MAP owner.srctab, TARGET owner.targtab;

#option_defaults ()
MAP owner.srctab2, TARGET owner.targtab2;

マクロは次のように展開されます。

GETINSERTS
GETUPDATES
GETDELETES
INSERTDELETES
IGNOREUPDATES
MAP owner.srctab, TARGET owner.targtab;

GETINSERTS
GETUPDATES
GETDELETES
INSERTDELETES
MAP owner.srctab2, TARGET owner.targtab2;

15.2.3 マクロからの他のマクロの呼出し

マクロから他のマクロを呼び出すには、次のようなマクロ定義を作成します。この例では、#make_dateマクロが#assign_dateマクロ内にネストされ、#assign_dateの実行時に呼び出されます。

ネストされたマクロは、ベース・マクロに定義された同じパラメータの全部またはサブセットを定義している必要があります。つまり、ベース・マクロの呼出し時の入力値が両方のマクロのパラメータに解決される必要があります。

次では、#assign_dateを定義しています。

MACRO #assign_date
PARAMS (#target_col, #year, #month, #day)
BEGIN
#target_col = #make_date (#year, #month, #day)
END;

次では、#make_dateを定義しています。このマクロでは、2桁の入力日付の前に世紀値(19または20)を付ける必要があるかどうかを最初に判別した後、4桁の年を含む日付書式を作成します。#make_datePARAMS文には、#assign_dateマクロ内のパラメータのサブセットが含まれています。

MACRO #make_date
PARAMS (#year, #month, #day)
BEGIN
@DATE ('YYYY-MM-DD', 'CC', @IF (#year < 50, 20, 19), 'YY', #year, 'MM', #month, 'DD', #day)
END;

次の構文は#assign_dateを呼び出します。

#assign_date (COL1, YEAR, MONTH, DAY)

前の入力値および埋込み#make_dateマクロを想定すると、マクロは次のように展開されます。

COL1 = @DATE ('YYYY-MM-DD', 'CC', @IF (YEAR < 50, 20, 19),'YY', YEAR, 'MM', MONTH, 'DD', DAY)

15.2.4 マクロ・ライブラリの作成

1つ以上のマクロを含むマクロ・ライブラリを作成できます。マクロ・ライブラリを使用すると、マクロを1回定義するだけで、そのマクロを多くのパラメータ・ファイルで使用できます。

マクロ・ライブラリを作成する手順

  1. テキスト・エディタで新規ファイルを開きます。

  2. 必要に応じて、コメント行を使用してライブラリを説明します。

  3. 「マクロの定義」に記載されている構文を使用して、各マクロの構文を入力します。

  4. ファイルを次の形式でOracle GoldenGateディレクトリのdirprmサブディレクトリに保存します。

    filename.mac
    

    説明:

    filenameは、ファイルの名前です。.mac拡張子によって、ファイルをマクロ・ライブラリとして定義します。

次のdatelibというサンプル・ライブラリには、#make_dateおよび#assign_dateという2つのマクロが含まれます。

-- datelib macro library
--
MACRO #make_date
PARAMS (#year, #month, #day)
BEGIN
@DATE ('YYYY-MM-DD', 'CC', @IF (#year < 50, 20, 19), 'YY', #year, 'MM', #month, 'DD', #day)
END;

MACRO #assign_date
PARAMS (#target_col, #year, #month, #day)
BEGIN
#target_col = #make_date (#year, #month, #day)
END;

マクロ・ライブラリを使用するには、パラメータ・ファイルの先頭でINCLUDEパラメータを使用します。次のサンプルのReplicatパラメータ・ファイルを参照してください。

INCLUDE /ggs/dirprm/datelib.mac
REPLICAT rep
ASSUMETARGETDEFS
USERIDALIAS ogg
MAP fin.acct_tab, TARGET fin.account;

パラメータ・ファイルに長いマクロ・ライブラリが含まれる場合、NOLISTパラメータを使用して、ExtractまたはReplicatのレポート・ファイルで各マクロがリスト表示されることを抑止できます。リスト表示の有効化と無効化を切り替えるには、パラメータ・ファイル内またはマクロ・ライブラリ・ファイル内の任意の場所にLISTパラメータおよびNOLISTパラメータを配置します。次の例では、NOLISTによって、hugelibマクロ・ライブラリに含まれる各マクロのリスト表示を抑止します。INCLUDE文の後にLISTを指定することで、レポート・ファイルを通常のリスト表示に戻します。

NOLIST
INCLUDE /ggs/dirprm/hugelib.mac
LIST
INCLUDE /ggs/dirprm/mdatelib.mac
REPLICAT REP

15.2.5 マクロ展開のトレース

CMDTRACEパラメータを使用して、マクロ展開をトレースできます。CMDTRACEを有効化すると、マクロ展開ステップがExtractまたはReplicatのレポート・ファイルに表示されます。

構文

CMDTRACE [ON | OFF | DETAIL]

説明:

  • ONは、トレースを有効化します。

  • OFFは、トレースを無効化します。

  • DETAILは、マクロ展開の詳細表示を生成します。

次の例では、トレースが#testmacの呼出し前に有効化され、マクロの実行後に無効化されます。

REPLICAT REP
MACRO #testmac
BEGIN
COL1 = COL2,
COL3 = COL4,
END;
...
CMDTRACE ON
MAP test.table1, TARGET test.table2,
COLMAP (#testmac);
CMDTRACE OFF

15.3 ユーザー・イグジットを使用したOracle GoldenGate機能の拡張

ユーザー・イグジットは、Cプログラミング・コードで記述してExtractまたはReplicatの処理中にコールするカスタム・ルーチンです。ユーザー・イグジットによって、複雑さとリスクを最小限に抑えながらExtractプロセスとReplicatプロセスの機能を拡張およびカスタマイズできます。ユーザー・イグジットの使用により、本番プログラムを変更することなく、データベース・イベントの発生時にレスポンスすることができます。

内容は次のとおりです。

15.3.1 ユーザー・イグジットを実装する場合

ユーザー・イグジットは、Oracle GoldenGate内で使用できる列変換関数のかわりとして、またはそれらと組み合せて使用できます。ユーザー・イグジットは、データを2回(データの抽出時に1回と変換の実行時に1回)処理するかわりに、データの抽出時に1回のみ処理するため、組込み関数の代用として適しています。

ユーザー・イグジットは次の用途で実装できます。

  • ある表から別の表へのマップ時における算術演算、データ変換または表検索の実行。

  • レコード・アーカイブ関数のオフライン実装。

  • 通常とは異なるデータベース・イベントに対するカスタム形式でのレスポンス(出力値に基づいて電子メール・メッセージまたは通知を送信するなど)。

  • 合計値の蓄積および統計値の収集。

  • レコードの操作。

  • 無効なデータの修復。

  • 更新前後のレコードにおける正味の差異の計算。

  • 複雑な基準に基づいた抽出またはレプリケーションのためのレコードの受入れまたは拒否。

  • 変換時のデータベースの正規化。

15.3.2 Oracle GoldenGateレコード情報のルーチンへの使用可能化

ほとんどのユーザー・イグジット処理の基本となるのがEXIT_CALL_PROCESS_RECORD関数です。Extractでは、この関数はレコード・バッファが証跡に出力される直前にコールされます。Replicatでは、これはレコードがターゲットに適用される直前にコールされます。パラメータ・ファイルにソースとターゲットのマッピングが指定されている場合、EXIT_CALL_PROCESS_RECORDイベントはマッピングの実行後に発生します。

EXIT_CALL_PROCESS_RECORDがコールされると、コールバック・ルーチンを通じて、レコード・バッファとその他のレコード情報が利用可能になります。ユーザー・イグジットは、マッピング、変換、クリーンアップ、その他すべての操作をデータ・レコードに対して実行できます。操作が完了したら、ユーザー・イグジットは、ExtractまたはReplicatによってレコードを処理するのか、無視するのかを示すステータスを戻すことができます。

15.3.3 ユーザー・イグジットの作成

次の内容は、WindowsおよびUNIXシステムでユーザー・イグジットを作成する場合に役立ちます。それらの説明に記載されているパラメータや関数の詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。

ノート:

ユーザー・イグジットは、データベース・オブジェクト名の大/小文字を区別します。名前は、ホスト・データベースで定義されたとおりに戻されます。オブジェクト名は完全修飾名である必要があります。

ユーザー・イグジットを作成する手順

  1. Cコードで、共有オブジェクト(UNIXシステム)またはDLL(Windows)を作成し、ExtractまたはReplicatからコールするルーチンを作成またはエクスポートします。このルーチンは、Oracle GoldenGateとユーザー独自のルーチン間の通信ポイントになります。このルーチンに任意の名前を付けます。ルーチンでは、次のOracle GoldenGateユーザー・イグジット・パラメータを受け入れる必要があります。

    • EXIT_CALL_TYPE: 処理中にいつルーチンをコールするかを指定します。

    • EXIT_CALL_RESULT: ルーチンにレスポンスを提供します。

    • EXIT_PARAMS: ルーチンに情報を提供します。この関数を使用すると、TABLE文またはMAP文のEXITPARAMオプションを使用して、リテラル文字列のパラメータをユーザー・イグジットに渡すことができます。これは、特定のレコードを処理するイグジット・コール中にのみ有効です。この関数を使用すると、イグジット・コール起動時にCUSEREXITパラメータのPARAMSオプションで指定されたパラメータを渡すこともできます。

  2. ソース・コードで、usrdecs.hファイルをインクルードします。usrdecs.hファイルは、ユーザー・イグジットAPI用のインクルード・ファイルです。型定義、戻りステータス値、コールバック関数コード、および多数の他の定義が含まれます。usrdecs.hファイルは、Oracle GoldenGateディレクトリ内にインストールされます。このファイルは変更しないでください。

  3. 必要に応じてOracle GoldenGateコールバック・ルーチンをユーザー・イグジットに含めます。コールバック・ルーチンは、レコードおよびアプリケーション・コンテキスト情報を取得して、データ・レコードの内容を変更します。コールバック・ルーチンを実装するには、共有オブジェクトでERCALLBACK関数を使用します。ユーザー・コールバック・ルーチンは、コールバック・ルーチンに渡される関数コードに基づいて異なる動作をします。

    ERCALLBACK (function_code, buffer, result_code);
    

    説明:

    • function_codeは、コールバック・ルーチンによって実行される関数です。

    • bufferは、指定した関数コードに関連付けられた事前定義構造を含むバッファへのvoidポインタです。

    • result_codeは、コールバック・ルーチンによって実行される関数のステータスです。コールバック・ルーチンによって戻される結果コードは、コールバック関数が成功したかどうかを示します。

    • Windowsシステムでは、ExtractおよびReplicatによって、ユーザー・イグジット・ルーチンからコールされるERCALLBACK関数がエクスポートされます。ユーザー・イグジットでは、適切なWindows APIコールを使用して実行時にコールバック関数を明示的にロードする必要があります。

  4. ExtractまたはReplicatのパラメータ・ファイルにCUSEREXITパラメータを含めます。このパラメータでは、共有オブジェクトまたはDLLの名前と、ExtractまたはReplicatからコールされるエクスポート・ルーチンの名前を使用します。共有オブジェクトまたはDLLのフルパスを指定するか、オペレーティング・システムの標準検索機能を使用して共有オブジェクトの場所を特定できます。

    CUSEREXIT {DLL | shared_object} routine
    [, INCLUDEUPDATEBEFORES]
    [, PARAMS 'startup_string']
    

    説明:

    • DLLはWindows DLLで、shared_objectはユーザー・イグジット関数を含むUNIX共有オブジェクトです。

    • INCLUDEUPDATEBEFORESは、UPDATE操作のために変更前イメージを取得します。

    • PARAMS 'startup_string'は、起動文字列(起動パラメータなど)を指定します。

例15-5 ベース構文の例(UNIX)

CUSEREXIT eruserexit.so MyUserExit

例15-6 ベース構文の例(Windows)

CUSEREXIT eruserexit.dll MyUserExit

15.3.4 ユーザー・イグジットでの文字セット変換のサポート

データ整合性を保つには、ユーザー・イグジットで、Oracle GoldenGateプロセスと交換する文字型データの文字セットを認識する必要があります。Oracle GoldenGateユーザー・イグジットのロジックでは、次のものに対するグローバリゼーション・サポートが提供されます。

  • 文字ベースのデータベース・メタデータ(カタログ、スキーマ、表および列の名前など)

  • 文字型の列(CHARVARCHAR2CLOBNCHARNVARCHAR2NCLOBなど)の値や文字列ベースの数値、日時および期間

文字セット間での適切な変換によって、列データの比較、操作、変換およびあるタイプのデータベースと文字セットから別のものへの適切なマップが可能になります。この処理の大半は、EXIT_CALL_PROCESS_RECORDコール・タイプがコールされると実行され、レコード・バッファと他のレコード情報がコールバック・ルーチンを介して使用可能になります。

ユーザー・イグジットは独自のセッション文字セットを持ちます。これは、GET_SESSION_CHARSETおよびSET_SESSION_CHARSETコールバック関数によって定義されます。ユーザー・イグジットの文字セットがプロセスのホスト・コンテキストと異なる場合、コール元のプロセスで文字セット間の変換が行われます。

ユーザー・イグジットでこのサポートを有効にするために、GET_DATABASE_METADATAコールバック関数コードがあります。この関数によって、ユーザー・イグジットは、ロケールやコール元プロセス(Extract、データ・ポンプ、Replicat)と交換する文字型データの文字セットなどのデータベース・メタデータを取得できます。データベースでのオブジェクト名の大/小文字の区別、引用符付きおよび引用符なしの名前の処理およびオブジェクト名の格納方法も返されます。

これらのコンポーネントの詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。

15.3.5 名前のメタデータをチェックするマクロの使用

ユーザー・イグジットAPIによって渡されるオブジェクト名は、ユーザー・イグジット・セッション文字セットでエンコードされた正確な名前で、データベースから取得されたものと完全に同じ名前です。ユーザー・イグジットでオブジェクト名をリテラル文字列と比較する場合、ユーザー・イグジットでデータベースのロケールを取得し、文字列を正規化して同じエンコーディングでオブジェクト名と比較できるようにする必要があります。

Oracle GoldenGateには、ユーザー・イグジットでコールし、データベース・オブジェクト名のメタデータをチェックできる次のマクロが用意されています。たとえば、マクロを使用して、引用符で囲まれた名前で大/小文字が区別されるかどうかや、大/小文字混在でデータベース・サーバーに格納されているかどうかをチェックできます。これらのマクロは、usrdecs.hファイルで定義されています。

表15-4 メタデータ・チェック用のマクロ

マクロ 確認の対象

supportsMixedCaseIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれていない、指定されたデータ型の名前を、データベースが大/小文字を区別して処理し、大/小文字混在で格納するかどうか。

supportsMixedCaseQuotedIdentifiers( nameMeta, DBObjType )

大/小文字混在で引用符で囲まれた、指定されたデータ型の名前を、データベースが大/小文字を区別して処理し、大/小文字混在で格納するかどうか。

storesLowerCaseIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれていない、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、小文字で格納するかどうか。

storesLowerCaseQuotedIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれた、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、小文字で格納するかどうか。

storesMixedCaseIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれていない、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、大/小文字混在で格納するかどうか。

storesMixedCaseQuotedIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれた、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、大/小文字混在で格納するかどうか。

storesUpperCaseIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれていない、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、大文字で格納するかどうか。

storesUpperCaseQuotedIdentifiers( nameMeta, DbObjType )

大/小文字混在で引用符で囲まれた、指定されたデータ型の名前を、データベースが大/小文字を区別せずに処理し、大文字で格納するかどうか。

15.3.6 文字形式の説明

入力パラメータcolumn_value_modeは、処理されるデータの文字形式を表し、いくつかの関数コードで使用されます。次の表では、EXIT_FN_RAW_FORMATEXIT_FN_CHAR_FORMATおよびEXIT_FN_CNVTED_SESS_FORMAT形式コードの意味を、データ型ごとに説明します。

表15-5 column_value_mode_matrixの意味

データ型 EXIT_FN_RAW_FORMAT EXIT_FN_CHAR_FORMAT EXIT_FN_CNVTED_SESS_FORMAT

CHAR

"abc"

2バイトNULLインジケータ +

2バイトの長さ情報

+ 列値

0000 0004 61 62 63 20

ASCIIまたはEBCDICでエンコードされた"abc"。

NULL終端。

末尾の空白は切り捨てられます。

ユーザー・イグジット・セッションの文字セットでエンコードされた"abc"。

NOT NULL終端。

GLOBALSパラメータのNOTRIMSPACESが指定されていない場合、デフォルトで末尾の空白は切り捨てられます。

NCHAR

0061 0062 0063 0020

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値。

0000 0008 00 61 0062 0063 0020

NCHARがUTF-8として処理されるかどうかに応じて、"abc" (UTF8でエンコード)または最初のバイトで切捨て。

NULL終端。

末尾の空白は切り捨てられます。

ユーザー・イグジット・セッションの文字セットでエンコードされた"abc"。

NOT NULL終端。

GLOBALSパラメータのNOTRIMSPACESが指定されていない場合、デフォルトで末尾の空白は切り捨てられます。

VARCHAR2

"abc"

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

ASCIIまたはEBCDICでエンコードされた"abc"。

NULL終端。

切捨てなし。

ユーザー・イグジット・セッションの文字セットでエンコードされた"abc"。

NOT NULL終端。

切捨てなし。

NVARCHAR2

0061 0062 0063 0020

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

NVARCHAR2UTF-8として処理されるかどうかに応じて、"abc" (UTF8でエンコード)または最初のバイトで切捨て。

NULL終端。

切捨てなし。

ユーザー・イグジット・セッションの文字セットでエンコードされた"abc"。

NOT NULL終端。

切捨てなし。

CLOB

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

VARCHAR2と同様ですが、最大4Kバイトのみの出力。

NULL終端。

切捨てなし。

VARCHAR2と同様ですが、ユーザー・イグジット・セッションの文字セットでリクエストされたデータのみ出力。

NOT NULL終端。

切捨てなし。

NCLOB

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

NVARCHAR2と同様ですが、最大4Kバイトのみの出力。

NULL終端。

切捨てなし。

NVARCHAR2と同様ですが、ユーザー・イグジット・セッションの文字セットでリクエストされたデータのみ出力。

NOT NULL終端。

切捨てなし。

NUMBER

123.89

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

ASCIIまたはEBCDICでエンコードされた"123.89"。

NULL終端。

ユーザー・イグジット・セッションの文字セットでエンコードされた"123.89"。

NOT NULL終端。

DATE

31-May-11

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

ASCIIまたはEBCDICでエンコードされた"2011-05-31"。

NULL終端。

ユーザー・イグジット・セッションの文字セットでエンコードされた"2011-05-31"。

NOT NULL終端。

TIMESTAMP

31-May-11 12.00.00 AM

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

ASCIIまたはEBCDICでエンコードされた"2011-05-31 12.00.00 AM"。

NULL終端。

ユーザー・イグジット・セッションの文字セットでエンコードされた"2011-05-31 12.00.00 AM"。

NOT NULL終端。

Interval Year to MonthまたはInterval Day to Second

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

NA

NA

RAW

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

2バイトNULLインジケータ +

2バイトの長さ情報 +

列値

15.3.7 ユーザー・イグジットのアップグレード

usrdecs.hファイルは、新しい機能や構造変更などの拡張またはアップグレードがOracle GoldenGateの新規リリースに追加された場合に、既存のユーザー・イグジットとの下位互換性に対応するためにバージョンが付けられています。usrdecs.hファイルのバージョンは、ReplicatまたはExtractの起動時にレポート・ファイルに出力されます。

ユーザー・イグジットの新しい機能を使用するには、独自のルーチンを再コンパイルして新しいusrdecsファイルをインクルードする必要があります。新しい機能を使用しないルーチンは、再コンパイルする必要はありません。

15.3.8 ユーザー・イグジット関数を使用する方法のサンプルの表示

Oracle GoldenGateでは、Oracle GoldenGateのインストール・ディレクトリのUserExitExamplesディレクトリに次のサンプル・ユーザー・イグジット・ファイルがインストールされます。

  • exitdemo.cは、ユーザー・イグジットを初期化し、特定のイグジット・ポイントでコールバックを発行して、データを変更する方法を示しています。また、完全修飾の表名または特定のメタデータ部(カタログやコンテナの名前、スキーマ、または修飾されていない表名など)の取得方法も示しています。さらに、このデモはDDLデータがどのように処理されるかも示しています。このデモは、データベース・タイプに固有ではありません。

  • exitdemo_utf16.cは、ユーザー・イグジットとコール元プロセスの間で交換される情報のコールバック構造で、UTF16エンコードのデータ(メタデータと列データの両方)を使用する方法を示しています。

  • exitdemo_more_recs.cは、同じ入力レコードを複数回使用して複数のターゲット・レコードを生成する方法の例を示しています。

  • exitdemo_lob.cは、LOBデータに対する読取りアクセスを取得する方法の例を示しています。

  • exitdemo_pk_befores.cは、主キーの更新レコードの変更前および変更後イメージの一部と、通常の更新(キー以外の更新)の変更前イメージにアクセスする方法を示しています。また、競合検出の手段として、Replicatパラメータ・ファイルのSQLEXECを使用してターゲット行の値を取得する方法も示しています。ターゲットからフェッチされた値は、ユーザー・イグジットに取得された時点でターゲット・レコードとしてマップされます。

各ディレクトリには、.cファイルに加え、makefileおよびreadme.txtファイルが含まれます。

15.4 イベント・マーカー・システムを使用したデータベース・イベントの起動

Oracle GoldenGateでは、Oracle GoldenGateプロセスによって、(プロセスのデータソースに応じて)トランザクション・ログまたは証跡のイベント・レコードに基づいて定義済のアクションを実行できるイベント・マーカー・システムが提供されます。これはイベント・マーカー・インフラストラクチャ(EMI)とも呼ばれます。イベント・レコードは、アクションを実行するための特定のフィルタ基準に適合するレコードです。このシステムを使用して、データベース・イベントに基づいてOracle GoldenGate処理をカスタマイズできます。

たとえば、イベント・マーカー・システムを使用して、プロセスの起動、一時停止または停止、変換の実行、統計のレポートを行うことができます。イベント・マーカー・システムは、次の目的でも使用できます。

  • SQLEXECまたはユーザー・イグジット関数を実行できる同期ポイントを確立する

  • データ検証スクリプトを実行するか電子メールを送信するシェル・コマンドを実行する

  • 特定のアカウント番号が検出されたときにトレースを有効化する

  • ラグ履歴を取得する

  • 1日の終わりにレポートまたはバッチ・プロセスを実行するプロセスを停止または一時停止する

イベント・マーカー機能は、データ変更のレプリケーションではサポートされていますが、初期ロードではサポートされていません。

このシステムは、次の入力コンポーネントを必要とします。

  1. アクションを起動するイベント・レコードを、TABLE文またはMAP文のFILTERWHEREまたはSQLEXECで指定できます。あるいは、Replicatパラメータ・ファイルに特別なTABLE文を指定すると、ソース表をターゲット表にマップせずにEVENTACTIONSアクションを実行できます。

  2. イベント・レコードを指定するTABLE文またはMAP文に、プロセスで実行されるアクションを指定する適切なオプションとともにEVENTACTIONSパラメータを指定します。

EVENTACTIONSのオプションは、次の例に示すように組み合せることができます。

次の例では、プロセスでチェックポイントを発行し、情報メッセージを記録し、トランザクション全体を無視して(何も処理されません)、レポートを生成します。

EVENTACTIONS (CP BEFORE, REPORT, LOG, IGNORE TRANSACTION)

次の例では、破棄ファイルにイベント・レコードを書き込み、トランザクション全体を無視します。

EVENTACTIONS (DISCARD, IGNORE TRANS)

次の例では、情報メッセージを記録し、プロセスを正常に停止します。

EVENTACTIONS (LOG INFO, STOP)

次の例では、証跡ファイルをロールオーバーし、新規ファイルにイベント・レコードを書き込みません。

EVENTACTIONS (ROLLOVER, IGNORE)

構文の詳細や、その他の使用方法の詳細は、『Oracle GoldenGateリファレンス』を参照してください。

15.4.1 イベント・マーカー・システムの使用方法のケース・スタディ

次の各例では、イベント・マーカー・システムの使用方法に重点を置いて説明します。

内容は次のとおりです。

15.4.1.1 日次処理の起動

この例では、ソース・データベースのevent_tableという特別な表に実行される操作の取得を指定します。この表は、決められた時刻(毎日午後5:00など)に挿入操作を受信するためにのみ存在します。Replicatは、この操作のトランザクション・レコードを受信すると、オペレータが日次処理ジョブを開始できるように正常に停止します。毎日event_table表に対して行われる挿入を使用することで、オペレータは、Replicatによって5:00までのすべてのコミット済トランザクションが適用されたことを確認します。IGNOREによって、Replicatは、ターゲット・データベースでの用途がないイベント・レコード自体を無視します。LOG INFOによって、Replicatは、操作に関する情報メッセージを記録します。

TABLE source.event_table, EVENTACTIONS (IGNORE, LOG INFO, STOP);
15.4.1.2 初期ロードから変更同期への移行の簡略化

イベント・アクションおよびイベント表を使用して、初期ロードから進行中の変更レプリケーションへの移行を支援できます。たとえば、データが移入された既存のソース表をOracle GoldenGate構成に追加する必要があるとします。この表をターゲットに作成してから、エクスポートおよびインポートを使用して2つの表を同期する必要があります。この例では、source.event_tableというイベント表がソース・データベースに存在しており、ReplicatのTABLE文で指定されると仮定します。

TABLE source.event_table, EVENTACTIONS (IGNORE, LOG INFO, STOP);

ユーザーが新しいソース表で作業を継続できるように、そのソース表をReplicatのパラメータ・ファイルではなくExtractのパラメータ・ファイルに追加します。Extractは、この表から証跡へのデータの取得を開始し、データは証跡に格納されます。

エクスポート後にソースとターゲットの読取り一貫性が確保された時点で、ソースのイベント表にイベント・レコードが挿入され、その内容がターゲットに伝播されます。Replicatが(読取り一貫性ポイントを示す)イベント・レコードを受信すると、プロセスは、EVENTACTIONS STOPの指示に従って停止します。これにより、新規表がReplicatのMAP文に追加されます。Replicatは、イベント・レコードのタイムスタンプからレプリケーションを開始するように設定できるため、HANDLECOLLISIONSパラメータを使用する必要がなくなります。証跡内の操作のうちイベント・レコードより前のものは、エクスポートで適用されていることが確認されているため、無視できます。

イベント・レコード自体はReplicatによって無視されますが、情報メッセージが記録されます。

15.4.1.3 データ異常値が検出された場合の処理の停止

この例では、ABORTを使用して、銀行レコードで異常値が検出された場合(顧客が口座残高より多くの現金を引き出そうとした場合)、致命的エラーとともにReplicatを即座に終了します。この場合、ソース表は、ターゲットに対する実際のレプリケーションを目的とするReplicatのMAP文でターゲット表にマップされます。ソース表にはTABLE文も使用され、ABORTアクションによって、Replicatは異常値をターゲット・データベースに適用する前に停止されます。ABORTは、レコードの処理に優先します。

MAP source.account, TARGET target.account;
TABLE source.account, FILTER (withdrawal > balance), EVENTACTIONS (ABORT);
15.4.1.4 特定の注文番号のトレース

次の例では、特定の注文番号(order_no = 1)に対する挿入操作を含む注文トランザクションのみを対象にReplicatのトレースを有効化します。トレース情報は、order_1.trcトレース・ファイルに書き込まれます。MAPパラメータでは、ソース表とターゲット表のマッピングを指定します。

MAP sales.order, TARGET rpt.order;
TABLE source.order,
FILTER (@GETENV ('GGHEADER', 'OPTYPE') = 'INSERT' AND order_no = 1), &
EVENTACTIONS (TRACE order_1.trc TRANSACTION);
15.4.1.5 バッチ・プロセスの実行

この例では、バッチ・プロセスを1か月に1回実行して、ソース・データベースから蓄積されたデータを消去します。トランザクション(通常はバッチ・トランザクション)の開始時に、レコードが特別なjob表に書き込まれ、バッチ・ジョブが開始したことが示されます。ターゲット・システムには削除されたレコードを反映する必要がないため、TRANSACTIONIGNOREとともに使用して、トランザクション全体をExtractで無視するように指定します。Extract側の作業を無視することで、不要な証跡およびネットワーク・オーバーヘッドが排除されます。

TABLE source.job, FILTER (@streq (job_type = 'HOUSEKEEPING')=1), &
EVENTACTIONS (IGNORE TRANSACTION);

ノート:

論理バッチ削除が複数のより小さいバッチで構成される場合、それらのより小さいバッチごとに、トランザクションの最初のレコードとしてジョブ表に挿入する操作が必要です。

15.4.1.6 結果となる操作を除くSQL文のみの伝播

この例では、ソースとターゲットで異なるEVENTACTIONS句を組み合せて使用し、SQL文の結果となる操作ではなく、そのSQL文のみをレプリケートする方法を示します。この例では、INSERT INTO...SELECTトランザクションです。このようなトランザクションでは、伝播する必要のある大量の行が生成される可能性がありますが、この方法であれば、初期SQL文のみが伝播されるため、証跡およびネットワーク・オーバーヘッドを削減できます。各SELECT文は、すべてターゲットに対して実行されます。この構成では、データ整合性を保持するためにソース表とターゲット表を完全に同期する必要があります。

Extract:

TABLE source.statement, EVENTACTIONS (IGNORE TRANS INCLUDEEVENT);

Replicat:

TABLE source.statement, SQLEXEC (execute SQL statement), &
EVENTACTIONS (INFO, IGNORE);

この構成を使用するため、statement表にトランザクションの最初の操作(イベント・レコードとなるINSERT INTO...SELECT)を移入します。

ノート:

サイズの大きいSQL文の場合、文を表の複数の列に書き込むことができます。たとえば、8つのVARCHAR (4000)列を使用して、最大32KBの長さのSQL文を格納できます。

IGNORE TRANS INCLUDEEVENTがあるため、Extractでは、文のSELECT部分に関連する後続の挿入はすべて無視されますが、SQLテキストを含むイベント・レコードは証跡に書き込まれます。TABLE文の使用により、Replicatは、必要に応じてSQLテキスト列を連結するSQLEXEC文にイベント・レコードを渡し、SELECT副問合せの入力としてターゲット表を使用してINSERT INTO...SELECT文を実行します。

15.4.1.7 長時間実行トランザクション開始前の他のトランザクションのコミット

このEVENTACTIONSの使用によって、Replicatで処理されているすべてのオープン・トランザクションが、長時間実行トランザクションの開始前にターゲットにコミットされることが保証されます。この場合、Replicatによって、大規模トランザクションの作業開始前に強制的にチェックポイントが書き込まれます。チェックポイントを強制することで、リカバリの対象を長時間実行トランザクションのみに制限します。Replicatのチェックポイントは暗黙的にはデータベースに対するコミットであるため、未処理のロックが解放され、保留中の変更を他のセッションで認識できるようになります。

TABLE source.batch_table, EVENTACTIONS (CHECKPOINT BEFORE);
15.4.1.8 データ検証のためのシェル・スクリプトの実行

この例では、シェル・スクリプトを実行して、Replicatがテスト実行の最後のトランザクションを適用した後にデータ検証を行う別のスクリプトを実行します。ソースでは、イベント・レコードがsource.eventというイベント表に書き込まれます。レコードによって、値COMPAREがイベント表のevent_type列に挿入されます。このレコードは、他のテスト・データの最後にレプリケートされます。Replicatパラメータ・ファイルのTABLE文で、FILTER句によってレコードを限定し、EVENTACTIONS句のSHELLの指定によってシェル・スクリプトcompare_db.shをトリガーします。その後、FORCESTOPの指定によってReplicatは即座に停止します。

Extract:

TABLE src.*;
TABLE test.event;

Replicat:

MAP src.*, TARGET targ.*;
MAP test.event, TARGET test.event, FILTER (@streq (event_type, 'COMPARE')=1), &
EVENTACTIONS (SHELL 'compare_db.sh', FORCESTOP);