36 DBMS_CQ_NOTIFICATION

DBMS_CQ_NOTIFICATIONパッケージは、クライアント・アプリケーションによって指定された問合せに関する登録を作成し、その問合せに関連付けられているオブジェクトでDML変更またはDDL変更が発生した際に通知を受け取る機能を提供するデータベース変更通知機能の一部です。通知は、DMLトランザクションまたはDDLトランザクションのコミット時にデータベースによって発行されます。

参照:

データベース変更通知の実装については、『Oracle Database開発ガイド』を参照してください。

この章のトピックは、次のとおりです:

36.1 DBMS_CQ_NOTIFICATIONの概要

DBMS_CQ_NOTIFICATIONパッケージは、PL/SQLベースの登録インタフェースを提供します。クライアントは、このインタフェースを使用して、問合せに関する登録を対象となるオブジェクトに基づいて作成し、通知を受け取るPL/SQLコールバック・ハンドラを指定できます。オブジェクト・レベルの登録の場合、登録した問合せに関連付けられているオブジェクトのいずれかがトランザクションによって変更され、そのトランザクションが|COMMIT|されると、それらのオブジェクトの登録時に指定したPL/SQLコールバックが起動されます。このアプリケーションによって、PL/SQLコールバック・ハンドラの実装の内部に、クライアント固有の処理を定義できます。

このインタフェースでは、(BEGIN-ENDブロックと同様の方法で)登録ブロックを定義できます。BEGINフェーズでは、通知の受信者(PL/SQLコールバック・ハンドラの名前)およびその他のいくつかの登録プロパティ(タイムアウトなど)を指定できます。(登録ブロック内で)続いて実行される問合せは優先度が高い問合せとみなされ、問合せの実行時にこれらの問合せによって参照されるオブジェクトが登録されます。登録は、登録ブロックをENDで終了することで完了します。登録ブロックでは、新しい登録の作成および既存の登録へのオブジェクトの追加を行うことができます。

PL/SQLインタフェースで登録を作成すると、RDBMSによって一意の登録IDが割り当てられます。クライアント・アプリケーションは、作成した登録をこの登録IDで追跡できます。RDBMSによって通知が発行されると、この登録IDが通知に含まれます。

通常のアプリケーション

たとえば、この機能は、問合せの結果セットを中間層内の読取り専用のオブジェクトに多くの場合キャッシュして、データベースへのネットワーク上のラウンドトリップを回避するアプリケーションで有効です。このようなアプリケーションでは、キャッシュする必要がある問合せに関する登録を作成できます。それらの問合せ内で参照されているオブジェクトに変更があった場合、元のトランザクションのコミット時に、データベースによって通知が発行されます。この通知に対応して、中間層のアプリケーションは、問合せを再度実行してキャッシュをリフレッシュできます。

36.2 DBMS_CQ_NOTIFICATIONのセキュリティ・モデル

DBMS_CQ_NOTIFICATIONパッケージを使用して通知を受け取るユーザーは、CHANGE NOTIFICATIONシステム権限およびDBMS_CQ_NOTIFICATIONパッケージに対するEXECUTE権限を付与されている必要があります。

また、このユーザーには、登録するすべてのオブジェクトに対するSELECTまたはREAD権限も必要です。登録の作成時に付与されたオブジェクトに対するSELECTまたはREAD権限を、その後(失効などで)失った場合は、登録がパージされ、そのことが通知されます。

36.3 DBMS_CQ_NOTIFICATIONの定数

DBMS_CQ_NOTIFICATION定数は、登録時または通知受信時のflagパラメータとして使用されます。

DBMS_CQ_NOTIFICATIONパッケージには、次の定数があります。

  • EVENT_STARTUPEVENT_SHUTDOWNEVENT_SHUTDOWN_ANYEVENT_DEREGは、データベースによって発行される通知のタイプを示します。

  • INSERTOPDELETEOPUPDATEOPALTEROPDROPOPおよびUNKNOWNOPは、(データベースによって発行される通知での)表の操作のタイプです。

  • QOS_RELIABLEQOS_DEREG_NFYQOS_ROWIDsは、クライアントから要求される、登録のサービス品質プロパティを示します。これらは、登録時に指定されます。

これらの定数を、次の表に示します。

表36-1 DBMS_CQ_NOTIFICATIONの定数

名前 タイプ 説明

ALL_OPERATIONS

BINARY_INTEGER

0

すべての操作に対する通知(登録時のパラメータとして指定)。

ALL_ROWS

BINARY_INTEGER

1

表内のすべての行が変更された可能性があります。

EVENT_STARTUP

BINARY_INTEGER

1

インスタンス起動通知。

EVENT_SHUTDOWN

BINARY_INTEGER

2

インスタンス停止通知。

EVENT_SHUTDOWN_ANY

BINARY_INTEGER

3

Oracle Real Application Clusters(Oracle RAC)実行時のインスタンスの停止。

EVENT_DEREG

BINARY_INTEGER

5

登録が削除されました。

EVENT_OBJCHANGE

BINARY_INTEGER

6

オブジェクト変更通知。

EVENT_QUERYCHANGE

BINARY_INTEGER

7

問合せ結果セットの変更の通知。

INSERTOP

BINARY_INTEGER

2

挿入操作。

UPDATEOP

BINARY_INTEGER

4

更新操作。

DELETEOP

BINARY_INTEGER

8

削除操作。

ALTEROP

BINARY_INTEGER

16

表の変更。

DROPOP

BINARY_INTEGER

32

表の削除。

UNKNOWNOP

BINARY_INTEGER

64

不明な操作。

QOS_RELIABLE

BINARY_INTEGER

1

信頼性(永続性)のある通知。また、コミットするとオブジェクトが変更されるトランザクションによって、通知が最小単位で持続記憶域に挿入されることも示します。

QOS_DEREG_NFY

BINARY_INTEGER

2

最初の通知時での登録のパージ。

QOS_ROWIDS

BINARY_INTEGER

4

変更した行のROWIDの要求。

QOS_QUERY

BINARY_INTEGER

8

問合せの粒度での登録。

QOS_BEST_EFFORT

BINARY_INTEGER

16

ベスト・エフォートの評価。

NTFN_GROUPING_CLASS_TIME

BINARY_INTEGER

1

時間別の通知のグループ化。

NTFN_GROUPING_TYPE_SUMMARY

BINARY_INTEGER

1

通知の要約のグループ化。

NTFN_GROUPING_TYPE_LAST

BINARY_INTEGER

2

グループ内の最後の通知。

NTFN_GROUPING_FOREVER

BINARY_INTEGER

-1

無期限の通知の繰返し。

36.4 DBMS_CQ_NOTIFICATIONの使用上の注意

DBMS_CQ_NOTIFICATIONの使用上の注意は、次のとおりです。

オブジェクト・レベルの統計

  • 通知は、登録されたオブジェクトがトランザクションによって変更され、そのトランザクションがCOMMITでコミットされると、データベースによって発行されます。

  • 以前のNEW_REG_STARTまたはENABLE_REGからREG_ENDまでの登録ブロック内で実行された問合せで参照されているすべてのオブジェクトは、優先度が高いオブジェクトとみなされ、登録に追加されます。

問合せ結果の変更の登録

  • 通知は、登録された問合せの結果セットがトランザクションによって変更され、そのトランザクションがCOMMITされると、データベースによって発行されます。

トラブルシューティング

登録の作成後、元の表の変更時に通知が送られていないと考えられる場合は、次の内容を確認します。

  • job_queue_processesパラメータが0(ゼロ)以外の値に設定されているかどうか。ハンドラを介してPL/SQL通知を受け取るには、このパラメータを0(ゼロ)以外の値に設定する必要があります。

  • SYSユーザー以外のユーザーとして登録を作成しているかどうか。

  • 登録されたオブジェクトにDML変更を行う場合、トランザクションをCOMMITでコミットしているかどうか。通知は、トランザクション処理であるため、トランザクションをCOMMITでコミットすると生成されます。

  • PL/SQLコールバックの実行時に、実装エラーが原因でランタイム・エラーが発生する可能性があります。その場合は、プロシージャを実行しようとしたJOBQプロセスのトレース・ファイルにエラーが記録されます。通常、トレース・ファイルは、<ORACLE_SID>_j*_<PID>.trcという名前です。'

    たとえば、ORACLE_SIDが'dbs1'で、プロセスが12483の場合、トレース・ファイルはdbs1_j000_12483.trcという名前になります。

    chnf_callbackを通知ハンドラとし、registration_idに100を指定して登録が作成されているとします。ユーザーがchnf_callbackプロシージャを定義し忘れたとします。この場合、JOBQトレース・ファイルには次の形式のメッセージが含まれます。

    Runtime error during execution of PL/SQL cbk chnf_callback for reg CHNF100
       Error in PLSQL notification of msgid:
       Queue : 
       Consumer Name :
       PLSQL function :chnf_callback
       Exception Occured, Error msg:
       ORA-00604: error occurred at recursive SQL level 2
       ORA-06550: line 1, column 7: 
       PLS-00201: identifier 'CHNF_CALLBACK' must be declared
       ORA-06550: line 1, column 7:
       PL/SQL: Statement ignored 

参照:

データベース変更通知のトラブルシューティングの詳細は、『Oracle Database開発ガイド』を参照してください。

36.5 DBMS_CQ_NOTIFICATIONの例

中間層のアプリケーションに、HR.EMPLOYEES表に関する大量の問合せがあるとします。EMPLOYEES表の更新頻度が低い場合は、表の行をキャッシュすると、バックエンドのデータベース・サーバーに対するラウンドトリップおよびサーバー側での実行待機時間を回避できるため、パフォーマンスが向上します。このアプリケーションによって、通知をリスニングする中間層のHTTPリスナーが実装され、通知に対応して中間層のキャッシュが更新されるとします。

オブジェクトの変更の登録例

この例では、DBMS_CQ_NOTIFICATIONパッケージを使用し、次の手順で表の変更に関する通知を送信できます。

  1. データベースから送信される通知メッセージをリスニングし、通知に対応して中間層のキャッシュをリフレッシュするキャッシュ管理システムの中間層リスナー・コンポーネント(たとえば、HTTPを使用)を実装します。

  2. 通知を処理する、サーバー側のストアド・プロシージャを作成します。

    CONNECT system;
    Enter password: password
    GRANT CHANGE NOTIFICATION TO hr;
    GRANT EXECUTE ON DBMS_CQ_NOTIFICATION TO hr;
     
    Rem Enable job queue processes to receive notifications.
    ALTER SYSTEM SET "job_queue_processes"=2;
     
    CONNECT hr;
    Enter password: password
    Rem Create a table to record notification events
    CREATE TABLE nfevents(regid number, event_type number);
     
    Rem create a table to record changes to registered tables
    CREATE TABLE nftablechanges(regid number, table_name varchar2(100),
                                table_operation number);
     
    Rem create a table to record rowids of changed rows.
    CREATE TABLE nfrowchanges(regid number, table_name varchar2(100), 
                              row_id varchar2(30));
     
    Rem Create a PL/SQL callback handler to process notifications.
    CREATE OR REPLACE PROCEDURE chnf_callback(ntfnds IN SYS.CHNF$_DESC) IS
       regid           NUMBER;
       tbname          VARCHAR2(60);
       event_type      NUMBER;
       numtables       NUMBER;
       operation_type  NUMBER;
       numrows         NUMBER;
       row_id          VARCHAR2(20);
     BEGIN
         regid      := ntfnds.registration_id;
         numtables  := ntfnds.numtables;
         event_type := ntfnds.event_type;
     
      INSERT INTO nfevents VALUES(regid, event_type);
      IF (event_type = DBMS_CQ_NOTIFICATION.EVENT_OBJCHANGE) THEN
        FOR i IN 1..numtables LOOP
          tbname          := ntfnds.table_desc_array(i).table_name;
          operation_type  := ntfnds.table_desc_array(I). Opflags;
          INSERT INTO nftablechanges VALUES(regid, tbname, operation_type);
          /* Send the table name and operation_type to client side listener using UTL_HTTP */
          /* If interested in the rowids, obtain them as follows */
          IF (bitand(operation_type, DBMS_CQ_NOTIFICATION.ALL_ROWS) = 0) THEN
            numrows := ntfnds.table_desc_array(i).numrows;
          ELSE 
            numrows :=0;   /* ROWID INFO NOT AVAILABLE */
          END IF;
          
          /* The body of the loop is not executed when numrows is ZERO */
          FOR j IN 1..numrows LOOP
              Row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
              INSERT INTO nfrowchanges VALUES(regid, tbname, Row_id);
             /* optionally Send out row_ids to client side listener using UTL_HTTP; */
          END LOOP;
          
        END LOOP;
      END IF;
      COMMIT;
    END;
    / 

    手順2では、通知記述子で取得される情報に基づいて、中間層アプリケーションで必要な無効化に関する情報を送信できます。

    注意

    1. 前述の例では、'chnf_callback'を通知のPL/SQLハンドラとして使用してEMPLOYEES表に関する登録を作成しました。登録時に、クライアントによって、信頼性のある通知(QOS_RELIABLE)およびROWIDの通知(QOS_ROWIDS)が指定されました。

    2. ハンドラは、通知タイプがEVENT_OBJCHANGEの場合にのみ、通知記述子の表記述子配列にアクセスします。他のすべての場合(たとえば、EVENT_DEREGEVENT_SHUTDOWNの場合)、表記述子配列はアクセスされません。

    3. ハンドラは、表操作フラグにALL_ROWSビットがセットされていない場合にのみ、表通知記述子の行記述子配列にアクセスします。表操作フラグにALL_ROWSビットがセットされている場合は、表内のすべての行が変更された可能性があることを示します。また、このビットは、表内のすべての行に影響するTRUNCATEのような操作の他に、個々のROWIDがFULLタイプの表の無効化にロールアップされた場合にもセットされます。

      これは、ある表で行われた1つのトランザクションで変更された行が多すぎる(80行を超えている)か、またはRDBMSのROWIDが原因で共有メモリーの消費合計が多すぎる(動的共有プール・サイズの1%を超えている)と判断された場合に発生します。この場合、受信者は、表全体が無効になったことを想定し、コールバック/アプリケーションでこの状況に対処できるようにする必要があります。

      また、ユーザー定義のコールバックの実装は、開発者が決定することに注意してください。前述の例では、コールバックを使用してイベントの詳細をデータベース表に記録しました。また、このアプリケーションでは、(例のように)UTL_HTTPを使用して、通知の詳細をキャッシュ管理システムの中間層HTTPリスナーに送信することもできます。このリスナーは、バックエンドのデータベースから問合せを行ってキャッシュをリフレッシュすることができます。

  3. 通知を行う対象となる表の登録を作成します。以前に定義したプロシージャの名前(chnf_callback)を、通知の生成時に実行するサーバー側のPL/SQLプロシージャの名前として渡します。

    Rem Create a REGISTRATION on the EMPLOYEES TABLE    
    DECLARE
      REGDS      SYS.CHNF$_REG_INFO;
      regid      NUMBER;
      mgr_id     NUMBER;
      dept_id    NUMBER;
      qosflags   NUMBER;
    BEGIN
     qosflags := DBMS_CQ_NOTIFICATION.QOS_RELIABLE +
             DBMS_CQ_NOTIFICATION.QOS_ROWIDS;
    REGDS := SYS.CHNF$_REG_INFO ('chnf_callback', qosflags, 0,0,0);
    regid := DBMS_CQ_NOTIFICATION.NEW_REG_START (REGDS); 
    SELECT manager_id INTO mgr_id FROM EMPLOYEES WHERE employee_id = 200;
    DBMS_CQ_NOTIFICATION.REG_END;
    END;
    /

    前述の手順3で登録を作成すると、手順2で定義したサーバー側のPL/SQLプロシージャが、HR.EMPLOYEES表に対してCOMMITでコミットされた変更に対応して実行されます。たとえば、employees表に対して次の更新が行われるとします。

    UPDATE employees SET salary=salary*1.05 WHERE employee_id=203;COMMIT;

    通知が処理されると、nfeventsnftablechangesnfrowchangesの各表に、次のような行が挿入されます。

    SQL> SELECT * FROM nfevents;
     
         REGID     EVENT_TYPE
    ---------------------------
         20045          6
     
     
    SQL> SELECT * FROM nftablechanges;
     
      REGID      TABLE_NAME         TABLE_OPERATION
    -------------------------------------------
      20045      HR.EMPLOYEES            4
     
    
    SQL> select * from nfrowchanges;
     
        REGID      TABLE_NAME          ROW_ID
    ------------------------------------------------------
        20045     HR.EMPLOYEES    AAAKB/AABAAAJ8zAAF
    
    

問合せ結果の変更の登録例

  1. コールバックを作成します。

    CONNECT system;
    Enter password: password
    GRANT CHANGE NOTIFICATION TO hr;
    GRANT EXECUTE ON DBMS_CQ_NOTIFICATION TO hr;
    CONNECT hr;
    Enter password: password
    Rem Create a table to record notification events
    CREATE TABLE nfevents(regid NUMBER, event_type NUMBER);
    
    Rem Create a table to record notification queries
    CREATE TABLE nfqueries (qid NUMBER, qop NUMBER);
    
    Rem Create a table to record changes to registered tables
    CREATE TABLE nftablechanges(
           qid                NUMBER,
           table_name         VARCHAR2(100),
           table_operation    NUMBER);
    
    Rem Create a table to record rowids of changed rows.
    CREATE TABLE nfrowchanges(
           qid                NUMBER,
           table_name         VARCHAR2(100),
           row_id             VARCHAR2(2000));
     
     
    CREATE OR REPLACE PROCEDURE chnf_callback
      (ntfnds IN CQ_NOTIFICATION$_DESCRIPTOR)
    IS
      regid           NUMBER;
      tbname          VARCHAR2(60);
      event_type      NUMBER;
      numtables       NUMBER;
      operation_type  NUMBER;
      numrows         NUMBER;
      row_id          VARCHAR2(2000);
      numqueries      NUMBER;
      qid NUMBER;
      qop NUMBER;
    
    BEGIN
      regid := ntfnds.registration_id;
      event_type := ntfnds.event_type;
      INSERT INTO nfevents VALUES(regid, event_type);
      numqueries :=0;
      IF (event_type = DBMS_CQ_NOTIFICATION.EVENT_QUERYCHANGE) THEN
          numqueries := ntfnds.query_desc_array.count;
          FOR i in 1..numqueries LOOP
             qid := ntfnds.QUERY_DESC_ARRAY(i).queryid;
             qop := ntfnds.QUERY_DESC_ARRAY(i).queryop;
             INSERT INTO nfqueries VALUES(qid, qop);
             numtables := 0;
             numtables := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array.count;
             FOR j IN 1..numtables LOOP
               tbname := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array(j).table_name;
               operation_type := ntfnds.QUERY_DESC_ARRAY(i).table_desc_array(j).Opflags;
               INSERT INTO nftablechanges VALUES(qid, tbname, operation_type);
               IF (bitand(operation_type, DBMS_CQ_NOTIFICATION.ALL_ROWS) = 0)
               THEN
                 numrows := ntfnds.query_desc_array(i).table_desc_array(j).numrows;
               ELSE
                 numrows :=0;   /* ROWID INFO NOT AVAILABLE */
               END IF;
     
                /* The body of the loop is not executed when numrows is ZERO */
                FOR k IN 1..numrows LOOP
                   Row_id := ntfnds.query_desc_array(i).table_desc_array(j).row_desc_array(k).row_id;
                   INSERT INTO nfrowchanges VALUES(qid, tbname, Row_id);
                   
                END LOOP;  /* loop over rows */
             END LOOP;     /* loop over tables */
           END LOOP;        /* loop over queries */
      END IF;
      COMMIT;
    END;
    /
    
    
  2. 問合せの登録を作成します。

    DECLARE
      reginfo    cq_notification$_reg_info;
      mgr_id     NUMBER;
      dept_id    NUMBER;
      v_cursor   SYS_REFCURSOR;
      regid      NUMBER;
      qosflags   NUMBER;  
    
    BEGIN
      /* Register two queries for result-set-change notifications: */
    
      /* 1. Construct registration information.
            'chnf_callback' is name of notification handler.
            QOS_QUERY specifies result-set-change notifications. */
     
       qosflags := DBMS_CQ_NOTIFICATION.QOS_QUERY + 
                   DBMS_CQ_NOTIFICATION.QOS_ROWIDS;
    
       reginfo := cq_notification$_reg_info('chnf_callback', qosflags,0, 0, 0);
     
      /* 2. Create registration */
     
            regid := DBMS_CQ_NOTIFICATION.NEW_REG_START(reginfo);
     
            OPEN v_cursor FOR 
               SELECT DBMS_CQ_NOTIFICATION.CQ_NOTIFICATION_QUERYID, manager_id
               FROM HR.employees
               WHERE employee_id = 7902;
            CLOSE v_cursor;
     
           OPEN v_cursor for
            SELECT DBMS_CQ_NOTIFICATION.CQ_NOTIFICATION_QUERYID, department_id
            FROM HR.departments
            WHERE department_name = 'IT';
           CLOSE v_cursor;
     
      DBMS_CQ_NOTIFICATION.REG_END;
    END;
    /
    
  3. 問合せの登録を作成すると、USER_CQ_NOTIFICATION_QUERIESからの出力が次のように表示されます。

    SQL> SELECT queryid, regid, to_char(querytext) 
         FROM user_cq_notification_queries;
     
       QUERYID      REGID
    ---------- ----------
    TO_CHAR(QUERYTEXT)
    --------------------------------------------------------------------------------
            22         41
     SELECT HR.DEPARTMENTS.DEPARTMENT_ID  FROM HR.DEPARTMENTS  WHERE HR.DEPARTMENTS.
    DEPARTMENT_NAME  = 'IT'
     
            21         41
     SELECT HR.EMPLOYEES.MANAGER_ID  FROM HR.EMPLOYEES  WHERE HR.EMPLOYEES.EMPLOYEE_
    ID  = 7902
     
     
    Now, let us perform an UPDATE that changes the result of the query with queryid 22
    by renaming the department with name 'IT' to FINANCE.
     
    SQL>  update departments set department_name = 'FINANCE' where department_name = 'IT';
     
    1 row updated.
     
    SQL> commit;
     
    Commit complete.
     
    Now we can query the notifications that we recorded in the callback.
     
    SQL> select * from nfevents;
     
         REGID EVENT_TYPE
    ---------- ----------
            61          7
     
     
    Event type 7 corresponds to EVENT_QUERYCHANGE
     
    SQL> select * from nfqueries;
     
           QID        QOP
    ---------- ----------
            42          7
     
    Event type 7 corresponds to EVENT_QUERYCHANGE
     
    SQL> select * from nftablechanges;
    SQL> select * from nftablechanges;
     
         REGID
    ----------
    TABLE_NAME
    --------------------------------------------------------------------------------
    TABLE_OPERATION
    ---------------
            42
    HR.DEPARTMENTS
                  4
     
     
    TABLE_OPERATION 4 corresponds to UPDATEOP
     
    SQL> select * from nfrowchanges;
         REGID
    ----------
    TABLE_NAME
    --------------------------------------------------------------------------------
    ROW_ID
    --------------------------------------------------------------------------------
            61
    HR.DEPARTMENTS
    AAANkdAABAAALinAAF

36.6 DBMS_CQ_NOTIFICATIONのデータ構造

DBMS_CQ_NOTIFICATIONパッケージは、複数のOBJECTタイプを定義します。

36.6.1 CQ_NOTIFICATION$_DESCRIPTORオブジェクト・タイプ

これは、トップレベルの変更通知記述子タイプです。これは、SYS.CHNF$_DESCタイプのシノニムです。

構文

TYPE SYS.CHNF$_DESC IS OBJECT(
   registration_id    NUMBER,
   transaction_id     RAW(8),
   dbname             VARCHAR2(30),
   event_type         NUMBER,
   numtables          NUMBER,
   table_desc_array   CQ_NOTIFICATION$_TABLE_ARRAY,
   query_desc_array   CQ_NOTIFICATION$_QUERY_ARRAY);

属性

表36-2 CQ_NOTIFICATION$_DESCRIPTORオブジェクト・タイプ

属性 説明

registration_id

登録時に戻される登録ID。

transaction_id

トランザクションID。変更を行ったトランザクションのtransaction_id。event_typeがEVENT_OBJCHANGEまたはEVENT_QUERYCHANGE以外の場合は、NULLになります。

dbname

データベースの名前。

event_type

通知に関連付けられているデータベース・イベント。EVENT_OBJCHANGE(登録されたオブジェクトへの変更)、EVENT_STARTUPEVENT_QUERYCHANGEEVENT_SHUTDOWNEVENT_DEREG(タイムアウトなどの理由で登録が削除された)のいずれかになります。

numtables

変更された表の数。event_typeEVENT_OBJCHANGE以外の場合は、NULLになります。

table_desc_array

表記述子の配列。event_typeEVENT_OBJCHANGE以外の場合は、NULLになります。

query_desc_array

変更された問合せの配列。event_typeがEVENT_QUERYCHANGE以外の場合は、NULLになります。

36.6.2 CQ_NOTIFICATION$_QUERYオブジェクト・タイプ

このオブジェクト・タイプは、トランザクションのコミットなどのイベントで発生する問合せ結果への変更を示します。

CQ_NOTIFICATION$_QUERY記述子の配列は、EVENT_QUERYCHANGEタイプのイベントに対するトップレベルの通知記述子(CQ_NOTIFICATION$_DESCRIPTOR)内に埋め込まれます。この配列は、イベントの結果として無効になったqueryidのSETに対応します。

これは、ベース・タイプSYS.CHNF$_QDESCのシノニムです。

構文

TYPE SYS.CHNF$_QDESC IS OBJECT (
  queryid            NUMBER,
  queryop            NUMBER,
  table_desc_array   CQ_NOTIFICATION$_TABLE_ARRAY);

属性

表36-3 TYPE SYS.CQ_NOTIFICATION$_QUERYオブジェクト・タイプ

属性 説明

queryid

変更された問合せのQueryId

queryop

問合せへの変更を示す操作

table_desc_array

問合せ結果セットの変更の原因となる表の変更の配列

36.6.3 CQ_NOTIFICATION$_QUERY_ARRAYオブジェクト(配列)タイプ

このタイプは、CQ_NOTIFICATION$_QUERYオブジェクトの配列に対応します。これは、SYS.CHNF$_QUERY_ARRAYタイプのシノニムです。

構文

TYPE CQ_NOTIFICATION$_TABLE_ARRAY IS VARRAY (1073741824) OF CQ_NOTIFICATION$_TABLE;

36.6.4 CQ_NOTIFICATION$_TABLEオブジェクト・タイプ

この記述子タイプは、表への変更を示し、EVENT_OBJCHANGEイベント・タイプに対するトップレベルの変更通知記述子タイプ内に埋め込まれます。問合せ結果セットの変更の場合(イベント・タイプはEVENT_QUERYCHANGEに設定されます)、表記述子の配列は各問合せ変更記述子内に埋め込まれます。

これは、SYS.CHNF$_TDESC (以前の名前)タイプのシノニムです。

構文

TYPE SYS.CHNF$_TDESC IS OBJECT (
  opflags            NUMBER,
  table_name         VARCHAR2(2*M_IDEN+1),
  numrows            NUMBER,
  row_desc_array     CQ_NOTIFICATION$_ROW_ARRAY)

属性

表36-4 TYPE SYS.CQ_NOTIFICATION$_TABLEオブジェクト・タイプ

属性 説明

opflags

表レベルの操作フラグ。これは、表に対して行われた操作内容を表すフラグ・フィールド(ビットベクトル)です。ビット・フィールド(INSERTOPUPDATEOPDELETEOPDROPOPALTEROPおよびALL_ROWS)のORになります。ALL_ROWS (0x1)ビットが設定されている場合は、表全体が変更されている(DELETE * FROM tなど)、または通知で行レベル粒度の情報が要求されていないか使用できないため、受信者は表全体が無効になっていると想定する必要があることを示します。

table_name

変更された表の名前。

numrows

表内の変更された行の数。表変更記述子にALL_ROWSビットがセットされている場合、numrowsはNULLになるため、アクセスしないでください。

row_desc_array

行記述子の配列。opflagsALL_ROWSビットがセットされている場合、このフィールドはNULLになります。

36.6.5 CQ_NOTIFICATION$_TABLE_ARRAYオブジェクト(配列)タイプ

このタイプは、CQ_NOTIFICATION$_TABLEオブジェクトの配列に対応します。これは、SYS.CHNF$_TDESC_ARRAYタイプのシノニムです。

構文

TYPE CQ_NOTIFICATION$_TABLE_ARRAY IS VARRAY (1073741824) OF CQ_NOTIFICATION$_TABLE;

36.6.6 CQ_NOTIFICATION$_ROWオブジェクト・タイプ

登録時にQOS_ROWIDSオプションを選択し、表変更記述子のopflagsフィールドにALL_ROWSビットがセットされていない場合、CQ_NOTIFICATION$_ROWの配列が、CQ_NOTIFICATION$_TABLE (表変更記述子)内に埋め込まれます。

これは、SYS.CHNF$_RDESC (以前の名前)タイプのシノニムです。

構文

TYPE SYS.CHNF$_RDESC IS OBJECT (
  opflags            NUMBER,
  row_id             VARCAHR2 (2000));

属性

表36-5 TYPE SYS.CQ_NOTIFICATION$_ROWオブジェクト・タイプ

属性 説明

opflags

行レベルの操作フラグ。このフラグ・フィールド(ビットベクトル)は、行の操作内容(INSERTOPUPDATEOPDELETEOPなど)を表します。

row_id

変更した行のROWID。

36.6.7 CQ_NOTIFICATION$_ROW_ARRAYオブジェクト(配列)タイプ

このオブジェクト・タイプは、CQ_NOTIFICATION$_ROWオブジェクトの配列に対応します。これは、登録時にQOS_ROWIDSを指定し、表変更記述子のopflagsフィールドにALL_ROWSビットがセットされていない場合、CQ_NOTIFICATION$_TABLE内に埋め込まれます。

これは、SYS.CHNF$_RDESC_ARRAYタイプのシノニムです。

構文

TYPE CQ_NOTIFICATION$_ROW_ARRAY IS VARRAY (1073741824) OF CQ_NOTIFICATION$_ROW;

36.6.8 CQ_NOTIFICATION$_REG_INFOオブジェクト・タイプ

このオブジェクト・タイプは、登録の新規作成に関連する属性を表します。これは、SYS.CHNF$_REG_INFO (以前の名前)タイプのシノニムです。

構文

TYPE SYS.CHNF$_REG_INFO IS OBJECT (
  callback                        VARCHAR2(20),
  qosflags                        NUMBER,
  timeout                         NUMBER,
  operations_filter               NUMBER,
  transaction_lag                 NUMBER,
  ntfn_grouping_class             NUMBER,
  ntfn_grouping_value             NUMBER,
  ntfn_grouping_type              NUMBER,
  ntfn_grouping_start_time        TIMESTAMP WITH TIME ZONE,
  ntfn_grouping_repeat_count      NUMBER);

属性

表36-6 TYPE CQ_NOTIFICATION$_REG_INFOオブジェクト・タイプ

属性 説明

callback

通知時に実行するサーバー側のPL/SQLプロシージャの名前。プロトタイプは、<call_backname>(ntfnds IN SYS.chnf$_desc)です。

qosflags

サービス品質フラグ。次の値のORに設定できます。

  • QOS_RELIABLE(0x1): 通知は信頼性(永続性)があり、インスタンスの停止後も有効です。これは、Oracle RACクラスタでインスタンスが停止した場合に、停止していないインスタンスによって、キュー内の無効化情報を配信できることを意味します。同様に、保留になっている無効化情報は、単一インスタンス構成で、インスタンスの再起動時に配信可能です。デメリットは、無効化メッセージを永続ストアに挿入すると発生するCPUコストおよび待機時間です。このパラメータがFALSEの場合は、イン・メモリー・キューに無効化情報がバッファリングされるため、サーバー側のCPUおよび待機時間は最小になりますが、インスタンスの停止時にクライアントが無効化メッセージを失う可能性があります。

  • QOS_DEREG_NFY(0x2): 最初の通知時に登録が完全削除されます。

  • QOS_ROWIDS(0x4): 変更されたROWIDに関する情報を通知に含める必要があります。

  • QOS_QUERY(0x8): オブジェクトの変更通知ではなく、問合せ結果の変更通知を指定します。

  • QOS_BEST_EFFORT (0x10)またはQOS_BEST_EFFORT (0x16): 簡易版の問合せを登録し、評価を最小化できます。一部偽陽性が発生します。

timeout

0(ゼロ)以外の値に設定すると、その時間(秒)の経過後にデータベースによって登録が自動的に完全削除されます。0(ゼロ)またはNULLに設定すると、登録は、明示的に登録解除するまで存在します。timeoutオプションは、通知時にパージするオプション(QOS_DEREG_NFY)と組み合せて設定することもできます。

operations_filter

0(ゼロ)以外の場合は、特定の操作を選択して通知するフィルタを指定します。次のフラグを使用すると、特定の操作のタイプに基づいてフィルタ処理を行うことができます。

  • 0: すべての操作について通知(DBMS_CQ_NOTIFICATION.ALL_OPERATIONS)

  • 0x2: すべてのINSERTについて通知(DBMS_CQ_NOTIFICATION.INSERTOP)

  • 0x4: すべてのUPDATEについて通知(DBMS_CQ_NOTIFICATION.UPDATEOP)

  • 0x8: すべてのDELETEについて通知(DBMS_CQ_NOTIFICATION.DELETEOP)

ビット単位のORを使用すると、操作を組み合せて指定できます。

注意: このパラメータはオブジェクト・レベルの登録には有効ですが、問合せ結果の変更の登録では無視されます。11gで通知フロー制御を実装するために、アプリケーションではGROUPING通知オプションを使用できます。

transaction_lag

トランザクション単位で指定する、連続する通知間のタイム・ラグ。トランザクション数/データベース変更数の指定に使用でき、これによって、クライアントによるデータベースに対する遅れを指定できます。0 (ゼロ)の場合、生成直後にクライアントが無効化メッセージを受信する必要があることを意味します。

注意: このパラメータはオブジェクト・レベルの登録には有効ですが、問合せ結果の変更通知の登録では無視されます。

ntfn_grouping_class

通知をグループ化するときに、このクラスに基づきグループが導出されます。現在、使用できる値は、通知を時間別にグループ化するDBMS_CQ_NOTIFICATION.NTFN_GROUPING_CLASS_TIMEのみです。

ntfn_grouping_value

グループ化の値。グループを定義する時間間隔を秒単位で指定します。たとえば、この値を900に設定した場合、生成された通知は15分間隔でグループ化されます。

ntfn_grouping_type

指定するグループ化のタイプ。使用できる2つの値のいずれかを指定します。

  • DBMS_CQ_NOTIFICATION.NTFN_GROUPING_TYPE_SUMMARY: グループ内のすべての通知が、単一の通知に要約されます。

  • DBMS_CQ_NOTIFICATION.NTFN_GROUPING_TYPE_LAST: グループ内の最後の通知のみが公開され、それより前の通知は破棄されます。

ntfn_grouping_start_time

通知の生成を開始する時間。NULLを指定すると、現行のシステムで生成される時間がデフォルトとなります。

ntfn_grouping_repeat_count

通知が繰り返される回数。登録の存続期間を通して通知を受け取り続けるには、この値をDBMS_CQ_NOTIFICATION.NTFN_GROUPING_FOREVERに設定します。登録の存続期間に対して特定の回数の通知のみを要求する場合は、0(ゼロ)以外の値に設定します。

使用上の注意

  • このタイプ宣言は、他の3つの代替コンストラクタを組み込みます。1番目のケースでは、他のすべてのパラメータがデフォルト値に設定されます。

    TYPE CQ_NOTIFICATION$_REG_INFO IS OBJECT (
      callback                        VARCHAR2(20),
      qosflags                        NUMBER,
      timeout                         NUMBER);
    

    2番目のオプションは、以前のリリースで定義されたタイプ・コンストラクタに適用されます(下位互換性のために保持されています)。

    TYPE CQ_NOTIFICATION$_REG_INFO IS OBJECT (
      callback                        VARCHAR2(20),
      qosflags                        NUMBER,
      timeout                         NUMBER,
      operations_filter               NUMBER,
      transaction_lag                 NUMBER);
    

    3番目の定義には、推奨されていないtransaction_lagを除いて、タイプのメンバーがすべて含まれます。

    TYPE CQ_NOTIFICATION$_REG_INFO IS OBJECT (
      callback                        VARCHAR2(20),
      qosflags                        NUMBER,
      timeout                         NUMBER,
      operations_filter               NUMBER,
      ntfn_grouping_class             NUMBER,
      ntfn_grouping_value             NUMBER,
      ntfn_grouping_type              NUMBER,
      ntfn_grouping_start_time        TIMESTAMP WITH TIME ZONE,
      ntfn_grouping_repeat_count      NUMBER);
    
  • データベース変更に対応して、callbackで指定されたサーバー側のPL/SQLプロシージャが実行されます。PL/SQLプロシージャの名前は、schema_name.procedure_nameの形式で指定する必要があります。このプロシージャには、次の署名が必要です。

    PROCEDURE <procedure_name>(ntfnds IN SYS.chnf$_desc)
    

    CHNF$_DESCは、変更通知記述子を示します。

  • 指定したプロシージャは、通知の生成時にジョブ・キュー・プロセス内で実行されるため、PL/SQL通知を受け取るには、init.oraのパラメータjob_queue_processesを0(ゼロ)以外の値に設定する必要があります。

36.7 DBMS_CQ_NOTIFICATIONサブプログラムの要約

この表は、DBMS_CQ_NOTIFICATIONサブプログラムを示し、簡単に説明しています。

表36-7 DBMS_CQ_NOTIFICATIONパッケージのサブプログラム

サブプログラム 説明

CQ_NOTIFICATION_QUERYIDファンクション

登録ブロックへの登録が試行された最新の問合せのqueryidを戻します。

DEREGISTERプロシージャ

指定した登録識別子(ID)のクライアントのサブスクライブを解除します。

ENABLE_REGプロシージャ

既存の登録識別子(ID)を使用して、登録ブロックを開始します。

NEW_REG_STARTファンクション

新しい登録ブロックを開始します。

REG_ENDプロシージャ

登録範囲を終了します。

SET_ROWID_THRESHOLDプロシージャ

トランザクションで表の行が変更された場合に変更通知でパブリッシュされる表の行の最大数を設定します。

36.7.1 CQ_NOTIFICATION_QUERYIDファンクション

このファンクションは、登録ブロックへの登録が試行された最新の問合せのqueryidを戻します。

構文

DBMS_CQ_NOTIFICATION.CQ_NOTIFICATION_QUERYID
 RETURN NUMBER;

戻り値

登録された最新の問合せのqueryidを戻します。

36.7.2 DEREGISTERプロシージャ

このプロシージャは、指定した登録識別子(ID)のクライアントを示します。

構文

DBMS_CQ_NOTIFICATION.DEREGISTER (
  regid IN NUMBER);

パラメータ

表36-8 DEREGISTERプロシージャのパラメータ

パラメータ 説明

regid

クライアントの登録ID。

使用上の注意

登録を作成したユーザー(またはSYSユーザー)のみが、その登録のサブスクライブを解除できます。

36.7.3 ENABLE_REGプロシージャ

このプロシージャは、既存の登録識別子(ID)にオブジェクトを追加します。

これは、オブジェクトの追加に既存のregidを使用することを除くと、新規登録の作成に使用するインタフェースに似ています。この後、問合せで参照されるオブジェクトが、指定したregidに追加され、REG_ENDプロシージャを起動すると、登録が終了します。

構文

DBMS_CQ_NOTIFICATION.ENABLE_REG (  
  regid IN NUMBER);

パラメータ

表36-9 ENABLE_REGプロシージャのパラメータ

パラメータ 説明

regid

クライアントの登録ID。

使用上の注意

登録を作成したユーザーのみが、その登録にオブジェクトを追加できます。

36.7.4 NEW_REG_STARTファンクション

このプロシージャは、新しい登録ブロックを開始します。

この登録ブロック内で実行する問合せによって参照されるすべてのオブジェクトは、優先度が高いオブジェクトとみなされ、登録に追加されます。登録ブロックは、REG_ENDプロシージャをコールすると終了します。

構文

DBMS_CQ_NOTIFICATION.NEW_REG_START (  
  regds IN sys.chnf$_reg_info)
 RETURN NUMBER;

パラメータ

表36-10 NEW_REG_STARTファンクションのパラメータ

パラメータ 説明

sys.chnf$_reg_info

通知ハンドラなどの登録プロパティを示す登録記述子。

戻り値

このプロシージャは、登録ID(データベースによってこの登録に割り当てられた一意の整数)を戻します。登録IDは、この登録に関して受け取るすべての通知でエコーバックされます。

使用上の注意

  • 登録ブロック内で実行可能な操作は、(ユーザーが登録する)問合せのみです。DML操作およびDDL操作は実行できません。

  • 登録ブロックは、セッションのプロパティであり、セッションを終了すると暗黙的に終了されます。登録ブロックはセッションのプロパティですが、登録自体は永続的なデータベース・エンティティです。作成された登録は、クライアント・アプリケーションまたはタイムアウトによって明示的に登録解除されるか、またはその他の理由(権限の失効など)でデータベースによって削除されるまで存在します。

  • ユーザーには、CHANGE NOTIFICATIONシステム権限および登録するオブジェクトに対するSELECTまたはREAD権限が必要です。

  • SYSユーザーは、登録の新規作成を実行できません。

  • 登録ブロックは、ネストできません。

36.7.5 REG_ENDプロシージャ

このプロシージャは、登録ブロックの終了を示します。これ以降に実行される問合せは追跡されません。

構文

DBMS_CQ_NOTIFICATION.REG_END;

36.7.6 SET_ROWID_THRESHOLDプロシージャ

このプロシージャは、トランザクションで表の行が変更された場合に変更通知でパブリッシュされる表の行の最大数を設定します。

構文

DBMS_CQ_NOTIFICATION.SET_ROWID_THRESHOLD (  
  tbname     IN  VARCHAR2,
  threshold  IN  NUMBER);

パラメータ

表36-11 SET_ROWID_THRESHOLDプロシージャのパラメータ

パラメータ 説明

tbname

schemaname.tablenameの形式でスキーマ名で修飾された表名

threshold

変更通知でパブリッシュされる表の変更行の最大数

使用上の注意

  • オブジェクトの変更粒度または問合せ結果セットの粒度のいずれかで変更通知用に表を登録する必要があります。

  • このサブプログラムを使用して設定したしきい値は、そのインスタンスにのみ適用され、インスタンスの起動や停止を行うと存続しなくなります。