ヘッダーをスキップ
Oracle® Streamsレプリケーション管理者ガイド
12cリリース1 (12.1)
B71328-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

14 論理変更レコード(LCR)の管理

この章では、Oracle Streamsレプリケーション環境で論理変更レコード(LCR)を管理する方法について説明します。

この章の内容は次のとおりです。


関連項目:

LCRの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』および『Oracle Streams概要および管理』を参照してください。

LCRを管理するための要件

この項では、論理変更レコード(LCR)を作成または変更するための要件について説明します。LCR型のコンストラクタを使用してLCRを作成し、そのLCRをANYDATAキューの永続キュー部分にエンキューできます。このようなLCRは、永続LCRです。

また、適用ハンドラまたはルールベースの変換を使用して、LCRを変更できます。取得LCRまたは永続LCRを変更できます。

LCRを管理するときには、次の要件を満たしていることを確認してください。

  • 行LCRを作成または変更する場合は、command_type属性に古い列値の有無および新しい列値の有無との一貫性があることを確認してください。

  • DDL LCRを作成または変更する場合は、ddl_textbase_table_namebase_table_ownerobject_typeobject_ownerobject_nameおよびcommand_type属性と一貫していることを確認してください。

  • ユーザーが構成する行LCRの列に許可されるデータ型は、次のとおりです。

    • CHAR

    • VARCHAR2

    • NCHAR

    • NVARCHAR2

    • NUMBER

    • DATE

    • BINARY_FLOAT

    • BINARY_DOUBLE

    • RAW

    • TIMESTAMP

    • TIMESTAMP WITH TIME ZONE

    • TIMESTAMP WITH LOCAL TIME ZONE

    • INTERVAL YEAR TO MONTH

    • INTERVAL DAY TO SECOND

    ユーザーが構成する行LCRの列に許可されるデータ型は、これらのデータ型のみです。ただし、特定の方法を使用すると、LOB情報を含むLCRを構成できます。また、取得プロセスによって取得されるLCRでは、サポートされるデータ型がより多くなっていますが、同期取得によって取得されるLCRでは、サポートされるデータ型がより少なくなっています。


関連項目:

  • 適用ハンドラの詳細は、『Oracle Streams概要および管理』を参照してください。

  • 「LOB列を含むLCRの管理」

  • 取得プロセスまたは同期取得によって取得されるデータ型、およびルールベースの変換の詳細は、『Oracle Streams概要および管理』を参照してください。


LCRの構成とエンキュー

次のLCRコンストラクタを使用してLCRを作成します。

  • データ操作言語(DML)文によって生じた行に対する変更を含む行LCRを作成するには、SYS.LCR$_ROW_RECORDコンストラクタを使用します。

  • データ定義言語(DDL)変更を含むDDL LCRを作成するには、SYS.LCR$_DDL_RECORDコンストラクタを使用します。各DDL LCRのddl_text属性に指定するDDLテキストが、Oracle SQL構文に準拠していることを確認してください。

次の例では、Oracle Database内のキューと、そのキューに関連付けられた適用プロセスを作成します。次に、渡された情報に基づいて行LCRを構成し、それをキューにエンキューするPL/SQLプロシージャを作成します。この例では、Oracle Streams管理者strmadminを構成して、この管理者にDBAロールを付与していると想定しています。

手順は次のとおりです。

  1. SQL*Plusで、管理ユーザーとしてデータベースに接続します。

    SQL*Plusでデータベースに接続する手順については、『Oracle Database管理者ガイド』を参照してください。

  2. Oracle Streams管理者にDBMS_STREAMS_MESSAGINGパッケージに対するEXECUTE権限を付与します。次に例を示します。

    GRANT EXECUTE ON DBMS_STREAMS_MESSAGING TO strmadmin;
    

    手順9のPL/SQLプロシージャ内でこのパッケージのプロシージャをコールするため、このパッケージに対する明示的なEXECUTE権限が必要です。この場合、ロールを介して権限を付与するのみでは不十分です。

  3. SQL*Plusで、Oracle Streams管理者としてデータベースに接続します。

  4. Oracle DatabaseにANYDATAキューを作成します。

    BEGIN 
      DBMS_STREAMS_ADM.SET_UP_QUEUE(
        queue_table          =>  'strm04_queue_table',
        storage_clause       =>  NULL,
        queue_name           =>  'strm04_queue');
    END;
    /
    
  5. キュー内のメッセージを受信するOracle Databaseで、適用プロセスを作成します。適用プロセスでは、取得LCRではなく永続LCRが適用されるため、この適用プロセスの作成時には、apply_capturedパラメータをFALSEに設定してください。また、hr.regions表に変更が適用され、適用ユーザーにはこの表にDML変更を加える権限が必要であるため、apply_userパラメータがhrに設定されていることを確認してください。

    BEGIN
      DBMS_APPLY_ADM.CREATE_APPLY(
         queue_name      => 'strm04_queue',
         apply_name      => 'strm04_apply',
         apply_captured  => FALSE,
         apply_user      => 'hr');
    END;
    /
    
  6. 適用プロセスのポジティブ・ルール・セットを作成し、DML変更をdbs1.example.comソース・データベースに作成されたhr.regions表に適用するルールを追加します。

    BEGIN 
      DBMS_STREAMS_ADM.ADD_TABLE_RULES(
        table_name          =>  'hr.regions',
        streams_type        =>  'apply',
        streams_name        =>  'strm04_apply',
        queue_name          =>  'strm04_queue',
        include_dml         =>  TRUE,
        include_ddl         =>  FALSE,
        include_tagged_lcr  =>  FALSE,
        source_database     =>  'dbs1.example.com',
        inclusion_rule      =>  TRUE);
    END;
    /
    
  7. 適用プロセスのdisable_on_errorパラメータをnに設定します。

    BEGIN
      DBMS_APPLY_ADM.SET_PARAMETER(
        apply_name  => 'strm04_apply', 
        parameter   => 'disable_on_error', 
        value       => 'N');
    END;
    /
    
  8. 適用プロセスを起動します。

    EXEC DBMS_APPLY_ADM.START_APPLY('strm04_apply');
    
  9. 行LCRを構成して手順4で作成したキューにエンキューするプロシージャconstruct_row_lcrを作成します。

    CREATE OR REPLACE PROCEDURE construct_row_lcr(
                     source_dbname  VARCHAR2,
                     cmd_type       VARCHAR2,
                     obj_owner      VARCHAR2,
                     obj_name       VARCHAR2,
                     old_vals       SYS.LCR$_ROW_LIST,
                     new_vals       SYS.LCR$_ROW_LIST) AS
      row_lcr        SYS.LCR$_ROW_RECORD;
    BEGIN
      -- Construct the LCR based on information passed to procedure
      row_lcr := SYS.LCR$_ROW_RECORD.CONSTRUCT(
        source_database_name  =>  source_dbname,
        command_type          =>  cmd_type,
        object_owner          =>  obj_owner,
        object_name           =>  obj_name,
        old_values            =>  old_vals,
        new_values            =>  new_vals);
      -- Enqueue the created row LCR
      DBMS_STREAMS_MESSAGING.ENQUEUE(
        queue_name         =>  'strm04_queue',
        payload            =>  ANYDATA.ConvertObject(row_lcr));
    END construct_row_lcr;
    /
    

    注意:

    トランザクション識別子やSCNは適用プロセスで生成されてメモリーに格納されるため、これらの値をLCRの作成時にアプリケーションで指定する必要はありません。LCRでトランザクション識別子またはSCNを指定しても、適用プロセスでは無視され、新規の値が割り当てられます。


    関連項目:

    LCRコンストラクタの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

  10. 手順5で作成したconstruct_row_lcrプロシージャを使用してLCRを作成し、エンキューします。

    1. SQL*Plusで、Oracle Streams管理者としてデータベースに接続します。

    2. hr.regions表に1行を挿入する行LCRを作成します。

      DECLARE
        newunit1  SYS.LCR$_ROW_UNIT;
        newunit2  SYS.LCR$_ROW_UNIT;
        newvals   SYS.LCR$_ROW_LIST;
      BEGIN
        newunit1 := SYS.LCR$_ROW_UNIT(
          'region_id', 
          ANYDATA.ConvertNumber(5),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        newunit2 := SYS.LCR$_ROW_UNIT(
          'region_name', 
          ANYDATA.ConvertVarchar2('Moon'),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        newvals := SYS.LCR$_ROW_LIST(newunit1,newunit2);
      construct_row_lcr(
        source_dbname  =>  'dbs1.example.com',
        cmd_type       =>  'INSERT',
        obj_owner      =>  'hr',
        obj_name       =>  'regions',
        old_vals       =>  NULL,
        new_vals       =>  newvals);
      END;
      /
      COMMIT;
      
    3. SQL*Plusで、hrユーザーとしてデータベースに接続します。

    4. hr.regions表を問い合せて、適用済の行の変更を表示します。region_id5である行は、region_nameMoonとなっているはずです。

      SELECT * FROM hr.regions;
      
    5. SQL*Plusで、Oracle Streams管理者としてデータベースに接続します。

    6. hr.regions表から1行を更新する行LCRを作成します。

      DECLARE
        oldunit1  SYS.LCR$_ROW_UNIT;
        oldunit2  SYS.LCR$_ROW_UNIT;
        oldvals   SYS.LCR$_ROW_LIST;
        newunit1  SYS.LCR$_ROW_UNIT;
        newvals   SYS.LCR$_ROW_LIST;
      BEGIN
        oldunit1 := SYS.LCR$_ROW_UNIT(
          'region_id', 
          ANYDATA.ConvertNumber(5),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        oldunit2 := SYS.LCR$_ROW_UNIT(
          'region_name', 
          ANYDATA.ConvertVarchar2('Moon'),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        oldvals := SYS.LCR$_ROW_LIST(oldunit1,oldunit2);
        newunit1 := SYS.LCR$_ROW_UNIT(
          'region_name', 
          ANYDATA.ConvertVarchar2('Mars'),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        newvals := SYS.LCR$_ROW_LIST(newunit1);
      construct_row_lcr(
        source_dbname  =>  'dbs1.example.com',
        cmd_type       =>  'UPDATE',
        obj_owner      =>  'hr',
        obj_name       =>  'regions',
        old_vals       =>  oldvals,
        new_vals       =>  newvals);
      END;
      /
      COMMIT;
      
    7. SQL*Plusで、hrユーザーとしてデータベースに接続します。

    8. hr.regions表を問い合せて、適用済の行の変更を表示します。region_id5である行は、region_nameMarsとなっているはずです。

      SELECT * FROM hr.regions;
      
    9. hr.regions表から1行を削除する行LCRを作成します。

      DECLARE
        oldunit1  SYS.LCR$_ROW_UNIT;
        oldunit2  SYS.LCR$_ROW_UNIT;
        oldvals   SYS.LCR$_ROW_LIST;
      BEGIN
        oldunit1 := SYS.LCR$_ROW_UNIT(
          'region_id', 
          ANYDATA.ConvertNumber(5),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        oldunit2 := SYS.LCR$_ROW_UNIT(
          'region_name',
          ANYDATA.ConvertVarchar2('Mars'),
          DBMS_LCR.NOT_A_LOB,
          NULL,
          NULL);
        oldvals := SYS.LCR$_ROW_LIST(oldunit1,oldunit2);
      construct_row_lcr(
        source_dbname  =>  'dbs1.example.com',
        cmd_type       =>  'DELETE',
        obj_owner      =>  'hr',
        obj_name       =>  'regions',
        old_vals       =>  oldvals,
        new_vals       =>  NULL);
      END;
      /
      COMMIT;
      
    10. SQL*Plusで、hrユーザーとしてデータベースに接続します。

    11. hr.regions表を問い合せて、適用済の行の変更を表示します。region_id5である行は、削除されているはずです。

      SELECT * FROM hr.regions;
      

LCRの実行

行LCRおよびDDL LCR用に、個別のEXECUTEメンバー・プロシージャがあります。これらのメンバー・プロシージャを使用すると、現行ユーザーのセキュリティ・ドメインでLCRが実行されます。LCRが正常に実行されると、LCRに記録された変更がローカル・データベースに対して行われます。ここでは、行LCRおよびDDL LCRの実行について説明します。

行LCRの実行

行LCR用のEXECUTEメンバー・プロシージャは、LCR$_ROW_RECORD型のサブプログラムです。行LCRにEXECUTEメンバー・プロシージャを実行すると、行LCRが実行されます。行LCRが適用プロセスによって実行される場合、LCRに対して実行される適用プロセスのハンドラは実行されません。

次のいずれかの条件が満たされる場合は、行LCRにEXECUTEメンバー・プロシージャを実行できます。

  • LCRが適用ハンドラによって処理されている。

  • LCRがキューに存在し、このLCRが適用プロセス、アプリケーションまたはユーザーによって最後にエンキューされたLCRである。

  • LCRがLCR$_ROW_RECORDコンストラクタ・ファンクションを使用して構成されているが、エンキューされていない。

  • LCRがエラー・キューに存在する。

行LCRにEXECUTEメンバー・プロシージャを実行する場合、競合解消を実行するかどうかをconflict_resolutionパラメータで制御します。具体的には、conflict_resolutionパラメータをTRUEに設定した場合、変更対象の表に定義されている競合解消を使用して、LCRの実行によって発生する競合が解消されます。conflict_resolutionパラメータをFALSEに設定した場合、競合解消は使用されません。conflict_resolutionパラメータを設定しない場合、またはNULLに設定した場合は、エラーが発生します。


注意:

カスタム・ルールベースの変換では、行LCRにEXECUTEメンバー・プロシージャを実行しないでください。実行すると、トランザクション・コンテキストの外部で行LCRが実行される場合があります。


関連項目:

  • 『Oracle Streams概要および管理』

  • 行LCRおよびLCR$_ROW_RECORD型の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


行LCRの構成および実行の例

この項の例では、PL/SQLプロシージャを作成し、行LCRを構成および実行することによってhr.jobs表の行の挿入、更新および削除を実行します。行LCRは、適用プロセスによってエンキューまたは処理されずに実行されます。この例では、Oracle Streams管理者strmadminを構成して、この管理者にDBAロールを付与していると想定しています。

手順は次のとおりです。

  1. SQL*Plusで、Oracle Streams管理者としてデータベースに接続します。

    SQL*Plusでデータベースに接続する手順については、『Oracle Database管理者ガイド』を参照してください。

  2. 行LCRを実行するPL/SQLプロシージャexecute_row_lcrを作成します。

    CREATE OR REPLACE PROCEDURE execute_row_lcr(
                     source_dbname  VARCHAR2,
                     cmd_type       VARCHAR2,
                     obj_owner      VARCHAR2,
                     obj_name       VARCHAR2,
                     old_vals       SYS.LCR$_ROW_LIST,
                     new_vals       SYS.LCR$_ROW_LIST) as
      xrow_lcr  SYS.LCR$_ROW_RECORD;
    BEGIN
      -- Construct the row LCR based on information passed to procedure
      xrow_lcr := SYS.LCR$_ROW_RECORD.CONSTRUCT(
        source_database_name => source_dbname,
        command_type         => cmd_type,
        object_owner         => obj_owner,
        object_name          => obj_name,
        old_values           => old_vals,
        new_values           => new_vals);
      -- Execute the row LCR
      xrow_lcr.EXECUTE(FALSE);
    END execute_row_lcr;
    /
    
  3. hr.jobs表に行を挿入する行LCRを実行するPL/SQLプロシージャinsert_job_lcrを作成します。

    CREATE OR REPLACE PROCEDURE insert_job_lcr(
                     j_id     VARCHAR2,
                     j_title  VARCHAR2,
                     min_sal  NUMBER,
                     max_sal  NUMBER) AS
      xrow_lcr   SYS.LCR$_ROW_RECORD;
      col1_unit  SYS.LCR$_ROW_UNIT;
      col2_unit  SYS.LCR$_ROW_UNIT;
      col3_unit  SYS.LCR$_ROW_UNIT;
      col4_unit  SYS.LCR$_ROW_UNIT;
      newvals    SYS.LCR$_ROW_LIST;
    BEGIN
      col1_unit := SYS.LCR$_ROW_UNIT(
        'job_id', 
        ANYDATA.ConvertVarchar2(j_id),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      col2_unit := SYS.LCR$_ROW_UNIT(
        'job_title', 
        ANYDATA.ConvertVarchar2(j_title),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      col3_unit := SYS.LCR$_ROW_UNIT(
        'min_salary', 
        ANYDATA.ConvertNumber(min_sal),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      col4_unit := SYS.LCR$_ROW_UNIT(
        'max_salary', 
        ANYDATA.ConvertNumber(max_sal),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      newvals := SYS.LCR$_ROW_LIST(col1_unit,col2_unit,col3_unit,col4_unit);
      -- Execute the row LCR
      execute_row_lcr(
        source_dbname => 'DB1.EXAMPLE.COM',
        cmd_type      => 'INSERT',
        obj_owner     => 'HR',
        obj_name      => 'JOBS',
        old_vals      => NULL,
        new_vals      => newvals);  
    END insert_job_lcr;
    /
    
  4. hr.jobs表の行のmax_salary値を更新する行LCRを実行するPL/SQLプロシージャupdate_max_salary_lcrを作成します。

    CREATE OR REPLACE PROCEDURE update_max_salary_lcr(
                     j_id         VARCHAR2,
                     old_max_sal NUMBER,
                     new_max_sal NUMBER) AS
      xrow_lcr      SYS.LCR$_ROW_RECORD;
      oldcol1_unit  SYS.LCR$_ROW_UNIT;
      oldcol2_unit  SYS.LCR$_ROW_UNIT;
      newcol1_unit  SYS.LCR$_ROW_UNIT;
      oldvals       SYS.LCR$_ROW_LIST;
      newvals       SYS.LCR$_ROW_LIST;
    BEGIN
      oldcol1_unit := SYS.LCR$_ROW_UNIT(
        'job_id', 
        ANYDATA.ConvertVarchar2(j_id),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      oldcol2_unit := SYS.LCR$_ROW_UNIT(
        'max_salary', 
        ANYDATA.ConvertNumber(old_max_sal),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      oldvals := SYS.LCR$_ROW_LIST(oldcol1_unit,oldcol2_unit);
      newcol1_unit := SYS.LCR$_ROW_UNIT(
        'max_salary', 
        ANYDATA.ConvertNumber(new_max_sal),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      newvals := SYS.LCR$_ROW_LIST(newcol1_unit);
      -- Execute the row LCR
      execute_row_lcr(
        source_dbname => 'DB1.EXAMPLE.COM',
        cmd_type      => 'UPDATE',
        obj_owner     => 'HR',
        obj_name      => 'JOBS',
        old_vals      => oldvals,
        new_vals      => newvals);  
    END update_max_salary_lcr;
    /
    
  5. hr.jobs表から行を削除する行LCRを実行するPL/SQLプロシージャdelete_job_lcrを作成します。

    CREATE OR REPLACE PROCEDURE delete_job_lcr(j_id VARCHAR2) AS
      xrow_lcr   SYS.LCR$_ROW_RECORD;
      col1_unit  SYS.LCR$_ROW_UNIT;
      oldvals    SYS.LCR$_ROW_LIST;
    BEGIN
      col1_unit := SYS.LCR$_ROW_UNIT(
        'job_id',
        ANYDATA.ConvertVarchar2(j_id),
        DBMS_LCR.NOT_A_LOB,
        NULL,
        NULL);
      oldvals := SYS.LCR$_ROW_LIST(col1_unit); 
      -- Execute the row LCR
      execute_row_lcr(
        source_dbname => 'DB1.EXAMPLE.COM',
        cmd_type      => 'DELETE',
        obj_owner     => 'HR',
        obj_name      => 'JOBS',
        old_vals      => oldvals,
        new_vals      => NULL);
    END delete_job_lcr;
    /
    
  6. insert_job_lcrプロシージャを使用して、hr.jobs表に行を挿入します。

    EXEC insert_job_lcr('BN_CNTR','BEAN COUNTER',5000,10000);
    
  7. hr.jobs表に挿入された行を問い合せます。

    SELECT * FROM hr.jobs WHERE job_id = 'BN_CNTR';
    
    JOB_ID     JOB_TITLE                           MIN_SALARY MAX_SALARY
    ---------- ----------------------------------- ---------- ----------
    BN_CNTR    BEAN COUNTER                              5000      10000
    
  8. update_max_salary_lcrプロシージャを使用して、手順6hr.jobs表に挿入した行のmax_salary値を更新します。

    EXEC update_max_salary_lcr('BN_CNTR',10000,12000);
    
  9. hr.jobs表で更新された行を問い合せます。

    SELECT * FROM hr.jobs WHERE job_id = 'BN_CNTR';
    
    JOB_ID     JOB_TITLE                           MIN_SALARY MAX_SALARY
    ---------- ----------------------------------- ---------- ----------
    BN_CNTR    BEAN COUNTER                              5000      12000
    
  10. delete_job_lcrプロシージャを使用して、手順6hr.jobs表に挿入した行を削除します。

    EXEC delete_job_lcr('BN_CNTR');
    
  11. hr.jobs表から削除された行を問い合せます。

    SELECT * FROM hr.jobs WHERE job_id = 'BN_CNTR';
    
    no rows selected
    

DDL LCRの実行

DDL LCR用のEXECUTEメンバー・プロシージャは、LCR$_DDL_RECORD型のサブプログラムです。DDL LCRにEXECUTEメンバー・プロシージャを実行すると、LCRが実行され、LCRに対して実行される適用プロセスのハンドラは実行されません。DDL LCR用のEXECUTEメンバー・プロシージャを起動できるのは、適用プロセスの適用ハンドラ内のみです。

適用されたDDL LCRは、すべて自動的にコミットされます。したがって、DDLハンドラがDDL LCRのEXECUTEメンバー・プロシージャをコールすると、自動的にコミットが実行されます。


関連項目:

  • 『Oracle Streams概要および管理』

  • DDL LCRおよびLCR$_DDL_RECORD型の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


LOB列を含むLCRの管理

LOBデータ型は、取得プロセスによって取得される行LCRに存在できますが、他のデータ型として表されます。LOBデータ型は、同期取得によって取得される行LCRには存在できません。特定のLOBデータ型は、ユーザーが構成する行LCRには存在できません。表14-1に、これらのデータ型のLCR表現、および行LCRに存在できるかどうかを示します。

表14-1 行LCR内のLOBデータ型の表現

データ型 行LCR表現 取得プロセスによって取得される行LCRに存在できるかどうか 同期取得によって取得される行LCRに存在できるかどうか ユーザーが構成する行LCRに存在できるかどうか

固定幅CLOB

VARCHAR2

できる

できない

できる

可変幅CLOB

AL16UTF16キャラクタ・セットのRAW

できる

できない

できない

NCLOB

AL16UTF16キャラクタ・セットのRAW

できる

できない

できない

BLOB

RAW

できる

できない

できる

CLOBとして格納されたXMLType

RAW

できる

できない

できない


Oracle Streams環境でのLOBデータ型に関係する行変更の一般的な考慮事項は、次のとおりです。

  • LOB列に関係する行変更は、複数の行LCRとして取得、伝播および適用される場合があります。

  • これらの行LCRの評価に使用されるルールは、ルール・セット内のルールが行変更に対応するすべての行LCRをTRUEと評価するか、またはどの行LCRもTRUEと評価しないように、決定的である必要があります。

ここでは、LOB列を構成または処理する場合に満たす必要のある要件、LOB列を含むLCRに対する適用プロセスの動作、およびLOBアセンブリについて説明します。また、LOB列を含むLCRを構成してエンキューする例も示します。


注意:

CLOBとして格納されたXMLTypeは、このリリースでは非推奨です。

この項の内容は、次のとおりです。


関連項目:

  • LOBの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

  • LOBを含むLCRを構成してエンキューする例については、『Oracle Streams拡張例』を参照してください。


LOBを含むLCRの直接適用に対する適用プロセスの動作

LOB列を含むLCRを(適用ハンドラを使用せずに)直接適用すると、適用プロセスは次のように動作します。

  • コマンド・タイプがINSERTまたはUPDATEのLCRにデータを含む新規のLOBがあり、lob_informationDBMS_LCR.LOB_CHUNKまたはDBMS_LCR.LAST_LOB_CHUNKでない場合は、そのデータが適用されます。

  • コマンド・タイプがINSERTまたはUPDATEのLCRにデータを含まない新規のLOBがあり、lob_informationDBMS_LCR.EMPTY_LOBの場合は、空のLOBとして適用されます。

  • コマンド・タイプがINSERTまたはUPDATEのLCRにデータを含まない新規のLOBがあり、lob_informationDBMS_LCR.NULL_LOBまたはDBMS_LCR.INLINE_LOBの場合は、NULLとして適用されます。

  • コマンド・タイプがINSERTまたはUPDATEのLCRに新規のLOBがあり、lob_informationDBMS_LCR.LOB_CHUNKまたはDBMS_LCR.LAST_LOB_CHUNKの場合は、すべてのLOB値が無視されます。コマンド・タイプがINSERTの場合は、LOBチャンクが続くものとみなされ、列に空のLOBが挿入されます。コマンド・タイプがUPDATEの場合は、LOBチャンクが続くものとみなされ、列の値が無視されます。

  • コマンド・タイプがUPDATEのLCR内の新規列がすべてLOBで、そのlob_informationDBMS_LCR.LOB_CHUNKまたはDBMS_LCR.LAST_LOB_CHUNKの場合は、LOBチャンクが続くものとみなされ、更新がスキップされます。

  • コマンド・タイプがUPDATEまたはDELETEのLCRの場合は、古いLOB値が無視されます。

LOBアセンブリとLOB列を含むLCRのカスタム適用

LOB列を含まない表の行に対して変更を行うと、1つの行LCRが生成されますが、1つ以上のLOB列を含む行に対して変更を行うと、複数の行LCRが生成される場合があります。適用プロセスは、LOB列を含む行LCRを適用ハンドラに送信しない場合、その行LCRを直接適用できます。ただし、Oracle Database 10g リリース2より前のリリースでは、1つの行変更に対して複数のLCRが適切に処理されるように適用ハンドラを構成する必要があったため、LOB列を含む行LCRのカスタム処理は複雑でした。

Oracle Database 10g リリース2以上では、LOBアセンブリによって、取得プロセスで取得されたLOB列を含む行LCRのカスタム処理が簡略化されています。LOBアセンブリを使用すると、LOB列を含む行に対する変更によって生成される複数の取得された行LCRが、1つの行LCRに自動的に結合されます。LOBアセンブリを有効にすると、適用プロセスがこの1つの行LCRをDMLハンドラまたはエラー・ハンドラに渡します。また、LOBアセンブリの実行後は、LOB列値がVARCHAR2またはRAWデータ型値ではなくLOBロケータとして表されます。プロシージャDMLハンドラまたはエラー・ハンドラにLOBアセンブリを有効化するには、DBMS_APPLY_ADM.SET_DML_HANDLERプロシージャでassemble_lobsパラメータをTRUEに設定します。文DMLハンドラに対しては、LOBアセンブリは常に有効化されています。

DMLハンドラまたはエラー・ハンドラに対してassemble_lobsパラメータをFALSEに設定した場合、LOBアセンブリは無効化され、LOB列を含む1行の変更に対して複数の行LCRがハンドラに渡されます。表14-2に、LOBアセンブリを無効化した場合のOracle Streamsの動作を示します。具体的には、LOB列を含む1行に対する変更によって生成され、プロシージャDMLハンドラまたはエラー・ハンドラに渡されるLCRを示します。

表14-2 LOBアセンブリを無効化した場合のOracle Streamsの動作

元の行変更 最初のLCRのセット 2番目のLCRのセット 3番目のLCRのセット 最後のLCRのセット

INSERT

1つのINSERT LCR

1つ以上のLOB WRITE LCR

1つ以上のLOB TRIM LCR

UPATE

UPDATE

1つのUPDATE LCR

1つ以上のLOB WRITE LCR

1つ以上のLOB TRIM LCR

UPATE

DELETE

1つのDELETE LCR

なし

なし

なし

DBMS_LOB.WRITE

1つ以上のLOB WRITE LCR

なし

なし

なし

DBMS_LOB.TRIM

1つのLOB TRIM LCR

なし

なし

なし

DBMS_LOB.ERASE

1つのLOB ERASE LCR

なし

なし

なし


表14-3に、LOBアセンブリを有効化した場合のOracle Streamsの動作を示します。具体的には、LOB列を含む1行に対する変更によって生成され、DMLハンドラまたはエラー・ハンドラに渡される行LCRを示します。

表14-3 LOBアセンブリを有効化した場合のOracle Streamsの動作

元の行変更 1つのLCR

INSERT

INSERT

UPDATE

UPDATE

DELETE

DELETE

DBMS_LOB.WRITE

LOB WRITE

DBMS_LOB.TRIM

LOB TRIM

DBMS_LOB.ERASE

LOB ERASE


LOBアセンブリを有効化すると、DMLハンドラまたはエラー・ハンドラによって、行LCRのLOB列が変更されます。DMLハンドラまたはエラー・ハンドラとして指定したPL/SQLプロシージャ内でLOBに対する操作を実行するには、DBMS_LOBパッケージのサブプログラムを使用することをお薦めします。行LCRにNULLのLOB列が含まれている場合、新しいLOBロケータでNULLを置き換える必要があります。EXECUTEメンバー・プロシージャを使用して行LCRを適用する場合は、行LCR用のADD_COLUMNSET_VALUEおよびSET_VALUESメンバー・プロシージャを使用してLOBに対する変更を行います。

LOBアセンブリを有効化すると、LOBアセンブリによって、永続LCR内の非NULLのLOB列がLOBロケータに変換されます。ただし、LOBアセンブリでは、複数の永続行LCRが1つの行LCRに結合されません。たとえば、永続行LCRの場合、LOBアセンブリでは、INSERT行LCRの後に続く複数のLOB WRITE行LCRは1つのINSERT行LCRに結合されません。


関連項目:

  • 適用ハンドラの詳細は、『Oracle Streams概要および管理』を参照してください。

  • DBMS_LOBパッケージを使用する方法の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』および『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

  • 行LCR用のADD_COLUMNSET_VALUEおよびSET_VALUESメンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


LOBアセンブリに関する考慮事項

LOBアセンブリを使用する場合の考慮事項は次のとおりです。

  • DMLハンドラまたはエラー・ハンドラを使用して、アセンブルされたLOBを複数の宛先データベースで処理するには、LOBアセンブリによって各宛先データベースで個別にLOBをアセンブルする必要があります。

  • Oracle Database 10g リリース2より前のリリースのOracleが実行されているデータベースで取得された行LCRは、LOBアセンブリでアセンブルできません。

  • 互換レベルが10.2.0より低いOracle Database 10g リリース2以上が実行されているデータベースで取得された行LCRは、LOBアセンブリでアセンブルできません。

  • 適用ハンドラにLOBアセンブリを指定するには、適用ハンドラが実行されているデータベースの互換レベルが10.2.0以上である必要があります。

  • LONGまたはLONG RAW列を含む表からの行LCRは、LOBアセンブリでアセンブルできません。

  • DBMS_APPLY_ADMパッケージのSET_ENQUEUE_DESTINATIONおよびSET_EXECUTEプロシージャは、常に元のアセンブルされていない行LCRに実行されます。したがって、LOB列を含む行LCRの場合、行LCRが宛先データベースで適用ハンドラ用に個別にアセンブルされていても、元のアセンブルされていない行LCRがエンキューまたは実行されます。

  • 取得、伝播または適用中に、LOB列を含む行LCRにルールベースの変換が実行された場合、適用ハンドラは変換済の行LCRに実行されます。ソース・データベースにLONGまたはLONG RAW列が存在し、ルールベースの変換で行LCR用のCONVERT_LONG_TO_LOB_CHUNKメンバー・ファンクションを使用してそれらの列がLOBに変換される場合、これらの行LCRに実行される適用ハンドラに対してLOBアセンブリを有効化できます。

  • 行LCRに1つ以上のXMLType列が含まれている場合、DMLハンドラまたはエラー・ハンドラに対してassemble_lobsパラメータがFALSEに設定されていても、行LCRのすべてのXMLType列およびLOB列が常にアセンブルされます。


関連項目:

  • データベースの互換レベルの詳細は、『Oracle Databaseリファレンス』および『Oracle Databaseアップグレード・ガイド』を参照してください。

  • DBMS_APPLY_ADMパッケージのサブプログラムの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


LOBアセンブリの例

この項では、プロシージャDMLハンドラとともにLOBアセンブリを使用する例を示します。この例では、複数のデータベースでoe.production_information表を共有しているが、一部のデータベースのみを会社のオンラインWorld Wide Webカタログに使用している会社について考えます。この会社は各製品の写真をカタログ・データベースに格納する予定ですが、領域を節約するために、カタログ・データベース以外のデータベースには写真を格納しません。

この目標を達成するには、接続先カタログ・データベースのプロシージャDMLハンドラで、データ型BLOBの列photoを、ソース・データベースのproduct_information表に対して実行される各INSERTおよびUPDATEに追加します。ソース・データベースの表にphoto列は含まれません。プロシージャDMLハンドラは、接続先で既存の写真を使用して更新および挿入を実行するように構成されます。また、この会社には、すべてのデータベースのoe.product_information表にproduct_long_descを追加する目標もあります。この表には、簡単な説明を含むproduct_description列がすでに存在します。product_long_desc列のデータ型はCLOBで、詳細な説明が含まれています。詳細な説明は英語で記述されていますが、会社の1つのデータベースを使用して、会社のカタログがスペイン語で表示されます。したがって、適切な言語で詳細な説明が表示されるように、プロシージャDMLハンドラによってproduct_long_desc列が更新されます。

次の手順を実行して、LOBアセンブリを使用して前述の目標を達成するようにプロシージャDMLハンドラを構成します。

手順1: product_information表へのphoto列の追加

次の文を実行すると、photo列が宛先データベースのproduct_information表に追加されます。

ALTER TABLE oe.product_information ADD(photo BLOB);
手順2: product_information表へのproduct_long_desc列の追加

次の文を実行すると、product_long_desc列が、環境内のすべてのデータベースのproduct_information表に追加されます。

ALTER TABLE oe.product_information ADD(product_long_desc CLOB);
手順3: プロシージャDMLハンドラ用のPL/SQLプロシージャの作成

この例では、convert_product_informationプロシージャを作成します。このプロシージャは、プロシージャDMLハンドラ用に使用されます。このプロシージャでは、ユーザーが作成した次のPL/SQLサブプログラムが存在すると想定されています。

  • get_photoプロシージャ。product_idに基づいてURLまたは表からBLOB形式の写真を取得し、引数として渡されたBLOBロケータを更新します。

  • get_product_long_descプロシージャ。product_idIN引数およびproduct_long_descIN OUT引数を持ち、product_long_descをスペイン語に翻訳するか、または置換用のスペイン語の説明を取得して、product_long_descを更新します。

次のコードを実行すると、convert_product_informationプロシージャが作成されます。

CREATE OR REPLACE PROCEDURE convert_product_information(in_any IN ANYDATA)
IS
  lcr                      SYS.LCR$_ROW_RECORD;
  rc                       PLS_INTEGER;
  product_id_anydata       ANYDATA;
  photo_anydata            ANYDATA;
  long_desc_anydata        ANYDATA;
  tmp_photo                BLOB;
  tmp_product_id           NUMBER;
  tmp_prod_long_desc       CLOB;
  tmp_prod_long_desc_src   CLOB;
  tmp_prod_long_desc_dest  CLOB;
  t                        PLS_INTEGER;
BEGIN
  -- Access LCR
  rc := in_any.GETOBJECT(lcr);
  product_id_anydata := lcr.GET_VALUE('OLD', 'PRODUCT_ID');
  t := product_id_anydata.GETNUMBER(tmp_product_id);
  IF ((lcr.GET_COMMAND_TYPE = 'INSERT') or (lcr.GET_COMMAND_TYPE = 'UPDATE')) THEN
    -- If there is no photo column in the lcr then it must be added
    photo_anydata := lcr.GET_VALUE('NEW', 'PHOTO');
    -- Check if photo has been sent and if so whether it is NULL
    IF (photo_anydata is NULL) THEN
      tmp_photo := NULL;
      ELSE
      t := photo_anydata.GETBLOB(tmp_photo);
    END IF;
    -- If tmp_photo is NULL then a new temporary LOB must be created and
    -- updated with the photo if it exists
    IF (tmp_photo is NULL) THEN
      DBMS_LOB.CREATETEMPORARY(tmp_photo, TRUE);
      get_photo(tmp_product_id, tmp_photo);
    END IF;
    -- If photo column did not exist then it must be added
    IF (photo_anydata is NULL) THEN
      lcr.ADD_COLUMN('NEW', 'PHOTO', ANYDATA.CONVERTBLOB(tmp_photo));
      -- Else the existing photo column must be set to the new photo
      ELSE
        lcr.SET_VALUE('NEW', 'PHOTO', ANYDATA.CONVERTBLOB(tmp_photo));
    END IF;
    long_desc_anydata := lcr.GET_VALUE('NEW', 'PRODUCT_LONG_DESC');
    IF (long_desc_anydata is NULL) THEN
      tmp_prod_long_desc_src := NULL;
      ELSE
      t := long_desc_anydata.GETCLOB(tmp_prod_long_desc_src);
    END IF;
    IF (tmp_prod_long_desc_src IS NOT NULL) THEN
      get_product_long_desc(tmp_product_id, tmp_prod_long_desc);
    END IF;
    -- If tmp_prod_long_desc IS NOT NULL, then use it to update the LCR
    IF (tmp_prod_long_desc IS NOT NULL) THEN
      lcr.SET_VALUE('NEW', 'PRODUCT_LONG_DESC',
                    ANYDATA.CONVERTCLOB(tmp_prod_long_desc_dest));
    END IF;
  END IF;
  -- DBMS_LOB operations also are executed 
  -- Inserts and updates invoke all changes
  lcr.EXECUTE(TRUE);
END;
/
手順4: 適用プロセスのプロシージャDMLハンドラの設定

この手順では、宛先データベースでのINSERTUPDATEおよびLOB_UPDATE操作用のプロシージャDMLハンドラとしてconvert_product_informationプロシージャを設定します。SET_DML_HANDLERプロシージャを実行するたびに、assemble_lobsパラメータがTRUEに設定されていることに注意してください。

BEGIN
  DBMS_APPLY_ADM.SET_DML_HANDLER(
    object_name         => 'oe.product_information',
    object_type         => 'TABLE',
    operation_name      => 'INSERT',
    error_handler       => FALSE,
    user_procedure      => 'strmadmin.convert_product_information',
    apply_database_link => NULL,
    assemble_lobs       => TRUE);
  DBMS_APPLY_ADM.SET_DML_HANDLER(
    object_name         => 'oe.product_information',
    object_type         => 'TABLE',
    operation_name      => 'UPDATE',
    error_handler       => FALSE,
    user_procedure      => 'strmadmin.convert_product_information',
    apply_database_link => NULL,
    assemble_lobs       => TRUE);
  DBMS_APPLY_ADM.SET_DML_HANDLER(
    object_name         => 'oe.product_information',
    object_type         => 'TABLE',
    operation_name      => 'LOB_UPDATE',
    error_handler       => FALSE,
    user_procedure      => 'strmadmin.convert_product_information',
    apply_database_link => NULL,
    assemble_lobs       => TRUE);
END;
/
手順5: DBA_APPLY_DML_HANDLERSビューの問合せ

oe.product_information表に対してプロシージャDMLハンドラが適切に設定されていることを確認するには、次の問合せを実行します。

COLUMN OBJECT_OWNER HEADING 'Table|Owner' FORMAT A5
COLUMN OBJECT_NAME HEADING 'Table Name' FORMAT A20
COLUMN OPERATION_NAME HEADING 'Operation' FORMAT A10
COLUMN USER_PROCEDURE HEADING 'Handler Procedure' FORMAT A25
COLUMN ASSEMBLE_LOBS HEADING 'LOB Assembly?' FORMAT A15

SELECT OBJECT_OWNER, 
       OBJECT_NAME, 
       OPERATION_NAME, 
       USER_PROCEDURE,
       ASSEMBLE_LOBS
  FROM DBA_APPLY_DML_HANDLERS;

出力は次のようになります。

Table
Owner Table Name           Operation  Handler Procedure         LOB Assembly?
----- -------------------- ---------- ------------------------- ---------------
OE    PRODUCT_INFORMATION  INSERT     "STRMADMIN"."CONVERT_PROD Y
                                      UCT_INFORMATION"
 
OE    PRODUCT_INFORMATION  UPDATE     "STRMADMIN"."CONVERT_PROD Y
                                      UCT_INFORMATION"
 
OE    PRODUCT_INFORMATION  LOB_UPDATE "STRMADMIN"."CONVERT_PROD Y
                                      UCT_INFORMATION"

正しいプロシージャconvert_product_informationが、表に対する各操作に使用されていることに注意してください。また、各ハンドラでLOBアセンブリが使用されていることにも注意してください。

LOB列を含むLCRを構成および処理するための要件

環境でLOB列を含む行LCRを生成する場合は、そのLCRを構成または処理するときに、次の項に示す要件を満たす必要があります。


関連項目:

LOBを含むLCRを構成してエンキューする例については、『Oracle Streams拡張例』を参照してください。

LOBアセンブリを使用せずにLCRを構成および処理するための要件

LOB列を含むLCRを構成する場合、およびLOBアセンブリが無効化されているDMLハンドラまたはエラー・ハンドラでLOB列を処理する場合、次の要件を満たす必要があります。

  • LOBアセンブリが無効化されているプロシージャDMLハンドラまたはエラー・ハンドラで、行LCR内のLOB列データを変更しないでください。ただし、DMLハンドラまたはエラー・ハンドラで、行LCR内のLOB以外の列を変更することはできます。

  • 特定の操作にのみ起動される適用ハンドラで、LOB列を含む表からのLCRを処理しないでください。たとえば、INSERT操作にのみ起動される適用ハンドラによって、1つ以上のLOB列を含む表からのLCRを処理しないでください。

  • LCRのLOB列のデータ部分が、VARCHAR2型またはRAW型である必要があります。VARCHAR2CLOBRAWBLOBとして解析されます。

  • ユーザーが構成する行LCRのLOB列は、BLOBまたは固定幅CLOBのいずれかである必要があります。NCLOB型または可変幅CLOB型のLOB列を含む行LCRは構成できません。

  • 表外のLOBに有効なコマンド・タイプは、LOB WRITELOB ERASEおよびLOB TRIMのみです。

  • LOB WRITELOB ERASEおよびLOB TRIMのLCRの場合は、old_valuesコレクションを空またはNULLnew_valuesを空以外にする必要があります。

  • LOB WRITE LCRとLOB ERASE LCRの場合は、lob_offsetを有効な値にする必要があります。他のすべてのコマンド・タイプの場合は、その列のLOBチャンクが続くものとみなして、lob_offsetNULLにする必要があります。

  • LOB ERASE LCRとLOB TRIM LCRの場合は、lob_operation_sizeを有効な値にする必要があります。他のすべてのコマンド・タイプの場合は、lob_operation_sizeNULLにする必要があります。

  • LOB TRIMおよびLOB ERASEは、LCRに含まれているLOB列のlob_informationLAST_LOB_CHUNKに設定されている場合にのみ有効なコマンド・タイプです。

  • LOB WRITEは、LCRに含まれているLOB列のlob_informationLAST_LOB_CHUNKまたはLOB_CHUNKに設定されている場合にのみ有効なコマンド・タイプです。

  • lob_informationNULL_LOBに設定されているLOBの場合は、列のデータ部分をVARCHAR2型のNULL(CLOBの場合)またはRAW型のNULL(BLOBの場合)にする必要があります。それ以外の場合は、非NULLのインラインLOB列として解析されます。

  • LOB WRITE LCR、LOB ERASE LCRおよびLOB TRIM LCRに許容されるのは、1つの新規チャンクを持つ1つのLOB列参照のみです。

  • LOB ERASE LCRおよびLOB TRIM LCR用の新規LOBチャンクは、ANYDATAにカプセル化されたNULL値にする必要があります。

前述の要件の妥当性チェックは、すべて適用プロセスによって実行されます。前述の要件が満たされない場合、LOB列を含む行LCRは適用プロセスでは適用できず、適用ハンドラでは処理できません。この場合、LCRは同じトランザクション内の他のLCRとともにエラー・キューに移動します。


関連項目:


LOBアセンブリを使用してLCRを適用ハンドラで処理するための要件

LOBアセンブリが有効化されているDMLハンドラまたはエラー・ハンドラでLOB列を処理する場合、次の要件を満たす必要があります。

  • アセンブルされたLOBを含む行LCR内のLOB列には、次の行LCRのメンバー・プロシージャを使用しないでください。

    • SET_LOB_INFORMATION

    • SET_LOB_OFFSET

    • SET_LOB_OPERATION_SIZE

    これらのいずれかのプロシージャを行LCR内のLOB列に使用すると、エラーが発生します。

  • LOBアセンブリで構成した行LCRは、プロシージャDMLハンドラまたはエラー・ハンドラではエンキューできません。ただし、宛先データベースの1つ以上のハンドラにLOBアセンブリが有効化されている場合でも、DBMS_APPLY_ADMパッケージのSET_ENQUEUE_DESTINATIONプロシージャを使用して、LOB列を含む元のアセンブルされていない行LCRをエンキューできます。

前述の要件の妥当性チェックは、すべて適用プロセスによって実行されます。前述の要件が満たされない場合、LOB列を含む行LCRは適用プロセスでは適用できず、適用ハンドラでは処理できません。この場合、LCRは同じトランザクション内の他のLCRとともにエラー・キューに移動します。LOB列を含む行LCRの場合、元のアセンブルされていない行LCRがエラー・キューに置かれます。


関連項目:

  • 適用ハンドラの詳細は、『Oracle Streams概要および管理』を参照してください。

  • 行LCR用のメンバー・プロシージャおよびSET_ENQUEUE_DESTINATIONプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


LOBを含むLCRをルールベースの変換で処理するための要件

ルールベースの変換でLOB列を含む行LCRを処理する場合、次の要件を満たす必要があります。

  • カスタム・ルールベースの変換で、行LCR内のLOB列データを変更しないでください。ただし、カスタム・ルールベースの変換で、LOB列を含む行LCR内のLOB以外の列を変更することはできます。

  • カスタム・ルールベースの変換で行LCRを処理する場合、次の行LCRのメンバー・プロシージャをLOB列に使用することはできません。

    • ADD_COLUMN

    • SET_LOB_INFORMATION

    • SET_LOB_OFFSET

    • SET_LOB_OPERATION_SIZE

    • SET_VALUE

    • SET_VALUES

  • DBMS_STREAMS_ADMパッケージのADD_COLUMNプロシージャで作成した宣言ルールベースの変換では、LOB列を行LCRに追加できません。

  • 行変更に対応するすべての行LCRが同じ方法で変換されるように、LOB列を含む行LCRで実行されるルールベースの変換ファンクションは決定的である必要があります。

  • 特定の操作にのみ起動されるカスタム・ルールベースの変換で、LOB列を含む表からのLCRを処理しないでください。たとえば、INSERT操作にのみ実行されるカスタム・ルールベースの変換によって、1つ以上のLOB列を含む表からのLCRを処理しないでください。


注意:

行LCRにLOB列が含まれる場合、ルールベースの変換は、常に元のアセンブルされていない行LCRに実行されます。


関連項目:

  • 「LCRの構成とエンキュー」

  • ルールベースの変換の詳細は、『Oracle Streams概要および管理』を参照してください。

  • 行LCR用のメンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

  • 決定的なファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。


LONGまたはLONG RAW列を含むLCRの管理

LONGおよびLONG RAWデータ型は、いずれも取得プロセスによって取得される行LCRに存在できますが、これらのデータ型は行LCR内では次のデータ型として表されます。

  • LONGデータ型は、行LCR内ではVARCHAR2データ型として表されます。

  • LONG RAWデータ型は、行LCR内ではRAWデータ型として表されます。

LONGまたはLONG RAW列に関係する行変更は、複数のLCRとして取得、伝播および適用される場合があります。環境でLONGまたはLONG RAW列を含むLCRを使用する場合は、LCRのLONGまたはLONG RAW列のデータ部分が、VARCHAR2型またはRAW型である必要があります。VARCHAR2LONGRAWLONG RAWとして解析されます。

Oracle StreamsでLONGまたはLONG RAW列のデータを含む行LCRを処理する場合は、次の要件を満たす必要があります。

  • カスタム・ルールベースの変換を使用して、LCR内のLONGまたはLONG RAW列のデータを変更しないでください。ただし、ルールベースの変換を使用して、LONGまたはLONG RAW列のデータを含む行LCR内のLONGおよびLONG RAW以外の列を変更することはできます。

  • LONGまたはLONG RAWデータを含む行LCRを処理するカスタム・ルールベースの変換では、行LCRのSET_VALUEまたはSET_VALUESメンバー・プロシージャは使用しないでください。これらのメンバー・プロシージャを使用すると、ORA-26679エラーが発生します。

  • 行変更に対応するすべてのLCRが同じ方法で変換されるように、LONGまたはLONG RAW列を含むLCRで実行されるルールベースの変換ファンクションは決定的である必要があります。

  • DBMS_STREAMS_ADMパッケージのADD_COLUMNプロシージャで作成した宣言ルールベースの変換では、LONGまたはLONG RAW列を行LCRに追加できません。

  • プロシージャDMLハンドラまたはエラー・ハンドラを使用して、LONGまたはLONG RAW列のデータを含む行LCRを処理することはできません。

  • LONGまたはLONG RAW列を含むLCRの評価に使用されるルールは、ルール・セット内のルールが行変更に対応するすべてのLCRをTRUEと評価するか、またはどのLCRもTRUEと評価しないように、決定的である必要があります。

  • 適用プロセスを使用して、LONGまたはLONG RAW列のデータを含むLCRを宛先キューにエンキューすることはできません。DBMS_APPLY_ADMパッケージのSET_DESTINATION_QUEUEプロシージャを実行すると、指定した適用プロセスのルールを満たすLCRの宛先キューが設定されます。


注意:

LONGおよびLONG RAWデータ型は、同期取得によって取得される行LCRまたはユーザーが構成する行LCRには存在できません。


関連項目:

  • ルールベースの変換の詳細は、『Oracle Streams概要および管理』を参照してください。

  • 決定的なファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。