17 Oracle Streams情報コンシュームの管理
適用プロセスは、Oracle Streams環境で暗黙的に情報をコンシュームします。論理変更レコード(LCR)およびユーザー・メッセージを特定のキューからデキューして、各メッセージを直接適用するか、パラメータとしてユーザー定義プロシージャに渡します。
次の各項では、Oracle Streamsの適用プロセスの管理について説明します。
この章で説明する各タスクは、特に明記されていないかぎり、適切な権限を付与されているOracle Streams管理者が完了する必要があります。
関連項目:
-
Oracle Streams管理者を作成する方法の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
-
Oracle Enterprise Manager Cloud Controlでの適用プロセスの管理については、Oracle Enterprise Manager Cloud Controlのオンライン・ヘルプを参照
17.1 適用プロセスの起動
既存の適用プロセスを起動するには、DBMS_APPLY_ADM
パッケージのSTART_APPLY
プロシージャを実行します。たとえば、次のプロシージャでは適用プロセスstrm01_apply
が起動されます。
BEGIN DBMS_APPLY_ADM.START_APPLY( apply_name => 'strm01_apply'); END; /
関連項目:
Oracle Enterprise Manager Cloud Controlを使用して適用プロセスを起動する手順については、Oracle Enterprise Manager Cloud Controlのオンライン・ヘルプを参照
17.2 適用プロセスの停止
既存の適用プロセスを停止するには、DBMS_APPLY_ADM
パッケージのSTOP_APPLY
プロシージャを実行します。たとえば、次のプロシージャでは適用プロセスstrm01_apply
が停止されます。
BEGIN DBMS_APPLY_ADM.STOP_APPLY( apply_name => 'strm01_apply'); END; /
関連項目:
Oracle Enterprise Manager Cloud Controlを使用して適用プロセスを停止する手順については、Oracle Enterprise Manager Cloud Controlのオンライン・ヘルプを参照
17.3 適用プロセスのルール・セットの管理
この項では、次のタスクの実行手順を説明します。
17.3.1 適用プロセスのルール・セットの指定
適用プロセスには、1つのポジティブ・ルール・セットおよび1つのネガティブ・ルール・セットを指定できます。適用プロセスでは、メッセージは、ポジティブ・ルール・セットの少なくとも1つのルールについてTRUE
と評価される場合は適用され、ネガティブ・ルール・セットの少なくとも1つのルールについてTRUE
と評価される場合は廃棄されます。ネガティブ・ルール・セットは、ポジティブ・ルール・セットの前に評価されます。
17.3.1.1 適用プロセスのポジティブ・ルール・セットの指定
既存のルール・セットをポジティブ・ルール・セットとして既存の適用プロセスに指定するには、ALTER_APPLY
プロシージャのrule_set_name
パラメータを使用します。このプロシージャは、DBMS_APPLY_ADM
パッケージに含まれています。
たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のポジティブ・ルール・セットがstrm02_rule_set
に設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm01_apply', rule_set_name => 'strmadmin.strm02_rule_set'); END; /
17.3.1.2 適用プロセスのネガティブ・ルール・セットの指定
既存のルールセットをネガティブ・ルール・セットとして既存の適用プロセスに指定するには、ALTER_APPLY
プロシージャのnegative_rule_set_name
パラメータを使用します。このプロシージャは、DBMS_APPLY_ADM
パッケージに含まれています。
たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のネガティブ・ルール・セットがstrm03_rule_set
に設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm01_apply', negative_rule_set_name => 'strmadmin.strm03_rule_set'); END; /
17.3.2 適用プロセスのルール・セットへのルールの追加
適用プロセスのルール・セットにルールを追加するには、次のプロシージャのいずれかを実行します。
ADD_SUBSET_RULES
プロシージャ以外のこれらのプロシージャでは、適用プロセスのポジティブ・ルール・セットまたはネガティブ・ルール・セットにルールを追加できます。ADD_SUBSET_RULES
プロシージャでは、適用プロセスのポジティブ・ルール・セットにのみルールを追加できます。
関連項目:
17.3.2.1 適用プロセスのポジティブ・ルール・セットへのルールの追加
次の例では、DBMS_STREAMS_ADM
パッケージのADD_TABLE_RULES
プロシージャを実行して、適用プロセスstrm01_apply
のポジティブ・ルール・セットにルールを追加します。
BEGIN DBMS_STREAMS_ADM.ADD_TABLE_RULES( table_name => 'hr.departments', streams_type => 'apply', streams_name => 'strm01_apply', queue_name => 'streams_queue', include_dml => TRUE, include_ddl => TRUE, source_database => 'dbs1.example.com', inclusion_rule => TRUE); END; /
このプロシージャを実行すると、次のアクションが実行されます。
-
ルールが1つ作成されます。このルールは、
hr.departments
表に対するDML変更の結果を含む行LCRについてTRUE
と評価されます。ルール名はシステムによって生成されます。 -
ルールが1つ作成されます。このルールは、
hr.departments
表に対するDDL変更を含むDDL LCRについてTRUE
と評価されます。ルール名はシステムによって生成されます。 -
どちらのルールも、
dbs1.example.com
ソース・データベースで変更が発生したLCRに対してのみTRUE
と評価されるように指定されます。 -
inclusion_rule
パラメータがTRUE
に設定されているため、そのルールは適用プロセスに関連付けられたポジティブ・ルール・セットに追加されます。
17.3.2.2 適用プロセスのネガティブ・ルール・セットへのルールの追加
次の例では、DBMS_STREAMS_ADM
パッケージのADD_TABLE_RULES
プロシージャを実行して、適用プロセスstrm01_apply
のネガティブ・ルール・セットにルールを追加します。
BEGIN DBMS_STREAMS_ADM.ADD_TABLE_RULES( table_name => 'hr.regions', streams_type => 'apply', streams_name => 'strm01_apply', queue_name => 'streams_queue', include_dml => TRUE, include_ddl => TRUE, source_database => 'dbs1.example.com', inclusion_rule => FALSE); END; /
このプロシージャを実行すると、次のアクションが実行されます。
-
ルールが1つ作成されます。このルールは、
hr.regions
表に対するDML変更の結果を含む行LCRについてTRUE
と評価されます。ルール名はシステムによって生成されます。 -
ルールが1つ作成されます。このルールは、
hr.regions
表に対するDDL変更を含むDDL LCRについてTRUE
と評価されます。ルール名はシステムによって生成されます。 -
どちらのルールも、
dbs1.example.com
ソース・データベースで変更が発生したLCRに対してのみTRUE
と評価されるように指定されます。 -
inclusion_rule
パラメータがFALSE
に設定されているため、そのルールは適用プロセスに関連付けられたネガティブ・ルール・セットに追加されます。
17.3.3 適用プロセスのルール・セットからのルールの削除
既存の適用プロセスのルール・セットからルールを削除するには、DBMS_STREAMS_ADM
パッケージのREMOVE_RULE
プロシージャを実行します。たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のポジティブ・ルール・セットからルールdepartments3
が削除されます。
BEGIN DBMS_STREAMS_ADM.REMOVE_RULE( rule_name => 'departments3', streams_type => 'apply', streams_name => 'strm01_apply', drop_unused_rule => TRUE, inclusion_rule => TRUE); END; /
この例では、REMOVE_RULE
プロシージャのdrop_unused_rule
パラメータがTRUE
に設定されています。これはデフォルトの設定です。したがって、削除するルールが他のどのルール・セットにも含まれていなければ、そのルールはデータベースから削除されます。drop_unused_rule
パラメータがFALSE
に設定されている場合、ルールはルール・セットから削除されますが、他のどのルール・セットにも含まれていない場合でも、データベースからは削除されません。
inclusion_rule
パラメータをFALSE
に設定すると、REMOVE_RULE
プロシージャによって、適用プロセスのポジティブ・ルール・セットからではなく、ネガティブ・ルール・セットからルールが削除されます。
適用プロセスのルール・セットからすべてのルールを削除するには、REMOVE_RULE
プロシージャの実行時にrule_name
パラメータにNULL
を指定します。
17.3.4 適用プロセスのルール・セットの削除
既存の適用プロセスから ルール・セットを削除するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャを使用します。このプロシージャでは、ポジティブ・ルール・セットまたはネガティブ・ルール・セット、あるいはその両方を削除できます。適用プロセスのポジティブ・ルール・セットを削除するには、remove_rule_set
パラメータにTRUE
を設定します。適用プロセスのネガティブ・ルール・セットを削除するには、remove_negative_rule_set
パラメータにTRUE
を設定します。
たとえば、次のプロシージャでは、適用プロセスstrm01_apply
からポジティブ・ルール・セットとネガティブルール・セットの両方が削除されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm01_apply', remove_rule_set => TRUE, remove_negative_rule_set => TRUE); END; /
17.4 適用プロセス・パラメータの設定
適用プロセス・パラメータを設定するには、DBMS_APPLY_ADM
パッケージのSET_PARAMETER
プロシージャを使用します。適用プロセス・パラメータによって、適用プロセスの動作が制御されます。
たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のcommit_serialization
パラメータがDEPENDENT_TRANSACTIONS
に設定されます。commit_serialization
パラメータをこの値に設定にすると、適用プロセスはトランザクションを任意の順序でコミットできます。
BEGIN DBMS_APPLY_ADM.SET_PARAMETER( apply_name => 'strm01_apply', parameter => 'commit_serialization', value => 'DEPENDENT_TRANSACTIONS'); END; /
注意:
-
value
パラメータは、パラメータ値が数値の場合にも、常にVARCHAR2
値として入力されます。 -
value
パラメータがNULL
に設定されているか、または指定されていない場合、パラメータはデフォルト値に設定されます。 -
parallelism
適用プロセス・パラメータを1
より大きい値に設定する場合は、適用プロセスで変更が適用される表のすべての一意キー列と外部キー列について、ソース・データベースに条件付きのサプリメンタル・ログ・グループを指定する必要があります。構成によっては、これらの表の他の列についても同様にサプリメンタル・ロギングが必要になる場合があります。
関連項目:
-
Oracle Enterprise Manager Cloud Controlを使用して適用プロセス・パラメータを設定する手順については、Oracle Enterprise Manager Cloud Controlのオンライン・ヘルプを参照
-
適用プロセス・パラメータの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の
DBMS_APPLY_ADM.SET_PARAMETER
プロシージャに関する項を参照 -
サプリメンタル・ロギングの指定の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
17.5 適用プロセスの適用ユーザーの設定
適用ユーザーは、適用プロセスのルール・セットを満たすすべてのDML変更およびDDL変更を適用し、ユーザー定義の適用ハンドラを実行するユーザーです。適用プロセスの適用ユーザーを設定するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでapply_user
パラメータを使用します。
適用ユーザーを変更するには、ALTER_APPLY
プロシージャを起動するユーザーにDBA
ロールが付与されている必要があります。apply_user
をSYS
に設定できるのは、SYS
ユーザーに限られています。
たとえば、次のプロシージャでは、適用プロセスstrm03_apply
の適用ユーザーがhr
に設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm03_apply', apply_user => 'hr'); END; /
このプロシージャを実行すると、新しい適用ユーザーに、適用プロセスで使用されるキューのデキュー権限が付与され、そのユーザーがキューの保護キュー・ユーザーとして構成されます。また、適用ユーザーが次の権限を持っていることを確認する必要があります。
-
適用オブジェクトのDML変更とDDL変更を実行する際に必要な権限
-
適用プロセスで使用するルール・セットの
EXECUTE
権限 -
ルール・セットで使用するすべてのカスタム・ルールベースの変換ファンクションの
EXECUTE
権限 -
すべての適用ハンドラ・プロシージャの
EXECUTE
権限
これらの権限は、適用ユーザーに直接付与するか、ロールを介して付与できます。
また、適用ユーザーには、適用プロセスで実行されるサブプログラムで起動されるすべてのパッケージ(Oracle提供パッケージを含む)に対するEXECUTE
権限を付与する必要があります。これらの権限は、適用ユーザーに直接付与する必要があります。ロールを通して付与することはできません。
注意:
Oracle Database Vaultがインストールされている場合は、適用ユーザーを変更するユーザーにBECOME
USER
システム権限を付与する必要があります。Oracle Database Vaultがインストールされていない場合は、ユーザーにこの権限を付与する必要はありません。適用ユーザーを変更した後は、必要に応じて、そのユーザーからBECOME
USER
システム権限を取り消すことができます。
17.6 DMLハンドラの管理
DMLハンドラは、適用プロセスによってデキューされた行論理変更レコード(行LCR)を処理します。DMLハンドラには2つのタイプがあります。文DMLハンドラとプロシージャDMLハンドラです。文DMLハンドラは、SQL文のコレクションを使用して行LCRを処理します。一方プロシージャDMLハンドラは、PL/SQLプロシージャを使用して行LCRを処理します。
この項では、DMLハンドラの管理手順について説明します。
関連項目:
17.6.1 文DMLハンドラの管理
この項では、文DMLハンドラの次の管理手順について説明します。
関連項目:
17.6.1.1 文DMLハンドラの作成および適用プロセスへの追加
文DMLハンドラを作成して適用プロセスに追加するには、次の2とおりの方法があります。
-
1つ目は、文DMLハンドラの作成、1つの文の追加および適用プロセスへのその文DMLハンドラの追加をすべて1ステップで行う方法です。
-
2つ目は、文DMLハンドラの作成、1つ以上の文の追加および適用プロセスへのその文DMLハンドラの追加を個々のステップで行う方法です。
通常、文DMLハンドラに含まれる文が1つのみの場合には1ステップの方法が最適です。文DMLハンドラに複数の文が含まれる場合には複数ステップの方法が最適です。
次の各項では、それぞれの方法について詳しく説明する例を示します。
17.6.1.1.1 1つの文を含む文DMLハンドラの作成
一部のOracle Streamsレプリケーション環境では、レプリケートされた表はその表を共有するデータベースでまったく同じではありません。このような環境では、文DMLハンドラによって、行LCRで実行されたDML変更が変更される可能性があります。文DMLハンドラでは行LCRの列値は変更できません。ただし、文DMLハンドラでSQLを使用し、行を挿入したり、行LCRの列値とは異なる列値で行を更新できます。
この項の例では、次のことを想定しています。
-
Oracle Streamsレプリケーション環境は、ソース・データベースと宛先データベースとの間で
oe.orders
表に変更をレプリケートするように構成されています。oe.orders
表への変更はソース・データベースで取得プロセスまたは同期取得によって取得され、伝播によって宛先データベースに送信されて、宛先データベースで適用プロセスによって適用されます。 -
ソース・データベースでは、
oe.orders
表にorder_status
列が含まれます。宛先データベースで1
のorder_status
の挿入が適用されると、order_status
が2
に変更されることが想定されます。この例では、文DMLハンドラによってこの変更が行われます。1
ではないorder_status
が挿入されると、文DMLハンドラでは、order_status
値を変更せずに行LCRの元の変更が適用されます。
oe.orders
表への挿入を変更する文DMLハンドラを作成するには、次の手順を実行します。
-
この例のために、ソース・データベースで次のように必須のサプリメンタル・ロギングを指定します。
-
ソース・データベースにOracle Streams管理者として接続します。
SQL*Plusでデータベースに接続する方法については、『Oracle Database管理者ガイド』を参照してください。
-
oe.orders
表のorder_status
列を含む無条件サプリメンタル・ログ・グループを次のように指定します。ALTER TABLE oe.orders ADD SUPPLEMENTAL LOG GROUP log_group_ord_stat (order_status) ALWAYS;
宛先データベースで文DMLハンドラによって使用されるすべての列は、ソース・データベースで無条件ログ・グループに存在している必要があります。
-
-
宛先データベースにOracle Streams管理者として接続します。
-
文DMLハンドラを作成して適用プロセスに追加します。
DECLARE stmt CLOB; BEGIN stmt := 'INSERT INTO oe.orders( order_id, order_date, order_mode, customer_id, order_status, order_total, sales_rep_id, promotion_id) VALUES( :new.order_id, :new.order_date, :new.order_mode, :new.customer_id, DECODE(:new.order_status, 1, 2, :new.order_status), :new.order_total, :new.sales_rep_id, :new.promotion_id)'; DBMS_APPLY_ADM.ADD_STMT_HANDLER( object_name => 'oe.orders', operation_name => 'INSERT', handler_name => 'modify_orders', statement => stmt, apply_name => 'apply$_sta_2', comment => 'Modifies inserts into the orders table'); END; /
DECODE
ファンクションによってorder_status
が1
から2
に変更されることに注意してください。行LCRのorder_status
が1
でない場合、DECODE
ファンクションでデフォルトに:new.order_status
を指定することにより、DECODE
ファンクションでは元のorder_status
値が使用されます。ADD_STMT_HANDLER
プロシージャによって、modify_orders
文DMLハンドラが作成されてapply$_sta_2
適用プロセスに追加されます。文DMLハンドラは、oe.orders
表への挿入を実行する行LCRがこの適用プロセスによってデキューされるときに起動されます。この表に対して行われる更新や削除を実行する行LCRを変更するには、個別の文DMLハンドラが必要となります。
注意:
-
modify_orders
文DMLハンドラのこの文により、宛先の表に対する行変更が実行されます。したがって、文DMLハンドラに実行文を追加する必要はありません。この文によって実行される行変更は、適用プロセスによって行LCRのトランザクションに対するコミット・ディレクティブがデキューされるときにコミットされます。 -
この例では、
ADD_STMT_HANDLER
プロシージャによって文DMLハンドラがapply$_sta_2
適用プロセスに追加されます。データベース内のすべての適用プロセスによって使用される汎用文DMLハンドラを追加するには、このプロシージャのapply_name
パラメータを省略するか、またはapply_name
パラメータをNULL
に設定します。
17.6.1.1.2 1つ以上の文を含む文DMLハンドラの作成
文DMLハンドラを使用すると、表に対して行われた変更を追跡できます。この例では、文DMLハンドラによってhr.jobs
表に対して行われた更新が追跡されます。
この項の例では、次のことを想定しています。
-
Oracle Streamsレプリケーション環境は、ソース・データベースと宛先データベースとの間で
hr.jobs
表に変更をレプリケートするように構成されています。hr.jobs
表への変更はソース・データベースで取得プロセスまたは同期取得によって取得され、伝播によって宛先データベースに送信されて、宛先データベースで適用プロセスによって適用されます。hr.jobs
表には、ある組織の様々な役職に対する最小および最大の給与が含まれます。 -
給与情報に対する更新およびこれらの更新がいつ行われたかを追跡することが目的です。この目的のために、文DMLハンドラによって
hr.track_jobs
表に行が挿入されます。 -
hr.jobs
表に変更をレプリケートするには、適用プロセスで行LCRを実行する必要もあります。
hr.jobs
に対する更新を追跡する文DMLハンドラを作成するには、次の手順を実行します。
17.6.1.2 文DMLハンドラへの文の追加
文DMLハンドラに文を追加するには、DBMS_STREAMS_HANDLER_ADM
パッケージのADD_STMT_TO_HANDLER
プロシージャを実行して、文DMLハンドラに対してまだ指定されていない実行順序番号を指定します。
この項の例では、modify_orders
文DMLハンドラに文を追加します。この文DMLハンドラは「1つの文を含む文DMLハンドラの作成」で作成したものです。この文により、oe.orders
表への挿入が変更されます。
この項の例では、宛先データベースで特定の顧客に対して注文の10%を割引するとします。oe.orders
表でのこの顧客のcustomer_id
値は118
です。この場合、文DMLハンドラのSQL文を使用して、customer_id
値が118
のoe.orders
表への挿入について、order_total
値に.9
を乗算します。
modify_orders
文DMLハンドラに文を追加するには、次の手順を実行します。
これらの手順を完了した後、手順2の問合せに対する出力は次のようになります。
Statement Execution Handler Sequence Statement --------------- --------- -------------------------------------------------- MODIFY_ORDERS 1 INSERT INTO oe.orders( order_id, order_date, order_mode, customer_id, order_status, order_total, sales_rep_id, promotion_id) VALUES( :new.order_id, :new.order_date, :new.order_mode, :new.customer_id, DECODE(:new.order_status, 1, 2, :new. order_status), :new.order_total, :new.sales_rep_id, :new.promotion_id) MODIFY_ORDERS 10 UPDATE oe.orders SET order_total=order_total*.9 WHERE order_id=:new.order_id AND :new. customer_id=118
この出力は、実行順序番号が10
の新しい文が文DMLハンドラに追加されていることを示しています。
17.6.1.3 文DMLハンドラ内の文の変更
文DMLハンドラ内の文を変更するには、DBMS_STREAMS_HANDLER_ADM
パッケージのADD_STMT_TO_HANDLER
プロシージャを実行し、変更する文の実行順序番号を指定します。
この項の例では、track_jobs
文DMLハンドラの実行順序番号が20
の文が変更されます。この文DMLハンドラは「1つ以上の文を含む文DMLハンドラの作成」で作成したものです。これにより、hr.track_jobs
表を使用してhr.jobs
表への変更が追跡されます。
この項の例では、hr.jobs
表を更新したユーザーも追跡するとします。この場合、ソース・データベースで取得された行LCRにこの情報を追加して、user_name
列をhr.track_jobs
表に追加し、ユーザーを追跡するように文DMLハンドラ内の文を変更します。
文DMLハンドラ内の文を変更するには、次の手順を実行します。
関連項目:
17.6.1.4 文DMLハンドラからの文の削除
文DMLハンドラから文を削除するには、DBMS_STREAMS_HANDLER_ADM
パッケージのREMOVE_STMT_FROM_HANDLER
プロシージャを実行し、削除する文の実行順序番号を指定します。
この項の例では、track_jobs
文DMLハンドラから実行順序番号が10
の文が削除されます。この文DMLハンドラは「1つ以上の文を含む文DMLハンドラの作成」で作成したものです。これにより、hr.track_jobs
表を使用してhr.jobs
表への変更が追跡されます。
この項の例では、hr.jobs
表に対する更新を含む行LCRの実行が不要になったことを想定しています。この場合、この行LCRを実行する文を削除する必要があり、track_jobs
文DMLハンドラでのこの文の実行順序番号は10
です。
文DMLハンドラから文を削除するには、次の手順を実行します。
17.6.1.5 適用プロセスからの文DMLハンドラの削除
適用プロセスから文DMLハンドラを削除するには、DBMS_APPLY_ADM
パッケージのREMOVE_STMT_HANDLER
プロシージャを実行します。
この項の例では、apply$_sta_2
適用プロセスからtrack_jobs
文DMLハンドラが削除されます。この文DMLハンドラは「1つ以上の文を含む文DMLハンドラの作成」で作成したものです。これにより、hr.track_jobs
表を使用してhr.jobs
表への変更が追跡されます。
適用プロセスから文DMLハンドラを削除するには、次の手順を実行します。
文DMLハンドラは、適用プロセスから削除した後でもデータベースには存在します。
17.6.1.6 文DMLハンドラの削除
データベースから文DMLハンドラを削除するには、DBMS_STREAMS_HANDLER_ADM
パッケージのDROP_STMT_HANDLER
プロシージャを実行します。
この項の例では、track_jobs
文DMLハンドラが削除されます。この文DMLハンドラは「1つ以上の文を含む文DMLハンドラの作成」で作成したものです。これにより、hr.track_jobs
表を使用してhr.jobs
表への変更が追跡されます。
文DMLハンドラを削除するには、次の手順を実行します。
17.6.2 プロシージャDMLハンドラの管理
この項では、プロシージャDMLハンドラの次の管理手順について説明します。
関連項目:
17.6.2.1 プロシージャDMLハンドラの作成
プロシージャDMLハンドラには、次のシグネチャが必要です。
PROCEDURE user_procedure ( parameter_name IN ANYDATA);
user_procedure
はプロシージャ名、parameter_name
はプロシージャに渡されるパラメータ名を表します。プロシージャに渡されるパラメータは、行論理変更レコード(行LCR)をANYDATA
にカプセル化したものです。
ユーザー・プロシージャには、次の制限事項が適用されます。
-
COMMIT
文またはROLLBACK
文を実行しないでください。実行すると、行LCRを含むトランザクションの一貫性が失われる危険性があります。 -
行LCR用の
EXECUTE
メンバー・プロシージャを使用して行を操作している場合は、1つの行操作で複数の行を操作しないでください。複数行を操作するDML文は、手動で構成および実行する必要があります。 -
コマンド・タイプが
UPDATE
またはDELETE
の場合、LCRに対してEXECUTE
メンバー・プロシージャを使用して再実行される行操作では、以前の値リストにキー全体が含まれている必要があります。キーは、代替キーがSET_KEY_COLUMNS
プロシージャによって指定されていないかぎり、少なくとも1つのNOT
NULL
列を含む主キーまたは最小の一意キーとなります。キーが指定されていない場合、キーはすべての表の列で構成されますが、LOB、LONG
、LONG
RAW
の各データ型、ユーザー定義型(オブジェクト型、REF、VARRAY、ネストした表など)およびOracle提供の型(Any型、XML型、空間型、メディア型など)の列は除外されます。 -
コマンド・タイプが
INSERT
の場合、LCRに対してEXECUTE
メンバー・プロシージャを使用して再実行される行操作では、新規の値リストにキー全体が含まれている必要があります。キー全体が組み込まれていない場合は、行が重複する可能性があります。キーは、代替キーがSET_KEY_COLUMNS
プロシージャによって指定されていないかぎり、少なくとも1つのNOT
NULL
列を含む主キーまたは最小の一意キーとなります。キーを指定しない場合は、LOB列、LONG
列およびLONG
RAW
列以外のすべての列によってキーが構成されます。
プロシージャDMLハンドラは、行LCRの任意のカスタム処理に使用できます。たとえば、ハンドラでLCRを変更してから、そのLCRに対するEXECUTE
メンバー・プロシージャを使用してLCRを実行することができます。プロシージャDMLハンドラで行LCRを実行すると、適用プロセスはプロシージャDMLハンドラを再度呼び出すことなくLCRを適用します。
プロシージャDMLハンドラでSQL生成を使用して、表に対して行われるDML変更を記録することもできます。これらの変更は、表かファイルに記録できます。たとえば、この項のサンプル・プロシージャDMLハンドラでは、SQL生成を使用し、GET_ROW_TEXT
メンバー・プロシージャによりhr.departments
表に対して実行された各UPDATE
SQL文を記録します。プロシージャDMLハンドラによって、EXECUTE
メンバー・プロシージャを使用して行LCRも適用されます。
このプロシージャDMLハンドラで使用されるプロシージャを作成するには、次の手順を実行します。
プロシージャを作成した後、「プロシージャDMLハンドラの設定」の手順に従って、作成したプロシージャをプロシージャDMLハンドラとして設定できます。
注意:
-
宛先データベースでプロシージャDMLハンドラが必要とする任意の列に対して、ソース・データベースで無条件サプリメンタル・ログ・グループを指定する必要があります。このサンプル・プロシージャDMLハンドラではSQL文が記録され、その他の方法で行LCRが操作されることはないため、このサンプル・プロシージャDMLハンドラに追加のサプリメンタル・ロギングは必要ありません。
-
プロシージャDMLハンドラを使用前にテストしたり、プロシージャDMLハンドラをデバッグするために、行LCRを作成し、適用プロセスのコンテキスト外でプロシージャDMLハンドラのプロシージャを実行できます。
関連項目:
-
「SQL生成」
-
GET_ROW_TEXT
行LCRメンバー・ファンクションの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
プロシージャDMLハンドラで処理する可能性のある一般的な適用エラーの詳細は、「エラー・キューに適用エラーがあるか」を参照
-
データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
17.6.2.2 プロシージャDMLハンドラの設定
プロシージャDMLハンドラにより、特定の表に対する特定の操作を含む任意の適用プロセスによってデキューされた各行LCRが処理されます。表に対する様々な操作を処理するために、同じ表で複数のプロシージャDMLハンドラを指定できます。ローカル・データベース内の指定した表に変更を適用するすべての適用プロセスでは、指定したプロシージャDMLハンドラが使用されます。
DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを使用して、プロシージャDMLハンドラを設定します。たとえば、次のプロシージャでは、hr.departments
表に対するUPDATE
操作用のプロシージャDMLハンドラを設定します。したがって、変更をローカルに適用する任意の適用プロセスがhr.departments
表に対するUPDATE
操作を含む行LCRをデキューすると、適用プロセスは行LCRをstrmadmin
スキーマのsql_gen_dep
PL/SQLプロシージャに処理用に送信します。適用プロセスでは、このような変更を含む行LCRを直接適用することはありません。
この例では、apply_name
パラメータがNULL
に設定されています。したがって、プロシージャDMLハンドラは、データベース内のすべての適用プロセスによって使用される汎用プロシージャDMLハンドラです。
BEGIN DBMS_APPLY_ADM.SET_DML_HANDLER( object_name => 'hr.departments', object_type => 'TABLE', operation_name => 'UPDATE', error_handler => FALSE, user_procedure => 'strmadmin.sql_gen_dep', apply_database_link => NULL, apply_name => NULL); END; /
注意:
-
プロシージャDMLハンドラを1つの適用プロセスに対してのみ指定するには、適用プロセスの名前を
apply_name
パラメータで指定します。 -
適用プロセスによってOracle以外のリモート・データベースに変更が適用される場合、この適用プロセスでは、同じ表に対して別のプロシージャDMLハンドラを使用できます。
DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを実行して、apply_database_link
パラメータをNULL
以外の値に設定することにより、Oracle以外のリモート・データベースに適用される変更に対してプロシージャDMLハンドラを指定できます。 -
operation_name
パラメータにDEFAULT
を指定して、プロシージャをデータベース・オブジェクトのデフォルトのプロシージャDMLハンドラとして設定できます。この場合、データベース・オブジェクトに対する操作に別のプロシージャDMLハンドラが明確に設定されているのでなければ、データベース・オブジェクトに対するINSERT
、UPDATE
、DELETE
およびLOB_WRITE
のすべてにこのプロシージャDMLハンドラが使用されます。
17.6.2.3 プロシージャDMLハンドラの設定解除
プロシージャDMLハンドラの設定を解除するには、DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを使用します。このプロシージャを実行するときに、特定の表に対する特定の操作について、user_procedure
パラメータをNULL
に設定します。プロシージャDMLハンドラの設定を解除した後、変更をローカルに適用する任意の適用プロセスで、このような変更を含む行LCRが直接適用されるようになります。
たとえば、次のプロシージャでは、hr.departments
表に対するUPDATE
操作について、プロシージャDMLハンドラの設定が解除されます。
BEGIN DBMS_APPLY_ADM.SET_DML_HANDLER( object_name => 'hr.departments', object_type => 'TABLE', operation_name => 'UPDATE', error_handler => FALSE, user_procedure => NULL, apply_name => NULL); END; /
17.7 DDLハンドラの管理
この項では、適用プロセスのDDLハンドラの作成、指定および削除の手順について説明します。
注意:
適用されたDDL LCRはすべて自動的にコミットします。したがって、DDLハンドラがDDL LCRのEXECUTE
メンバー・プロシージャをコールすると、自動的にコミットが実行されます。
関連項目:
-
LCRタイプの
EXECUTE
メンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
17.7.1 適用プロセスのDDLハンドラの作成
DDLハンドラには、次のシグネチャが必要です。
PROCEDURE handler_procedure ( parameter_name IN ANYDATA);
handler_procedure
はプロシージャ名、parameter_name
はプロシージャに渡されるパラメータ名を表します。プロシージャに渡されるパラメータは、DDL LCRをANYDATA
にカプセル化したものです。
DDLハンドラは、DDL LCRの任意のカスタム処理に使用できます。たとえば、ハンドラでLCRを変更してから、そのLCRに対するEXECUTE
メンバー・プロシージャを使用してLCRを実行できます。DDLハンドラでDDL LCRを実行すると、適用プロセスはDDLハンドラを再度呼び出すことなくLCRを適用します。
また、DDLハンドラを使用してDDL変更の履歴を記録することもできます。たとえば、DDLハンドラを使用すると、DDLハンドラで処理したLCRに関する情報を表に挿入してから、EXECUTE
メンバー・プロシージャを使用してLCRを適用できます。
このようなDDLハンドラを作成するには、最初に、履歴情報を保持するための表を次のように作成します。
CREATE TABLE strmadmin.history_ddl_lcrs( timestamp DATE, source_database_name VARCHAR2(128), command_type VARCHAR2(30), object_owner VARCHAR2(32), object_name VARCHAR2(32), object_type VARCHAR2(18), ddl_text CLOB, logon_user VARCHAR2(32), current_schema VARCHAR2(32), base_table_owner VARCHAR2(32), base_table_name VARCHAR2(32), tag RAW(10), transaction_id VARCHAR2(10), scn NUMBER);
CREATE OR REPLACE PROCEDURE history_ddl(in_any IN ANYDATA) IS lcr SYS.LCR$_DDL_RECORD; rc PLS_INTEGER; ddl_text CLOB; BEGIN -- Access the LCR rc := in_any.GETOBJECT(lcr); DBMS_LOB.CREATETEMPORARY(ddl_text, TRUE); lcr.GET_DDL_TEXT(ddl_text); -- Insert DDL LCR information into history_ddl_lcrs table INSERT INTO strmadmin.history_ddl_lcrs VALUES( SYSDATE, lcr.GET_SOURCE_DATABASE_NAME(), lcr.GET_COMMAND_TYPE(), lcr.GET_OBJECT_OWNER(), lcr.GET_OBJECT_NAME(), lcr.GET_OBJECT_TYPE(), ddl_text, lcr.GET_LOGON_USER(), lcr.GET_CURRENT_SCHEMA(), lcr.GET_BASE_TABLE_OWNER(), lcr.GET_BASE_TABLE_NAME(), lcr.GET_TAG(), lcr.GET_TRANSACTION_ID(), lcr.GET_SCN()); -- Apply DDL LCR lcr.EXECUTE(); -- Free temporary LOB space DBMS_LOB.FREETEMPORARY(ddl_text); END; /
17.7.2 適用プロセスのDDLハンドラの設定
DDLハンドラによって、適用プロセスでデキューされたすべてのDDL LCRが処理されます。適用プロセスのDDLハンドラを設定するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでddl_handler
パラメータを使用します。たとえば、次のプロシージャでは、適用プロセスstrep01_apply
のDDLハンドラがstrmadmin
スキーマ内のhistory_ddl
プロシージャに設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strep01_apply', ddl_handler => 'strmadmin.history_ddl'); END; /
17.7.3 適用プロセスのDDLハンドラの削除
DDLハンドラによって、適用プロセスでデキューされたすべてのDDL LCRが処理されます。適用プロセスのDDLハンドラを削除するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでremove_ddl_handler
パラメータをTRUE
に設定します。たとえば、次のプロシージャでは、適用プロセスstrep01_apply
からDDLハンドラが削除されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strep01_apply', remove_ddl_handler => TRUE); END; /
17.8 適用プロセスのメッセージ・ハンドラの管理
メッセージ・ハンドラは、永続ユーザー・メッセージを処理する適用ハンドラです。次の各項では、適用プロセスにメッセージ・ハンドラを設定または設定解除する手順について説明します。
関連項目:
-
メッセージ・ハンドラの作成例については、『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照
17.8.1 適用プロセスのメッセージ・ハンドラの設定
適用プロセスのメッセージ・ハンドラを設定するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでmessage_handler
パラメータを使用します。たとえば、次のプロシージャでは、適用プロセスstrm03_apply
のメッセージ・ハンドラがoe
スキーマ内のmes_handler
プロシージャに設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm03_apply', message_handler => 'oe.mes_handler'); END; /
ALTER_APPLY
プロシージャを実行するユーザーは、指定したメッセージ・ハンドラのEXECUTE
権限を持っている必要があります。メッセージ・ハンドラが適用プロセスにすでに設定されている場合は、ALTER_APPLY
プロシージャを実行して、適用プロセスのメッセージ・ハンドラを変更できます。
17.8.2 適用プロセスのメッセージ・ハンドラの設定解除
適用プロセスのメッセージ・ハンドラを設定解除するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでremove_message_handler
パラメータをTRUE
に設定します。たとえば、次のプロシージャでは、適用プロセスstrm03_apply
のメッセージ・ハンドラの設定が解除されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm03_apply', remove_message_handler => TRUE); END; /
17.9 適用プロセスのプリコミット・ハンドラの管理
プリコミット・ハンドラは、トランザクションのコミット情報を受信し、カスタマイズした方法でコミット情報を処理できる適用ハンドラです。
次の各項では、適用プロセスのプリコミット・ハンドラの作成、設定および設定解除の手順について説明します。
17.9.1 適用プロセスのプリコミット・ハンドラの作成
プリコミット・ハンドラには、次のシグネチャが必要です。
PROCEDURE handler_procedure ( parameter_name IN NUMBER);
handler_procedure
はプロシージャ名、parameter_name
はプロシージャに渡されるパラメータ名を表します。プロシージャに渡されるパラメータは、適用プロセスで使用されるキューに含まれる内部コミット・ディレクティブのコミットSCNです。
プリコミット・ハンドラを使用すると、適用プロセスによって処理されたコミットの情報を記録できます。適用プロセスでは、取得LCR、永続LCRまたは永続ユーザー・メッセージを適用できます。取得された行LCRの場合は、コミット・ディレクティブに、ソース・データベースからのトランザクションのコミットSCNが含まれます。永続LCRおよび永続ユーザー・メッセージの場合、コミットSCNは適用プロセスによって生成されます。
プリコミット・ハンドラ・プロシージャでは、次の制限に従ってください。
-
コミットする作業を自律型トランザクションにする。
-
プロシージャで作成された指定のセーブ・ポイントまでロールバックする必要があります。
プリコミット・ハンドラで例外が発生した場合は、適用トランザクション全体がロールバックされ、トランザクション内のすべてのメッセージがエラー・キューに移動されます。
たとえば、プリコミット・ハンドラは、適用プロセスによって適用された行LCRの監査に使用できます。このようなプリコミット・ハンドラを1つ以上の個別のプロシージャDMLハンドラとともに使用し、トランザクションのソース・データベースのコミットSCNを監査表に記録し、適用プロセスがトランザクションを適用する時間を監査表に記録する場合もあります。
特に、この例では、次の表の行LCRに関する情報を記録するプロシージャDMLハンドラとともに使用されるプリコミット・ハンドラが作成されます。
CREATE TABLE strmadmin.history_row_lcrs( timestamp DATE, source_database_name VARCHAR2(128), command_type VARCHAR2(30), object_owner VARCHAR2(32), object_name VARCHAR2(32), tag RAW(10), transaction_id VARCHAR2(10), scn NUMBER, commit_scn NUMBER, old_values SYS.LCR$_ROW_LIST, new_values SYS.LCR$_ROW_LIST) NESTED TABLE old_values STORE AS old_values_ntab NESTED TABLE new_values STORE AS new_values_ntab;
プロシージャDMLハンドラは、適用プロセスによって処理される行LCRごとに、strmadmin.history_row_lcrs
表に1行挿入します。この例で作成されるプリコミット・ハンドラは、トランザクションのコミット時に、strmadmin.history_row_lcrs
表に1行挿入します。
history_row_lcrs
表にコミット情報を挿入するプロシージャを作成します。
CREATE OR REPLACE PROCEDURE strmadmin.history_commit(commit_number IN NUMBER) IS BEGIN -- Insert commit information into the history_row_lcrs table INSERT INTO strmadmin.history_row_lcrs (timestamp, commit_scn) VALUES (SYSDATE, commit_number); END; /
関連項目:
17.9.2 適用プロセスのプリコミット・ハンドラの設定
プリコミット・ハンドラは、適用プロセスによってデキューされたすべてのコミット・ディレクティブを処理します。適用プロセスにプリコミット・ハンドラを設定すると、適用プロセスがデキューするすべてのコミット・ディレクティブの処理に使用されます。適用プロセスには1つのプリコミット・ハンドラのみを設定できます。
適用プロセスのプリコミット・ハンドラを設定するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでprecommit_handler
パラメータを使用します。たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のプリコミット・ハンドラにstrmadmin
スキーマのhistory_commit
プロシージャが設定されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm01_apply', precommit_handler => 'strmadmin.history_commit'); END; /
また、DBMS_APPLY_ADM
パッケージのCREATE_APPLY
プロシージャを使用して適用プロセスを作成する際に、プリコミット・ハンドラを指定することもできます。適用プロセスにプリコミット・ハンドラがすでに設定されている場合は、ALTER_APPLY
プロシージャを実行して、適用プロセスのプリコミット・ハンドラを変更できます。
17.9.3 適用プロセスのプリコミット・ハンドラの設定解除
適用プロセスのプリコミット・ハンドラを設定解除するには、DBMS_APPLY_ADM
パッケージのALTER_APPLY
プロシージャでremove_precommit_handler
パラメータをTRUE
に設定します。たとえば、次のプロシージャでは、適用プロセスstrm01_apply
のプリコミット・ハンドラの設定が解除されます。
BEGIN DBMS_APPLY_ADM.ALTER_APPLY( apply_name => 'strm01_apply', remove_precommit_handler => TRUE); END; /
17.10 適用プロセスによるメッセージのエンキューの指定
この項では、ポジティブ・ルール・セットに指定したルールを使用する適用プロセスで、ルールを満たすメッセージがエンキューされる宛先キューを設定する手順について説明します。また、宛先キューの設定を削除する手順についても説明します。
関連項目:
17.10.1 ルールを満たすメッセージの宛先キューの設定
特定のルールを満たすメッセージの宛先キューを設定するには、DBMS_APPLY_ADM
パッケージのSET_ENQUEUE_DESTINATION
プロシージャを使用します。たとえば、ルールemployees5
の宛先キューをキューhr.change_queue
に設定するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_ENQUEUE_DESTINATION( rule_name => 'employees5', destination_queue_name => 'hr.change_queue'); END; /
このプロシージャでは、ルールのアクション・コンテキストを変更してキューを指定します。ポジティブ・ルール・セットにemployees5
ルールが含まれるローカル・データベースのすべての適用プロセスで、employees5
ルールを満たすメッセージがhr.change_queue
にエンキューされます。employees5
ルールの宛先キューを変更するには、SET_ENQUEUE_DESTINATION
プロシージャを再実行して異なるキューを指定します。
指定したルールを使用する各適用プロセスの適用ユーザーは、指定したキューにメッセージをエンキューするために必要な権限を持っている必要があります。キューが保護キューの場合、適用ユーザーはキューの保護キュー・ユーザーである必要があります。
SET_ENQUEUE_DESTINATION
プロシージャを使用してエンキューされたメッセージは、手動でエンキューされている他のすべてのメッセージと同様です。このメッセージに対して、手動でのデキュー、apply_captured
パラメータをFALSE
に設定して作成された適用プロセスによる適用、または他のキューへの伝播を実行できます。
注意:
-
指定したルールは、適用プロセスのポジティブ・ルール・セットに含まれている必要があります。ルールが適用プロセスのネガティブ・ルール・セットに含まれている場合、適用プロセスはメッセージを宛先キューにエンキューしません。
関連項目:
-
指定したルールのアクション・コンテキストを
SET_ENQUEUE_DESTINATION
プロシージャで変更する方法については、「適用時のメッセージのエンキューの宛先」を参照
17.10.2 ルールの宛先キュー設定の削除
指定したルールを満たすメッセージの宛先キューを削除するには、DBMS_APPLY_ADM
パッケージのSET_ENQUEUE_DESTINATION
プロシージャを使用します。具体的には、このプロシージャで、ルールのdestination_queue_name
パラメータをNULL
に設定します。ルールの宛先キューの指定が削除された場合、ルールを満たすメッセージは、適用プロセスによってキューにエンキューされません。
たとえば、ルールemployees5
の宛先キューを削除するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_ENQUEUE_DESTINATION( rule_name => 'employees5', destination_queue_name => NULL); END; /
ポジティブ・ルール・セットにemployees5
ルールが含まれるローカル・データベースのすべての適用プロセスで、employees5
ルールを満たすメッセージがhr.change_queue
にエンキューされなくなります。
17.11 適用プロセスの実行ディレクティブの指定
この項では、適用プロセスで、ポジティブ・ルール・セットで指定されたルールを満たすメッセージ用の実行ディレクティブを設定する手順について説明します。
関連項目:
17.11.1 ルールを満たすメッセージの実行の回避の指定
適用プロセスが、指定されたルールを満たすメッセージを実行しないように指定するには、DBMS_APPLY_ADM
パッケージのSET_EXECUTE
プロシージャを使用します。具体的には、このプロシージャで、ルールのexecute
パラメータをFALSE
に設定します。ルールの実行ディレクティブをFALSE
に設定すると、そのルールがポジティブ・ルール・セットに含まれる適用プロセスでは、そのルールを満たすメッセージは実行されません。
たとえば、適用プロセスでルールdepartments8
を満たすメッセージが実行されないように指定するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_EXECUTE( rule_name => 'departments8', execute => FALSE); END; /
このプロシージャは、ルールのアクション・コンテキストを変更して、実行ディレクティブを指定します。ポジティブ・ルール・セットにdepartments8
ルールが含まれるローカル・データベースのすべての適用プロセスで、departments8
ルールを満たすメッセージは実行されません。したがって、メッセージがLCRの場合、適用プロセスでは、LCRの変更が、関連するデータベース・オブジェクトに対して適用されません。また、適用プロセスでは、このルールを満たすメッセージは適用ハンドラに送信されません。
注意:
-
適用プロセスが実行ディレクティブに従うには、指定したルールが適用プロセスのポジティブ・ルール・セットに含まれている必要があります。ルールが適用プロセスのネガティブ・ルール・セットに含まれている場合、適用プロセスはルールの実行ディレクティブを無視します。
-
特定のルールを満たすメッセージを、実行せずに宛先キューにエンキューするには、
SET_EXECUTE
プロシージャとSET_ENQUEUE_DESTINATION
プロシージャを併用できます。SET_ENQUEUE_DESTINATION
プロシージャを使用してメッセージをエンキューすると、そのメッセージは手動でエンキューしたメッセージと同様になります。したがって、そのメッセージに対して、手動のデキュー、適用プロセスによる適用、または他のキューへの伝播を実行できます。
関連項目:
-
指定したルールのアクション・コンテキストを
SET_EXECUTE
プロシージャで変更する方法の詳細は、「適用時のメッセージの実行ディレクティブ」を参照
17.11.2 ルールを満たすメッセージの実行の指定
適用プロセスが、指定されたルールを満たすメッセージを実行するように指定するには、DBMS_APPLY_ADM
パッケージのSET_EXECUTE
プロシージャを使用します。具体的には、このプロシージャでルールのexecute
パラメータをTRUE
に設定します。デフォルトでは、メッセージが適用プロセスのネガティブ・ルール・セットのルールを満たしていないことを想定して、適用プロセスのポジティブ・ルール・セットに含まれるルールを満たすメッセージが各適用プロセスで実行されます。したがって、ルールのexecute
パラメータが以前FALSE
に設定されていた場合にのみ、TRUE
に設定する必要があります。
たとえば、適用プロセスがルールdepartments8
を満たすメッセージを実行するように指定するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_EXECUTE( rule_name => 'departments8', execute => TRUE); END; /
ポジティブ・ルール・セットにdepartments8
ルールが含まれるローカル・データベースのすべての適用プロセスで、departments8
ルールを満たすメッセージが実行されます。したがって、メッセージがLCRの場合、適用プロセスによって、LCRの変更が、関連するデータベース・オブジェクトに対して適用されます。また、適用プロセスでは、このルールを満たすメッセージは適用ハンドラに送信されます(適用プロセスをそのように設定している場合)。
17.12 エラー・ハンドラの管理
エラー・ハンドラは、任意の適用プロセスによってデキューされた、指定の表に対する指定の操作を含む行LCRから生成されたエラーを処理します。
次の各項では、エラー・ハンドラの作成、設定および設定解除の手順について説明します。
関連項目:
17.12.1 エラー・ハンドラの作成
エラー・ハンドラを作成するには、DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを実行して、error_handler
パラメータをTRUE
に設定します。
エラー・ハンドラには、次のシグネチャが必要です。
PROCEDURE user_procedure (
message IN ANYDATA,
error_stack_depth IN NUMBER,
error_numbers IN DBMS_UTILITY.NUMBER_ARRAY,
error_messages IN emsg_array);
user_procedure
は、プロシージャ名です。各パラメータは必須で、指定のデータ・タイプであることが必要です。ただし、パラメータの名前は変更できます。emsg_array
パラメータには、VARCHAR2
型のPL/SQL表である76文字以上のユーザー定義配列で指定する必要があります。
注意:
エラー・ハンドラは、SET_DML_HANDLER
で指定されたユーザー・プロシージャに関するいくつかの条件を満たす必要があります。これらの条件の詳細は、「DMLハンドラの管理」を参照してください。
エラー・ハンドラを実行すると、次のいずれかの結果になります。
-
エラー・ハンドラによって、エラーが正常に解決され、該当する場合は行LCRが適用され、制御が適用プロセスに戻されます。
-
エラー・ハンドラがエラーを解決できず、エラーが発生します。エラーが発生すると、トランザクションはロールバックされ、エラー・キューに入れられます。
DML操作を再実行する場合は、エラー・ハンドラ・プロシージャで、LCR用のEXECUTE
メンバー・プロシージャを実行します。
次の例では、hr.regions
表の主キー違反を解決するエラー・ハンドラregions_pk_error
を作成します。宛先データベースでは、ユーザーがhr.regions
表に行を挿入し、リモート・ソース・データベースの取得プロセスによって発生したhr.regions
表に対する変更が、適用プロセスによって適用されるとします。この環境では、宛先データベースのユーザーが、ソース・データベースから適用された挿入行LCRと同じ主キー値を持つ行を挿入すると、エラーが発生する可能性があります。
この例では、hr.regions
表の主キー違反によるエラーごとに次の情報を記録するため、strmadmin
スキーマにerrorlog
という表を作成します。
-
エラー発生時のタイム・スタンプ
-
エラーが発生した適用プロセスの名前
-
エラーの原因となったユーザー(送信者)。これは、取得LCRの場合は取得プロセス名、同期取得によって取得された永続LCRの場合は同期取得名、アプリケーションによってエンキューされた永続LCRおよび永続ユーザー・メッセージの場合はOracle Database Advanced Queuing(AQ)エージェントの名前です
-
将来、他のオブジェクトのエラーがログに記録される可能性があるため、DMLの操作が実行されたオブジェクトの名前
-
DML操作で使用されたコマンドのタイプ
-
違反となった制約の名前
-
エラー・メッセージ
-
エラーの原因となったLCR
このエラー・ハンドラでは、hr.regions
表での主キー違反によるエラーのみが解決されます。このタイプのエラーを解決するために、エラー・ハンドラでは、順序を使用して行LCRのregion_id
値が変更した後、行LCRを実行して適用します。他のタイプのエラーが発生した場合は、errorlog
表に格納した行LCRを使用して手動でエラーを解決できます。
たとえば、エラー・ハンドラでは次のエラーが解決されます。
-
宛先データベースで、ユーザーが
hr.regions
表にregion_id
の値が6
、region_name
の値が'LILLIPUT'
の1行を挿入します。 -
ソース・データベースで、ユーザーが
hr.regions
表にregion_id
の値が6
、region_name
の値が'BROBDINGNAG'
の1行を挿入します。 -
ソース・データベースの取得プロセスが、手順2で説明した変更を取得します。
-
伝播によって、ソース・データベースのキューから宛先データベースの適用プロセスで使用されるキューに、変更を含むLCRが伝播されます。
-
適用プロセスがLCRを適用すると、主キー違反のためにエラーが発生します。
-
適用プロセスがエラー・ハンドラを起動して、エラーを処理します。
-
エラー・ハンドラは、エラーを
strmadmin.errorlog
表に記録します。 -
エラー・ハンドラは、順序を使用してLCR内で
region_id
値を変更し、そのLCRを実行して適用します。
regions_pk_error
エラー・ハンドラを作成する手順は、次のとおりです。
注意:
-
変更された行に対する以降の変更が正常に適用されるように、2つのデータベースの行をできるだけ迅速に収束する必要があります。つまり、ソース・データベースと宛先データベースの行の
region_id
を一致させる必要があります。このような手動での変更をデータベースで再取得させないようにする場合は、DBMS_STREAMS
パッケージのSET_TAG
プロシージャを使用して、取得されない値を変更するセッション用のタグを設定します。 -
この例のエラー・ハンドラでは、LCRに対して
GET_VALUES
メンバー・ファンクションとSET_VALUES
メンバー・プロシージャを使用しています。LCR内で変更する値が1つのみの場合は、GET_VALUES
メンバー・ファンクションとSET_VALUE
メンバー・プロシージャを使用する方が簡単で効率的な場合があります。
関連項目:
-
現行セッションで生成されるタグの値の設定の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
-
エラー・ハンドラで処理する特定のエラー・メッセージの詳細は、「エラー・キューに適用エラーがあるか」を参照
17.12.2 エラー・ハンドラの設定
エラー・ハンドラは、任意の適用プロセスによってデキューされた、指定の表に対する指定の操作を含む行LCRから生成されたエラーを処理します。同一の表に対する様々な操作で生成されるエラーを処理するために、表に複数のエラー・ハンドラを指定できます。特定の適用プロセスにエラー・ハンドラを設定できます。また、指定の表に指定の操作を適用するすべての適用プロセスで使用される一般的なエラー・ハンドラとして、エラー・ハンドラを設定することもできます。
エラー・ハンドラを設定するには、DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを使用します。このプロシージャを実行してエラー・ハンドラを設定する場合は、error_handler
パラメータをTRUE
に設定します。
たとえば、次のプロシージャでは、hr.regions
表に対するINSERT
操作用のエラー・ハンドラを設定します。したがって、適用プロセスによって、ローカルのhr.regions
表に対するINSERT
操作を含む行LCRがデキューされ、行LCRがエラーになると、適用プロセスでは、行LCRがstrmadmin.errors_pkg.regions_pk_error
PL/SQLプロシージャに送信されて処理されます。エラー・ハンドラでエラーを解決できない場合は、その行LCRと、同じトランザクション内の他のすべての行LCRがエラー・キューに移動されます。
この例では、apply_name
パラメータがNULL
に設定されています。したがって、エラー・ハンドラは、データベース内のすべての適用プロセスで使用される汎用エラー・ハンドラになります。
次のプロシージャを実行してエラー・ハンドラを設定します。
BEGIN DBMS_APPLY_ADM.SET_DML_HANDLER( object_name => 'hr.regions', object_type => 'TABLE', operation_name => 'INSERT', error_handler => TRUE, user_procedure => 'strmadmin.errors_pkg.regions_pk_error', apply_database_link => NULL, apply_name => NULL); END; /
エラー・ハンドラがすでに設定されている場合は、SET_DML_HANDLER
プロシージャを実行してエラー・ハンドラを変更できます。
17.12.3 エラー・ハンドラの設定解除
エラー・ハンドラの設定を解除するには、DBMS_APPLY_ADM
パッケージのSET_DML_HANDLER
プロシージャを使用します。このプロシージャを実行するときに、特定の表に対する特定の操作について、user_procedure
パラメータをNULL
に設定します。
たとえば、次のプロシージャでは、hr.regions
表に対するINSERT
操作について、エラー・ハンドラの設定が解除されます。
BEGIN DBMS_APPLY_ADM.SET_DML_HANDLER( object_name => 'hr.regions', object_type => 'TABLE', operation_name => 'INSERT', user_procedure => NULL, apply_name => NULL); END; /
注意:
error_handler
パラメータを指定する必要はありません。
17.13 適用エラーの管理
次の各項では、適用エラーの再試行と削除の手順について説明します。
関連項目:
-
「エラー・キュー」
-
Oracle Enterprise Manager Cloud Controlでの適用エラーの管理については、Oracle Enterprise Manager Cloud Controlのオンライン・ヘルプを参照
-
適用エラーの考えられる原因の詳細は、「表へのDML変更の適用に関する考慮事項」を参照
17.13.1 適用エラー・トランザクションの再試行
特定のエラー・トランザクション、または適用プロセスのすべてのエラー・トランザクションを再試行できます。場合によっては、エラー・トランザクションを再試行する前に、データベース・オブジェクトに対してDML変更またはDDL変更を行い、1つ以上の適用エラーの原因となった状態を修正する必要があります。また、同じデータベース・オブジェクトに対する変更を取得するように1つ以上の取得プロセスまたは同期取得を構成しているときに、変更の取得が不要になる可能性があります。この場合は、変更を行うセッションのセッション・タグを、取得されない値に設定できます。
次の各項では、適用エラー・トランザクションの再試行の詳細を説明します。
関連項目:
現行セッションで生成されるタグの値の設定の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
17.13.1.1 特定の適用エラー・トランザクションの再試行
エラー・トランザクションを再試行する場合は、直接実行することも、ユーザー・プロシージャにエラー・トランザクションを送信して変更した後で実行することもできます。次の各項では、各方法の手順について説明します。
関連項目:
EXECUTE_ERROR
プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
17.13.1.1.1 ユーザー・プロシージャを使用しない特定の適用エラー・トランザクションの再試行
適用エラーの原因となった条件を修正した後に、ユーザー・プロシージャを指定せずにDBMS_APPLY_ADM
パッケージのEXECUTE_ERROR
プロシージャを実行して、トランザクションを再試行できます。この場合、トランザクションはカスタム処理を使用せずに実行されます。
たとえば、トランザクション識別子が5.4.312
のトランザクションを再試行するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.EXECUTE_ERROR( local_transaction_id => '5.4.312', execute_as_user => FALSE, user_procedure => NULL); END; /
execute_as_user
がTRUE
の場合は、適用プロセスでは、現行ユーザーのセキュリティ・コンテキスト内でトランザクションが実行されます。execute_as_user
がFALSE
の場合、適用プロセスでは、トランザクションの元の受信者のセキュリティ・コンテキスト内でトランザクションが実行されます。元の受信者とは、エラー発生時にトランザクションを処理していたユーザーです。
いずれの場合も、トランザクションを実行するユーザーには、適用オブジェクトに対するDML変更およびDDL変更を実行するための権限と、任意の適用ハンドラを実行するための権限が必要です。また、このユーザーには、適用プロセスで使用されるキューに対するデキュー権限も必要です。
17.13.1.1.2 ユーザー・プロシージャを使用した特定の適用エラー・トランザクションの再試行
DBMS_APPLY_ADM
パッケージのEXECUTE_ERROR
プロシージャを実行してエラー・トランザクションを再試行できます。また、ユーザー・プロシージャを指定して、トランザクションの実行前に、トランザクション内の1つ以上のメッセージを変更することもできます。この変更によって、トランザクションが正常に実行できるはずです。トランザクション内のメッセージは、LCRまたはユーザー・メッセージです。
たとえば、競合のために適用エラーが発生したとします。エラー・トランザクションを検証すると、行LCRのsalary
列の古い値が間違っていることが判明しました。具体的には、hr.employees
表のemployee_id
が197
の従業員について、給料の現行の値が、行LCRにおけるこの従業員の給料の古い値と一致していません。hr.employees
表で、この従業員の現行の値が3250
であるとします。
この場合、次のユーザー・プロシージャで、エラーの原因となった行LCRの給料を変更します。
CREATE OR REPLACE PROCEDURE strmadmin.modify_emp_salary( in_any IN ANYDATA, error_record IN DBA_APPLY_ERROR%ROWTYPE, error_message_number IN NUMBER, messaging_default_processing IN OUT BOOLEAN, out_any OUT ANYDATA) AS row_lcr SYS.LCR$_ROW_RECORD; row_lcr_changed BOOLEAN := FALSE; res NUMBER; ob_owner VARCHAR2(32); ob_name VARCHAR2(32); cmd_type VARCHAR2(30); employee_id NUMBER; BEGIN IF in_any.getTypeName() = 'SYS.LCR$_ROW_RECORD' THEN -- Access the LCR res := in_any.GETOBJECT(row_lcr); -- Determine the owner of the database object for the LCR ob_owner := row_lcr.GET_OBJECT_OWNER; -- Determine the name of the database object for the LCR ob_name := row_lcr.GET_OBJECT_NAME; -- Determine the type of DML change cmd_type := row_lcr.GET_COMMAND_TYPE; IF (ob_owner = 'HR' AND ob_name = 'EMPLOYEES' AND cmd_type = 'UPDATE') THEN -- Determine the employee_id of the row change IF row_lcr.GET_VALUE('old', 'employee_id') IS NOT NULL THEN employee_id := row_lcr.GET_VALUE('old', 'employee_id').ACCESSNUMBER(); IF (employee_id = 197) THEN -- error_record.message_number should equal error_message_number row_lcr.SET_VALUE( value_type => 'OLD', column_name => 'salary', column_value => ANYDATA.ConvertNumber(3250)); row_lcr_changed := TRUE; END IF; END IF; END IF; END IF; -- Specify that the apply process continues to process the current message messaging_default_processing := TRUE; -- assign out_any appropriately IF row_lcr_changed THEN out_any := ANYDATA.ConvertObject(row_lcr); ELSE out_any := in_any; END IF; END; /
トランザクション識別子が5.6.924
のトランザクションを再試行する際、実行前にstrmadmin
スキーマ内のmodify_emp_salary
プロシージャでトランザクションを処理するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.EXECUTE_ERROR( local_transaction_id => '5.6.924', execute_as_user => FALSE, user_procedure => 'strmadmin.modify_emp_salary'); END; /
注意:
プロシージャを実行するユーザーは、DBA_APPLY_ERROR
データ・ディクショナリ・ビューに対するSELECT
権限を持っている必要があります。
関連項目:
17.13.1.2 適用プロセスのすべてのエラー・トランザクションの再試行
適用プロセスについて、すべての適用エラーの原因となった条件を修正した後に、DBMS_APPLY_ADM
パッケージのEXECUTE_ALL_ERRORS
プロシージャを実行してすべてのエラー・トランザクションを再試行できます。たとえば、適用プロセスstrm01_apply
のすべてのエラー・トランザクションを再試行するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.EXECUTE_ALL_ERRORS( apply_name => 'strm01_apply', execute_as_user => FALSE); END; /
注意:
apply_name
パラメータに対してNULL
を指定した場合に、複数の適用プロセスが存在すると、すべての適用プロセスのすべての適用エラーが再試行されます。
17.13.2 適用エラー・トランザクションの削除
特定のエラー・トランザクションまたは適用プロセスのすべてのエラー・トランザクションを削除できます。
17.13.2.1 特定の適用エラー・トランザクションの削除
エラー・トランザクションを適用する必要がない場合は、DBMS_APPLY_ADM
パッケージのDELETE_ERROR
プロシージャを使用して、エラー・キューからトランザクションを削除できます。たとえば、トランザクション識別子が5.4.312
のトランザクションを削除するには、次のプロシージャを実行します。
EXEC DBMS_APPLY_ADM.DELETE_ERROR(local_transaction_id => '5.4.312');
17.13.2.2 適用プロセスのすべてのエラー・トランザクションの削除
すべてのエラー・トランザクションを適用しない場合は、DBMS_APPLY_ADM
パッケージのDELETE_ALL_ERRORS
プロシージャを実行して、すべてのエラー・トランザクションを削除できます。たとえば、適用プロセスstrm01_apply
のすべてのエラー・トランザクションを削除するには、次のプロシージャを実行します。
EXEC DBMS_APPLY_ADM.DELETE_ALL_ERRORS(apply_name => 'strm01_apply');
注意:
apply_name
パラメータに対してNULL
を指定した場合に、複数の適用プロセスが存在すると、すべての適用プロセスのすべての適用エラーが削除されます。
17.14 表の代替キー列の管理
17.14.1 表の代替キー列の設定
適用プロセスによって表に変更が適用される場合、代替キー列は、主キーを含む表の主キー列と置き換えられるか、または主キーを含まない表の主キー列として使用できます。表の代替キー列を設定するには、DBMS_APPLY_ADM
パッケージのSET_KEY_COLUMNS
プロシージャを使用します。この設定は、ローカルの変更をデータベースに適用する適用プロセスすべてに適用されます。
たとえば、hr.employees
表の代替キー列をfirst_name
、last_name
およびhire_date
の各列に設定して、employee_id
列を置換するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_KEY_COLUMNS( object_name => 'hr.employees', column_list => 'first_name,last_name,hire_date'); END; /
注意:
-
宛先データベースの
column_list
またはcolumn_table
パラメータで代替キー列として指定されたすべての列に対して、ソース・データベースで無条件サプリメンタル・ログ・グループを指定する必要があります。この例では、hr.employees
表のfirst_name
、last_name
およびhire_date
列を含む無条件サプリメンタル・ログ・グループを指定します。 -
適用プロセスによってOracle以外のリモート・データベースに変更が適用される場合、この適用プロセスでは、同じ表に対して別の代替キー列を使用できます。
DBMS_APPLY_ADM
パッケージのSET_KEY_COLUMNS
プロシージャを実行して、apply_database_link
パラメータをNULL
以外の値に設定することにより、Oracle以外のリモート・データベースに適用される変更に対して代替キー列を指定できます。
17.14.2 表の代替キー列の削除
表の代替キー列を削除するには、DBMS_APPLY_ADM
パッケージのSET_KEY_COLUMNS
プロシージャでcolumn_list
またはcolumn_table
パラメータにNULL
を指定します。表に主キーがある場合、代替主キーを削除すると、適用プロセスではデータベースに対するローカルの変更にその表の主キーが使用されます。
たとえば、hr.employees
表の代替キー列を削除するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_KEY_COLUMNS( object_name => 'hr.employees', column_list => NULL); END; /
17.15 仮想依存性定義の使用
仮想依存性定義とは、宛先データベースで適用されるトランザクション間の依存性を検出するために、適用プロセスで使用される依存性の記述です。仮想依存性定義は、適用プロセスの並列性が1より大きく、依存性が宛先データベースのデータ・ディクショナリに制約によって記述されていない場合に役立ちます。仮想依存性定義には、値の依存性とオブジェクト依存性の2つのタイプがあります。
値の依存性は、一意キーなどの表制約、または2つ以上の表の列間の関連を定義します。オブジェクト依存性は、宛先データベースの2つのオブジェクト間の親子関係を定義します。
次の各項では、仮想依存性定義の使用について説明します。
関連項目:
仮想依存性定義の詳細は、「適用プロセスおよび依存性」を参照
17.15.1 値の依存性の設定および設定解除
DBMS_APPLY_ADM
パッケージのSET_VALUE_DEPENDENCY
プロシージャを使用して、値の依存性を設定または設定解除します。次の各項では、値の依存性を使用する場合の使用例について説明します。
17.15.1.1 スキーマの相違および値の依存性
この使用例に関連する環境では、ソース・データベースと宛先データベースの間で数多くの表を共有するものの、これら2つのデータベースで表を所有するスキーマが異なっています。また、このレプリケーション環境では、ソース・データベースが米国に存在し、宛先データベースが英国に存在します。ある設計会社が製品設計を作成するのに多くの表を使用していますが、ソース・データベースの表では米国の測定単位(インチ、フィートなど)が使用され、宛先データベースの表ではメートル法の測定単位が使用されています。ソース・データベースでデータベース・オブジェクトを所有するスキーマの名前はus_designs
、宛先データベースでのスキーマの名前はuk_designs
です。したがって、適用前に共有データベース・オブジェクトのスキーマ名を変更する必要があり、すべての測定単位を米国の測定単位からメートル法の測定単位に変換する必要があります。データベース・オブジェクト間に依存性を持たせるために、両方のデータベースで同じ制約を使用します。
必要となる変更はルールベースの変換を使用して行うことができますが、ここでの目的は複数のLCRをパラレルで適用することです。ルールベースの変換では、LCRをシリアルに適用する必要があります。そのため、宛先データベースでのプロシージャDMLハンドラがLCRに必要な変更を行うように構成され、適用プロセスの並列性が5に設定されます。この環境では、宛先データベースにはソース・データベースから送信されるLCRのスキーマus_designs
に関する情報がありません。適用プロセスではLCRを適用ハンドラに渡す前に依存性を計算するため、適用プロセスにLCR間の依存性に関する情報が通知される必要があります。値の依存性を使用すると、これらの依存性を記述できます。
この使用例では、複数の表で異なる設計が作成され、これらの表にそれぞれ主キーが存在するとします。これらの表の1つにdesign_53
があり、その主キー列はkey_53
です。また、表all_designs_summary
には個別の設計すべての概要が含まれ、この表には各設計表の外部キー列が含まれます。all_designs_summary
には、design_53
表の主キーの外部キーであるkey_53列が含まれます。これらの表の関係について適用プロセスに通知するには、次のプロシージャを実行して、宛先データベースで値の依存性を作成します。
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'key_53_foreign_key', object_name => 'us_designs.design_53', attribute_list => 'key_53'); END; /
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'key_53_foreign_key', object_name => 'us_designs.all_designs_summary', attribute_list => 'key_53'); END; /
LCRにはソース・データベースのスキーマが含まれるため、値の依存性でそのソース・データベースのスキーマ(us_designs
)が使用されていることに注意してください。適用プロセスによって行LCRがハンドラに渡された後、プロシージャDMLハンドラによってスキーマがuk_designs
に変更されます。
値の依存性を設定解除するには、SET_VALUE_DEPENDENCY
プロシージャを実行して、dependency_name
パラメータに値の依存性の名前を指定し、object_name
パラメータにNULL
を指定します。たとえば、以前に設定した値の依存性key_53_foreign_key
を設定解除するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'key_53_foreign_key', object_name => NULL, attribute_list => NULL); END; /
関連項目:
17.15.1.2 宛先データベースでの未定義の制約および値の依存性
この使用例に関連する環境では、ソース・データベースの共有表に対して外部キー制約が使用され、宛先データベースのこれらの表に対しては制約が使用されていません。このレプリケーション環境では、宛先データベースがデータ・ウェアハウスとして使用されており、問合せよりもデータベースへのデータの書込みの方がはるかに頻繁に行われます。書込み操作を最適化するために、宛先データベースでは制約が定義されていません。
このような環境では、トランザクションを一貫して適用するために、宛先データベースで実行中の適用プロセスに制約について通知する必要があります。値の依存性を使用すると、適用プロセスにこれらの制約について通知できます。
たとえば、oe
スキーマ内のorders
およびorder_items
表が、この環境のソース・データベースと宛先データベース間で共有されているとします。ソース・データベースでは、order_id
列はorders
表の主キーであり、order_items
表のorder_id
列はorders
表の主キー列と一致する外部キーです。宛先データベースでは、これらの制約は削除されています。次のプロシージャを実行し、適用プロセスにこれらの表の列の関係について通知する値の依存性を宛先データベースで作成します。
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'order_id_foreign_key', object_name => 'oe.orders', attribute_list => 'order_id'); END; /
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'order_id_foreign_key', object_name => 'oe.order_items', attribute_list => 'order_id'); END; /
また、この環境では、適用プロセスでトランザクションが一貫して適用できるように、次のアクションを実行する必要があります。
-
ソース・データベースで一意キーまたはビットマップ索引を含む各列に対して値の依存性を設定する必要があります。
-
DBMS_APPLY_ADM.SET_KEY_COLUMNS
プロシージャを実行して、ソース・データベースで主キー列である列の代替キー列を設定する必要があります。
以前に設定した値の依存性を設定解除するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.SET_VALUE_DEPENDENCY( dependency_name => 'order_id_foreign_key', object_name => NULL, attribute_list => NULL); END; /
関連項目:
17.15.2 オブジェクト依存性の作成および削除
DBMS_APPLY_ADM
パッケージのCREATE_OBJECT_DEPENDENCY
およびDROP_OBJECT_DEPENDENCY
プロシージャを実行して、オブジェクト依存性を作成または削除します。
次の各項では、オブジェクト依存性の作成および削除の詳しい手順について説明します。
17.15.2.1 オブジェクト依存性の作成
特定の表の行LCRが常に別の表の行LCRより前に適用される必要があり、宛先データベースのデータ・ディクショナリにこの関係を持たせる制約が含まれていない場合に、オブジェクト依存性を使用できます。オブジェクト依存性を定義する場合、最初に適用される必要がある行LCRを含む表が親表であり、2番目に適用される必要がある行LCRを含む表が子表です。
たとえば、次の特性を持つOracle Streamsレプリケーション環境を考えます。
-
ord
スキーマ内の次の表はソース・データベースと宛先データベース間で共有されます。-
customers
表には、顧客に関する情報(各顧客の出荷先住所など)が含まれます。 -
orders
表には、各注文に関する情報が含まれます。 -
order_items
表には、各注文内のアイテムに関する情報が含まれます。 -
ship_orders
表には、出荷の準備が完了している注文に関する情報は含まれますが、顧客の詳細情報または各注文で出荷される個別のアイテムに関する情報は含まれません。
-
-
ship_orders
表には、制約によって定義された、他の表との関係は存在しません。 -
注文に関する情報はソース・データベースに入力され、宛先データベースに伝播されて適用されます。
-
宛先データベースのサイトは注文が顧客に出荷されるウェアハウスです。このサイトで、プロシージャDMLハンドラによって
ship_orders
、customers
、orders
およびorder_items
の各表の情報が使用され、顧客の出荷先住所と出荷するアイテムを含むレポートが生成されます。
プロシージャDMLハンドラによって生成されたレポートの情報は、出荷注文記録が作成された時間と一貫性がある必要があります。宛先データベースのオブジェクト依存性によって、この目的が達成されます。この場合、ship_orders
表は子表customers
、orders
およびorder_items
の親表です。ship_orders
がこれらの表の親であるため、ship_orders
表の記録が入力された後にこれらの表に対して行われた変更は、プロシージャDMLハンドラによって出荷注文のレポートが生成されるまで適用されません。
これらのオブジェクト依存性を作成するには、宛先データベースで次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.CREATE_OBJECT_DEPENDENCY( object_name => 'ord.customers', parent_object_name => 'ord.ship_orders'); END; /
BEGIN DBMS_APPLY_ADM.CREATE_OBJECT_DEPENDENCY( object_name => 'ord.orders', parent_object_name => 'ord.ship_orders'); END; /
BEGIN DBMS_APPLY_ADM.CREATE_OBJECT_DEPENDENCY( object_name => 'ord.order_items', parent_object_name => 'ord.ship_orders'); END; /
関連項目:
17.15.2.2 オブジェクト依存性の削除
「オブジェクト依存性の作成」で作成したオブジェクト依存性を削除するには、次のプロシージャを実行します。
BEGIN DBMS_APPLY_ADM.DROP_OBJECT_DEPENDENCY( object_name => 'ord.customers', parent_object_name => 'ord.ship_orders'); END; /
BEGIN DBMS_APPLY_ADM.DROP_OBJECT_DEPENDENCY( object_name => 'ord.orders', parent_object_name => 'ord.ship_orders'); END; /
BEGIN DBMS_APPLY_ADM.DROP_OBJECT_DEPENDENCY( object_name => 'ord.order_items', parent_object_name => 'ord.ship_orders'); END; /
17.16 適用プロセスの削除
既存の適用プロセスを削除するには、DBMS_APPLY_ADM
パッケージのDROP_APPLY
プロシージャを実行します。たとえば、次のプロシージャでは、適用プロセスstrm02_apply
が削除されます。
BEGIN DBMS_APPLY_ADM.DROP_APPLY( apply_name => 'strm02_apply', drop_unused_rule_sets => TRUE); END; /
drop_unused_rule_sets
パラメータがTRUE
に設定されているため、このプロシージャではstrm02_apply
適用プロセスで使用されているルール・セットも削除されます。ただし、他のOracle Streamsクライアントで使用されているルール・セットは削除されません。drop_unused_rule_sets
パラメータがTRUE
に設定されている場合は、適用プロセスのポジティブ・ルール・セットとネガティブ・ルール・セットの両方が削除されることがあります。このプロシージャによってルール・セットが削除された場合、そのルール・セット内のルールのうち、他のルール・セットに含まれていないルールも削除されます。
適用プロセスを削除しようとしたときに、指定した適用プロセスのエラー・キューにエラーが存在すると、エラーが発生します。このため、適用プロセスのエラー・キューにエラーが存在する場合は、適用プロセスを削除する前にエラーを削除します。
関連項目:
-
「適用エラーの管理」