ヘッダーをスキップ
Oracle Databaseルール・マネージャおよび式フィルタ開発者ガイド
11gリリース1(11.1)
E05697-01
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

4 イベントおよびルール・クラス構成

ルール・アプリケーションでは、データ型はイベント構造に含まれており、イベント・ソースはアプリケーションに依存しています。ルール・マネージャは、Oracleリッチ・タイプ・システムを使用して、XML、空間およびテキストなどの複合データ型を含むルール・アプリケーションをサポートします。同様に、データベースとの統合を活用して、データへのトランザクション、または非トランザクションの変更をイベントのソースとして取得します。

この章では、データベースにルール・アプリケーションを設計する際に、最高の柔軟性を提供する様々なイベントおよびルール・クラス構成について説明します。

4.1 リレーショナル表に指定されるルール

これまで検討してきたルール・アプリケーションは、アプリケーション・データに定義されているルール条件を使用します。つまり、イベント・インスタンスの概念はアプリケーションに存在し、データベースには格納される場合も格納されない場合もあります。ただし、一部の行に対応するイベント・インスタンスのデータは、リレーショナル表に格納されることがよくあります。そのようなアプリケーションでは、これらの行の行識別子(ROWID)を使用して、ルール・マネージャ・プロシージャにデータを参照渡しできます。たとえば、event_instパラメータを使用して、PROCESS_RULESコールのイベント・インスタンスを示します(event_inst => :FlightDataRowid)。そのために、対応するイベント構造は、式フィルタの表別名の構成メンバーを使用してモデル化してください。詳細は、「ADD_ELEMENTARY_ATTRIBUTEプロシージャ」を参照してください。その他の例は、第10.2項および付録Aを参照してください。

第2.4項のトラベル・サービス・アプリケーションでは、AddFlightおよびAddRentalCarのプリミティブ・イベントがそれぞれFlightDataおよびRentalCarDataの2つのリレーショナル表に格納される場合は、次のように対応するコンポジット・イベント構造を作成し、これらの表の行を参照できます。

BEGIN  DBMS_RLMGR.CREATE_EVENT_STRUCTURE (event_structure => 'TSCompEvent');
  DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE (
                           event_structure => 'TSCompEvent',
                           attr_name => 'Flt', --- Prim event name
                           tab_alias => rlm$table_alias('FlightData'));
  DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE (
                           event_structure => 'TSCompEvent',
                           attr_name => 'Car', --- Prim event name
                           tab_alias => rlm$table_alias('RentalCarData'));
END;

これで、コンポジット・イベント構造TSCompEventを使用して、(第2.4.1項の手順2と同様に)ルール・クラスを構成できるようになりました。ルール・クラスでのルールの表現は、このイベント構造によって変化することはありません。ただし、アクション・コールバック・プロシージャ内でルールと一致するプリミティブ・イベント・インスタンスは、対応する表からROWIDとして渡され、これらのROWIDを使用して元のイベント・データを取得できます。また、この新しいイベント構造では、対応する表の行のROWIDを使用してプリミティブ・イベント・インスタンスが参照渡しされ、ルールが処理されます。

BEGIN
  dbms_rlmgr.process_rules (
            rule_set_nm => 'TravelPromotion',
            event_type => 'FlightData',
            event_inst => :FlightDataRowid); -- rowid of a row ---
END;

適切なROWIDを使用してdbms_rlmgr.process_rulesプロシージャが起動されると、プリミティブ・イベントに対応する条件が評価されることに注意してください。ただし、ルール・マネージャでは、UPDATE操作を介した元の行への変更は追跡しません。

必要に応じて、対応する表へのすべてのDML操作(INSERTUPDATE、およびDELETE)をイベントとみなすように、前述のルール・クラスを構成することで、PROCESS_RULESコールを排除できます。この処理は、ルール・クラスの作成時に、DMLEVENTSまたはCNFEVENTSプロパティを使用して実行されます。(第3.7項および第3.8項を参照)

継続時間ポリシーおよび使用率ポリシーが関連データから導出されたプリミティブ・イベントに設定されている場合は、ルール・クラスに対して使用または削除される表の行への参照となります。これらのイベント管理ポリシーによって、元の行が影響されることはありません。コンポジット・イベント構造は、表別名の構成メンバーと(様々なプリミティブ・イベントの)埋込み抽象データ型(ADT)の組合せを使用して形成できます。1つ以上の表別名の構成メンバーで構成されるコンポジット・イベント構造に対して定義されるルール条件には、プリミティブ・イベント間の順序付けを実施するSEQUENCEプロパティ(短い形式)を使用できない場合があります(第5.2項を参照)。これは、リレーショナル表に格納されている行には暗黙的な属性rlm$crttimeが存在していない可能性があるためです。ユーザーは、ルール条件で結合プロパティを使用して、部分的な順序付けを実施できます。

4.2 XMLイベントのルール条件

オラクル社が提供するXMLTypeデータ型を使用すると、XML文書に定義されているルールを処理できる属性をイベント構造およびルール・クラスに作成できます。そのために、次のような1つ以上のXMLType属性を(非XML属性とともに)使用してプリミティブ・イベント構造を作成できます。

CREATE or REPLACE TYPE AddFlight AS OBJECT (
                  CustId NUMBER,
                  Airline VARCHAR(20),
                  FromCity VARCHAR(30),
                  ToCity VARCHAR(30),
                  Depart DATE,
                  Return DATE,
                  Details sys.XMLType)

プリミティブ・イベントが単にXML文書の場合は、前述のオブジェクト型を1つの属性(つまり、XMLType)のみで作成できます。XMLType属性の述語は、次の例に示すように、オラクル社が提供するEXTRACTおよびEXISTSNODE演算子を使用して指定されます。

<condition> <!-- optional for conditions on primitive events -->
   Airline='Abcair' and ToCity='Orlando' and
            EXTRACT(doc, '/preferences/seat[@class="economy"]') is not null
</condition>

XMLイベントのコンポジット・イベント構造は、XMLType属性が含まれている2つ以上のプリミティブ・イベント・タイプを指定することで形成できます。したがって、コンポジット・イベント構造は、埋込みプリミティブ・イベント・タイプを備えたオブジェクト型として作成されます(第2.4項を参照)。XMLType属性を使用してイベント構造が作成されると、その他すべての概念(第2.2項を参照)がイベントの一部であるXMLデータに適用されます。

XPath述語の処理方法および索引付けの方法の詳細は、第13章を参照してください。

4.3 空間述語を使用したルール条件


注意:

格納されている式で空間述語を使用するには、Oracle Spatialまたはロケータ・コンポーネントがインストールされている必要があります。

オラクル社が提供するSDO_GEOMETRYデータ型を使用すると、空間ジオメトリに定義されているルールを処理できるイベント構造およびルール・クラスを作成できます。そのために、次のようにMDSYS.SDO_GEOMETRY型の1つ以上の属性を使用して、プリミティブ・イベント構造を作成できます。

CREATE or REPLACE TYPE AddHotel AS OBJECT (
       CustId    NUMBER,
       Type      VARCHAR(20),
       CheckIn   DATE,
       CheckOut  DATE,
       Location  MDSYS.SDO_GEOMETRY)

空間属性に対して述語を指定し、効率を上げるためにその述語を索引付けするには、ディメンション、上限、下限、および各ディメンションの許容差を記述したジオメトリ・メタデータが、各空間ジオメトリ属性に関連付けられている必要があります。このメタデータ情報は、表名のかわりにイベント構造名を使用して、USER_SDO_GEOM_METADATAビューに挿入できます。USER_SDO_GEOM_METADATAビューとそのセマンティクスの詳細は、『Oracle Spatial開発者ガイド』を参照してください。

INSERT INTO user_sdo_geom_metadata VALUES ('ADDHOTEL','LOCATION',
        mdsys.sdo_dim_array(
             mdsys.sdo_dim_element('X',  -180, 180, 0.5),
             mdsys.sdo_dim_element('Y',  -90, 90, 0.5)), 8307);

空間属性を備えたイベント構造を使用してルール・クラスを作成すると、ルール・クラス表に格納されているルール条件には、SDO_WITHIN_DISTANCEまたはSDO_RELATE演算子を使用して、これらの属性の述語を指定できます。次に例を示します。

<condition>
  Type = 'Luxury' and CheckOut-CheckIn > 3 and
    SDO_WITHIN_DISTANCE (Location,
      SDO_GEOMETRY(2001, 8307,
        SDO_POINT_TYPE(-77.03644, 37.89868, NULL), NULL, NULL),
      'distance=0.5 units=mile') = 'TRUE'
</condition>

<condition>
  Type = 'Luxury' and CheckOut-CheckIn > 3 and
    SDO_RELATE (Location,
      SDO_GEOMETRY(2001, 8307, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 3),
         SDO_ORDINATE_ARRAY(-77.03644, 37.89868, -75, 39),
      'mask=anyinteract') = 'TRUE'
</condition>

空間属性を伴うコンポジット・イベント構造は、SDO_GEOMETRY属性が含まれている2つ以上のプリミティブ・イベント構造を指定することで形成できます。コンポジット・イベントに対して指定されたルールの場合、ルール条件の結合句には、SDO_WITHIN_DISTANCEまたはSDO_RELATE演算子を伴う空間述語を使用できません。必要な場合は、MDSYS.SDO_GEOMパッケージに定義されている関数を使用して、この機能を実現できます。詳細は、『Oracle Spatial開発者ガイド』を参照してください。

4.4 テキスト・イベントのルール条件

ルール・クラスに関連付けられたイベント構造は、対応するルール条件がこれらの属性のテキスト述語を含むように、1つ以上のテキスト属性に対して構成されます。ルール条件のテキスト述語は、Oracle TextのCONTAINS演算子を使用して指定されます。CONTAINS演算子は、イベント構造で定義されたテキスト属性を参照し、この属性にバインドされた文書に対してテキスト問合せ式を適用します。

イベント構造内のテキスト属性は、テキスト・プリファレンスに関連付けられたCLOBまたはVARCHARデータ型になるように定義されます。このような属性は、DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTEプロシージャを使用して作成されます。属性に対するテキスト・プリファレンスは、EXF$TEXT型のインスタンスを使用して指定され、文字列形式で受け取ります(例: LEXER hotelreserv_lexer WORDLIST hotelreserv_wordlist)。この引数を介して指定されたプリファレンスは、属性にバインドされた文書の解析や、ルール条件内のテキスト問合せ式の索引付けに使用されます。または、空のプリファレンス文字列のEXF$TEXTインスタンスが、デフォルトのプリファレンスの使用に割り当てられます。

第2.4項で説明されたトラベル・サービスのアプリケーションで、各ホテル予約に情報が追加される場合、AddHotelイベント構造は次のようにモデル化されます。

BEGIN
  DBMS_RLMGR.CREATE_EVENT_STRUCT (EVENT_STRUCT => 'AddFlight');
  DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE (
                       EVENT_STRUCT => 'AddHotel',
                       ATTR_NAME => 'CustId',
                       ATTR_TYPE => 'NUMBER');
  DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE (
                       EVENT_STRUCT => 'AddHotel',
                       ATTR_NAME => 'Type',
                       ATTR_TYPE => 'VARCHAR2(20)');
  . . .
  DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE (
                       EVENT_STRUCT => 'AddHotel',
                       ATTR_NAME => 'AddlInfo',
                       ATTR_TYPE => 'CLOB',
                       TEXT_PREF => EXF$TEXT('LEXER hotelreserv_lexer'));
END;

前述のイベント構造で指定されたルール条件は、次のようなAddlInfo属性でテキスト述語を含むことができます。

    Type = 'Luxury' and CONTAINS (AddlInfo, 'Disney World') = 1

1つ以上の属性で作成されたイベント構造は、コンポジット・イベント構造の一部であるため、テキスト述語が次のような個別のプリミティブ・イベントで指定できます。

     <condition>
        <and equal="Car.CustId, Hotel.CustId">
           <object name="Car"> carType = 'Luxury' </object>
           <object name="Hotel"> Type = 'Luxury' and
                          CONTAINS (AddlInfo, 'Disney World') = 1 </object>
        </and>
     </condition>

コンポジット・イベントに指定されたルールの場合、テキスト属性を含む述語はルール条件の結合句に使用できません。CONTAINS演算子は、プリミティブ・イベント条件の範囲内でのみ有効です。ルール条件のテキスト述語は、各テキスト属性に暗黙的に作成されたCTXRULE索引を使用して処理されます。他の索引形式と違って、CTXRULE索引は本来トランザクション用ではありません。つまり、ルール条件へのあらゆる変更は、対応するCTXRULE索引に自動的に反映されません。これにより、テキスト索引が更新されたルール条件と同期化しないかぎり、イベントとルール条件の不正確な一致が発生する可能性があります。ルール・クラスに関連付けられたすべてのテキスト索引は、次のコマンドと同期化されます。

BEGIN
  DBMS_RLMGR.SYNC_TEXT_INDEXES (rule_class => 'CompTravelPromo');
END;

前述のコマンドを実行するためには、CTX_DDLパッケージのEXECUTE権限が必要です。

4.5 ルールの無効化および有効化

ルール・クラスにルールを追加し、それを無効化する必要がある場合があります。それらのルールはなおもルール・クラスに属するため、後で有効化できます。そのために、DBMS_RLMGR.CREATE_RULE_CLASSプロシージャで作成されたルール・クラス表には、暗黙的に各ルールのステータスを格納するためrlm$enabled列が含まれます。Oracle Database 10gのアップグレードによるルール・クラスの場合、この列は存在しません。また、そのようなルール・クラスのルールは無効化できません。ルール・クラス表のrlm$enabled列は、デフォルトでは「Y」の値が設定されていて、デフォルトではルールは常に有効です。オプションで、新規のルールの挿入時または既存のルールの更新時に「N」の値を列に割り当てることもできます。rlm$enabled列に「N」が割り当てられたルールは無効であるため、受け取ったイベントすべてと一致しません。rlm$enabled列へのあらゆる修正またはルール条件自体への修正は、ルールに関連付けられた中間状態の情報をすべて破棄します。実際、既存ルールが無効化された後に有効化された場合は、前の状態の情報は一切引き継がれないため、新規のルールと同等になります。

4.6 共有可能なプリミティブ・ルール条件

コンポジット・イベントに定義されたルールは、各プリミティブ・イベントに基づいた条件と、これらのプリミティブ・イベントに関連する結合条件で構成されています。ルール・ベースの多くのアプリケーションでは、コンポジット・イベントを含む複数のルール条件で、プリミティブ・イベントの同一の条件式が使用されます。たとえば、第2.4項で説明されたトラベル・サービス・アプリケーションでは、Orlandoでの休暇は、最低4日の滞在でのOrlandoへの周遊旅行として定義されています(ToCity = 'Orlando' and Return-Depart >= 4)。同じOrlandoでの休暇に、高級車レンタルを付けたプリミティブ・イベント条件を結合したり、チャイルド・シート・オプションのある車をレンタルする別の条件を結合できます。そのようなアプリケーションに対して、ルール・マネージャは、プリミティブ・ルール条件のリポジトリへの参照を使用して、ルール間でルール条件の一部を共有できます。リポジトリ内で、各プリミティブ・ルール条件は一意の識別子を持ち、プリミティブ条件を共有する1つ以上のルールから参照できます。プリミティブ条件を共有できることで、コンポジット・イベントに対するルール条件の構造を単純化し、共有化されたプリミティブ・ルール条件への変更に対して、1つの論理単位として管理が可能になります。

共有可能なルール条件は、プリミティブ・イベント構造に関連付けられており、特別なルール・クラスには属しません。そのため、プリミティブ・イベント構造に定義されたルール条件の共通リストは、複数のルール・クラスで定義された(同一のプリミティブ・イベント構造で構成された)ルール同様、ルール・クラス内の複数のルール間で共有可能です。

イベント構造作成の基本手順に加え、ルール・クラスおよびアクション・コールバック・プロシージャ、共有可能なプリミティブ・ルール条件のあるルール・アプリケーションは、次の手順で実行します。

  1. 指定のオブジェクト型(プリミティブ・イベント構造として構成する場合)または既存のプリミティブ・イベント構造に対するプリミティブ・ルール条件のリポジトリを作成します。

    BEGIN
      dbms_rlmgr.create_conditions_table(
            cond_table    => 'FlightConditions',
            pevent_struct => 'AddFlight');
    END;
    
    

    前述の手順により、プリミティブ・ルール条件を格納するリレーショナル表が作成されます。この表はユーザーが指定した名前(FlightConditions)で作成され、各ルール条件(rlm$condid)に対する一意の識別子(プライマリ・キー)、ルール条件(rlm$condition)およびプレーン・テキストでのルール説明(rlm$conddesc)を格納する一連の列が含まれます。操作時に、プリミティブ・イベント引数に指定されたプリミティブ・イベント構造がデータベース内で1つのオブジェクト型で、ルール・クラスに関連付けられていない場合、オブジェクト型はイベント構造に変換され、式のメタデータとしてrlm$condition列に後で割り当てられます。


    注意:

    プリミティブ・ルール条件表は、最低でも1つはイベント構造に関連付けられます。

  2. 手順1で作成した表にプリミティブ・ルール条件を挿入します。条件列(rlm$condition)に格納された値は、関連付けられているイベント構造を使用して自動的に検証されます。

    INSERT INTO FlightConditions (rlm$condid, rlm$conddesc, rlm$condition)
     VALUES ('OrlandoVacation', 'Vacation in Orlando',
             'ToCity = ''Orlando'' and Return-Depart >= 4');
    
    
  3. プリミティブ・イベント構造(AddFlight)を使用して1つ以上のルール・クラスが作成されると、ルール・クラスに追加されたルールは、対応するプリミティブ・ルール条件表(FlightConditions)の条件を参照できます。これは、共有のプリミティブ・ルール条件のプライマリ・キーを、ルール条件内の対応するオブジェクト要素の参照属性に割り当てることで、実行されます。

    INSERT INTO CompTravelPromo
      (rlm$ruleid, promoType, offeredBy, rlm$rulecond) VALUES
      ('PARKS_PROMO', 'TICKETS','THEME_PARKS_ASSOC',
       '<condition>
          <and join="Flt.CustId = Car.CustId">
            <object name="Flt" ref="OrlandoVacation"/>
            <object name="Car" ref="LuxuryCarRental"/>
          </and>
        </condition>');
    
    

    前述のルール定義では、プリミティブ・ルール条件参照OrlandoVacationおよびLuxuryCarRentalにより、イベント構造名(それぞれAddFlightAddRentalCar)を介して、対応するプリミティブ・ルール条件表および、プライマリ・キーが決定されます。CompTravelPromo表の複数のルールは、同一プリミティブ・ルール条件を参照できます。

    コンポジット・イベントのルール条件内でのプリミティブ・ルール条件参照は、ルール定義時に決定されます。このようなルールの実行時特性は、インプレースのプリミティブ・ルール条件のルールのそれと類似しており、ルール評価に関する手順は変わりません。


    注意:

    1つ以上のルールに共有されるプリミティブ条件を更新すると、参照するすべてのルールにその変更が伝播されます。ルール自体が事実上更新されたとみなされ、これらのルールに関連付けられたすべての中間状態が破棄されます。

    プリミティブ・ルール条件は、ルール・クラスの1つ以上のルールが参照する場合、削除できません。SQL DROP TABLEコマンドは、プリミティブ・ルール条件表の削除に使用できない場合があります。かわりに、DBMS_RLMGR.DROP_CONDITIONS_TABLEプロシージャが使用されます。プリミティブ条件表は、ルール・クラスが、対応するプリミティブ・イベント構造と一緒に構成されている場合、SQL TRUNCATE TABLEコマンドと一緒に切り捨てできない場合があります。

    条件表に定義されている参照条件を含むルール条件のリストは、結合述語とDBMS_RLMGR.CONDITION_REF関数を使用して条件表とルール・クラス表を結合することで、取得できます。ルール条件およびプリミティブ・イベント名を指定すると、この関数は条件参照に識別子(キー)を戻します。この関数は、ルール条件がこのプリミティブ・イベントに対して参照を使用しない場合は、NULLに戻します。FlightConditions表に格納された共有条件を参照するすべてのルール条件は、次の問合せにより識別されます。

    select ctp.rlm$ruleid from CompTravelPromo ctp, FlightConditions fc
    where dbms_rlmgr.condition_ref(ctp.rlm$rulecond, 'FLT') = fc.rlm$condid;
    
    

    前述の問合せは、定義された関数索引を使用して、条件参照に基づくルール・クラス表から行を取得します。ルール・クラスが、重複する同一タイプのプリミティブ・イベントに対して構成されている場合、前述の問合せには複数の選言と結合された結合述語が含まれる必要があります。また、CONDITION_REF関数に渡されるプリミティブ・イベント名は、関数索引を使用できる前述の問合せに対して、大/小文字区別がありません。プリミティブ・イベント名に大/小文字区別または特殊文字を保つために引用句を要求される場合、引用符で囲まれた名前はCONDITION_REF関数に渡される必要があります。


注意:

1つ以上の条件参照のあるルール・クラスがエクスポートされる場合、対応する条件表は自動的にエクスポートされません。条件表は、EXPORTコマンドの表句を使用して明示的にエクスポートできます。この条件表は、スキーマ・エクスポートに暗黙的に含まれます。IMPORT操作時、ルール条件内のすべての参照は、インポート前に存在していた、またはルール・クラスとともにエクスポートされる条件表を使用して決定されます。ルールの1つが欠落した条件表または条件を参照している場合、ルール・クラスのインポートは失敗し、ORA-41704のエラー・メッセージが表示されます。その場合、無効な参照のルールは、対応するRLM$ENABLED列で格納される値「F」となり、無効としてマーク付けされます。

4.7 データベース変更通知を介するイベント

10gリリース2では、ルール・クラスに使用されるイベント構造が、1つ以上の表別名属性を使用して定義される場合、ルール・クラスは、基礎となる表のINSERT操作(11gではUPDATEおよびDELETEも有効)すべてを、ルールが評価されるイベントとして扱うように構成されます(第3.7項および第4.1項を参照)。これは、ルール・クラスの作成時に、DMLEVENTSプロパティを使用して指定されます。この場合、リレーショナル表の行レベルのトリガーがイベントを取得し、トリガー本体からPROCESS_RULESプロシージャを起動します。ルールはDML操作の一部として処理されるため、この構成は、可能なルール・アクションのタイプの制限(たとえば、ルール・アクションはコミットできないなど)、またはルール・クラスのAUTOCOMMITポリシーのような役割を持ちます。また、ルール・クラスの一致ルールにロックをかけた状態でトランザクションを長い間実行すると、デッドロックを引き起こす場合もあります。

DML操作のコミット後にイベントを識別すると、DMLEVENTS構成の副次的効果を回避できる場合があります。ルール・マネージャには、トランザクションの終了後にトランザクション内の正味のデータ変更に対してルールを処理するオプションが用意されています。この場合、ルール・マネージャは、データベース変更通知機能を使用して(『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照)、各トランザクション終了後に、正味のデータ変更の通知を受け取ります。これらの通知は、変更された行またはイベント・データの取得に使用され、ルール・クラス内のルールに一致します。

1つ以上の表別名属性で作成されたイベント構造を使用するルール・クラスは、ルール・クラス作成時に、変更通知イベントにCNFEVENTSプロパティを使用するように構成されます。ルール・クラスでは、INSERT通知のみ、またはINSERT、UPDATEおよびDELETE通知すべてを、それぞれ、CNFEVENTS="I"のイベント、またはCNFEVENTS="IUD"仕様として扱うように構成できます。CNFEVENTS="I"という構成は、データ付加のみのデータベースには最適です。CNFEVENTSプロパティでルール・クラスを作成したユーザーは、CHANGE NOTIFICATION権限およびDBMS_CHANGE_NOTIFICATIONパッケージでの実行権限が必要です。1つのルール・クラスは、DMLイベントおよび変更通知イベントの両方に対して構成できません。表別名とコンポジット・イベント構造内の埋込みプリミティブ・イベント・タイプの結合を使用すると、他は明示的にアプリケーションによって追加される一方で、ルール・クラスでは、変更通知を介して自動的にイベントのサブセットを取得するように構成できます。

ルールがDML操作と同期的に処理されるDMLEVENTSの場合とは異なり、CNFEVENTS構成では、トランザクションのコミット後に、非同期的にルールが処理されます。一連のトランザクションに対する変更通知が処理される順序が保証されないため、イベントの順序に敏感なルールは、一貫性のない結果を引き起こす場合もあります。また、ルール評価時に検出される行のバージョンが、トランザクション終了時の行のバージョンと異なる場合があります。ルール評価時に最新の行のバージョンを検出することにより、CNFEVENTS="IUD"という構成のルール・クラスには、すべてのイベント(通知)が処理された後、正確な永続的な状態の情報が含まれます。

4.8 コレクション・イベント

ルールベースのアプリケーションのクラスには、個別のイベントではなく、コレクション・イベントに対して条件式のサポートが必要です。このようなアプリケーションでのルール条件は、有限でありながら多数となる可能性のある同じタイプのプリミティブ・イベントの集計値を計算し、集計結果で述語を指定します。そのために、特定タイプのプリミティブ・イベントは、イベント属性に基づいてグループ化され、SUMAVGMINMAXおよびCOUNTなどの他のイベントの集計演算子は、述語への適用に使用されます。たとえば、ルール条件が特定の口座から送金された合計金額を検査する場合があります。各銀行取引が個別のイベントである場合、これらのイベントは口座識別子に基づいてグループ化され、述語は合計金額(SUM(amount) > 10000)で指定されます。

ルール・マネージャは、コレクション・イベントを使用してルール条件内の集計演算子をサポートします。コレクション・イベントは、特定のプロパティを共有する固有のタイプの1つ以上のプリミティブ・イベントで構成されます。たとえば、コレクション・イベントを使用して、共通の口座識別子を共有し、引出しタイプである一連のBankTransactionイベントを表すことができます。このようなコレクション・イベントを含むルール条件は、次のように表されます。

<condition>
  <collection name="bank" groupby = "subjectId"
                          having  = "SUM(amount) > 10000">
      tranType = 'Withdrawal'
  </collection>
</condition>

コレクション要素のname属性は、コレクションが考慮されたプリミティブ・イベントのタイプ、およびgroupby属性に指定された値を制限します。groupby属性は、コレクション内のプリミティブ・イベントすべてに共通のプロパティを定義する他のイベント属性の述語に結合します。having属性は、コレクション内のイベントを評価する必要のある集計述語を指定します。コレクション要素を含むルール条件は、WHERE句、GROUP BY句およびHAVING句を使用して標準SQL問合せを操作するように表示できます。たとえば、前述のルール条件は、概念的なTransactions表で次のSQL問合せにマップできます。

SELECT DISTINCT subjectId FROM Transaction
WHERE tranType = 'Withdrawal'
GROUP BY subjectId
HAVING SUM(amount) > 10000

前述のルール条件では、各銀行取引のプリミティブ・イベントは、Withdrawal取引きタイプで検査され、一致するプリミティブ・イベントは、subjectId属性に基づいてグループ化され、明確な各subjectIdに対して1つのコレクション・イベントが実行されます。特定のコレクションのプリミティブ・イベントは、ウィンドウのセマンティックスの移動を使用してさらに制限される場合があります。ルール・マネージャは、コレクション・イベントを使用したウィンドウの移動の2タイプをサポートします。

いくつかの制限を使用して、ルール条件は、コレクション・イベントと、他のコレクション・イベント、またはコレクションを含むコンポジット・イベント形式のプリミティブ・イベントと結合できます(第5.6項を参照)。コンポジット・イベントに関する基本ルール条件構文は、1つのコレクションをコンポジット・イベント内の他のイベントに関連付けるのに使用できます。

セット・セマンティックスを含むルール条件の場合とは異なり(第5.4項を参照)、コレクションを介するルール条件に参加するプリミティブ・イベントの数は、イベント構造定義により制限されません。コンポジット・イベント内のプリミティブ・イベント・タイプのサブセットは、コレクションに対して構成され、対応するルール・クラス内のルール条件は、様々なウィンドウ仕様を使用して、プリミティブ・イベントの様々な数を考慮できます。BankTransaction、TransportationおよびFieldReportイベントに関連する、セキュリティ・アラートを生成する警察管理アプリケーションを考えてみます(第10.1項を参照)。このアプリケーションでは、BankTransactionイベントで集計述語を指定する必要がある場合、警察管理コンポジット・イベント構造で作成されたルール・クラスは、次のように構成される必要があります。

BEGIN
   DBMS_RLMGR.CREATE_RULE_CLASS(
      rule_class => 'LawEnforcementRC',
      event_struct => 'LawEnforcement',
      action_cbk => 'LawEnforcementCBK',
      actprf_spec => 'actionType VARCHAR2(40), actionParam VARCHAR2(100)',
      rslt_viewnm => 'MatchedCriteria',
      rlcls_prop =>
         '<composite
              equal="bank.subjectId, transport.subjectId, fldrpt.subjectId"
              ordering="rlm$rule.rlm$ruleid, bank.subjectId, transport.subjectId">
            <collection type = "BankTransaction"
                        groupby = "subjectId, tranType"/>
          </composite>');
END;
/

コレクションの各プリミティブ・イベント・タイプに対して、ルール・クラス・プロパティは、タイプの名前の付いた<collection>要素およびgroupby仕様を含む必要があります。groupby仕様は、このプリミティブ・イベントが予想するすべての可能性のあるgroupby属性をリストします。前述のコマンドで作成されたルール・クラスは、銀行取引にsubjectIdまたはtransType属性、またはこの2つの属性の結合でグループ化するルール条件を含むことができます。イベントのグループ化も、イベント構造の属性を含む式に基づくことに注意してください。たとえば、いくつかのルールが、イベントが発生するリージョンに基づいてイベントをグループ化する必要がある場合、広範囲なリージョンに国をマップするというユーザー定義の関数は、groupby仕様に含まれます。(例: groupby = "subjectId, tranType, regionOf(fundFrom)")。

ルール・クラス・プロパティ内のオブジェクト要素のかわりにコレクション要素を使用することにより、コレクションに対して特定のイベント・タイプが有効になります。collection要素には、consumptionおよびdurationなどのobject要素を使用できる属性も含まれます。コレクション・イベントに構成されたルール・クラスは、追加のデータベース・オブジェクトを内部的に使用して、コレクションに関連する増分状態の情報を保持します。このようなルール・クラスは、コレクション・イベントを含むルール条件と同様、個別のイベントを含むルール条件を格納および管理できます。ルール条件は、コンポジット・イベントに対するルール条件構文内のcollection要素を使用して、個別のプリミティブ・イベント・インスタンスの外に、コレクション・イベントを作成できます。コレクション・イベントの構文は、一連のプリミティブ・イベントをコレクション・イベントの形式にグループ化し、これらのイベントの集計述語を検査できます。プリミティブ・イベントがグループされる属性は、指定されたイベント・タイプに対するルール・クラス・プロパティにリストされた属性のサブセットです。ルール・クラス内の各ルールは、コレクション・イベントに対して異なるgroupby仕様を使用する場合があります。コレクション・イベントに関する集計述語は、SQL演算子を使用して指定されます。イベント数を計算するにはCOUNT、属性の平均値を計算するにはAVG、特定の属性の合計を計算するにはSUM、属性の最小値を計算するにはMIN、最高値を計算するにはMAXを使用します。SQL-HAVING句構文で表現される集計述語式は、collection要素のhaving属性に割り当てられます。

<condition>
       <collection name="bank" groupby = "subjectId"
                               having  = "SUM(amount) > 10000 or COUNT(*) > 10"
                               windowlen ="1">
          tranType = 'Withdrawal'
       </collection>
    </condition>

イベントに一致する複数のルール間で共有されるプリミティブ・イベントとは異なり、コレクション・イベントは、一致するルールに固有です。プリミティブ・イベントがグループ化される属性の一意の結合数に基づいて、1つのルール条件には、関連付けられたコレクション・イベントが複数あります。これらのコレクション・イベントは、コレクションに追加されるプリミティブ・イベントとして保持されるか、またはウィンドウ仕様により削除されます。各コレクション・イベントおよび対応する集計値は増分的に計算され、結果は永続的にデータベースに格納されます。集計値は、新規イベントの到達時のみ計算され、経過時間によりウィンドウ外に削除されたプリミティブ・イベントは計算を強制しないことに注意してください。

ルール条件がTRUEと評価したコレクションを含む場合、対応するアクションは、アクション・コールバック・メカニズム、または第2.4項および第2.6項で説明された結果ビューを使用して実行されます。アクション実行に対して、コレクション・イベントのインスタンスは、コールバック・プロシージャに渡されます。コレクション・イベントは、内包するプリミティブ・イベントと同一タイプです。ただし、コレクション・イベントにおいては、グループ化されたイベントの属性は初期化され(コレクションのGROUP BY句からのネイティブの属性)、残りはNULLに設定されます。たとえば、前述のルール条件に一致するコレクション・イベントは、初期化されたsubjectId(コレクションのすべてのプリミティブ・イベントに共通)のみを持つBankTransactionタイプのインスタンスです。コレクション・イベントで計算される集計値にアクセスするためには、アクション・コールバック・プロシージャ(および結果ビュー)が、コレクション・イベント識別子(ROWIDタイプ)に渡すための追加引数で作成されます。このイベント識別子は、DBMS_RLMGR.GET_AGGREGATE_VALUEコールに渡され、SUM(amount)のような集計関数に対して計算済の値を取得します。

CREATE OR REPLACE PROCEDURE LawEnforcementCBK (
    bank        BankTransaction,
    bank_evtid  ROWID,   -- event identifier for the "bank" collection events --
    transport   Transportation,
    fldrpt      FieldReport,
    rlm$rule    LawEnforcementRC%ROWTYPE) IS
BEGIN
  ..
  dbms_rlmgr.get_aggregate_value(rule_class  => 'LawEnforcementRC',
                                 event_ident =>  bank_evtid,
                                 aggr_func   =>  'SUM(amount)');
END;

集計関数の署名がコレクションに対して計算された集計関数の1つに一致する場合のみ、DBMS_RLMGR.GET_AGGREGATE_VALUEコールはNULL以外の値を戻すことに注意してください。コレクション・イベントは期間を超えて作成されるので、このようなイベントに関連付けられる正確なタイムスタンプはありません。NULL値は、rlm$CrtTime(タイムスタンプ)属性に格納され、この属性(たとえばSEQUENCE)を含む操作は無効です。同様の理由で、経過時間として指定された継続時間ポリシーは、コレクション・イベントに何の影響もありません。ルール・クラスがSESSIONまたはTRANSACTIONイベントの継続時間ポリシーで構成されている場合、コレクション・イベントも、それぞれSESSIONまたはTRANSACTIONの終了時に終了することに注意してください。コレクション・イベントはルールに対して非公開であるため、このようなイベントの使用(EXCLUSIVEまたはRULE使用率ポリシーを使用した使用)によりコレクションはリセットされ(コレクションは空になり)、実行されたルールの数に影響しません。複数のルールがプリミティブ・イベントを使用してTRUEと評価された場合、1つまたは複数の一致ルールによるイベントの使用は、自動的に他のルールに対するアクション実行を停止します。

コレクション構成されたルール条件が、個別のプリミティブ・イベント(コレクションなし)を使用したルール条件と共存する場合、EXCLUSIVEまたはRULE使用率ポリシーによるプリミティブ・イベントの使用率は、既存のコレクション・イベントからプリミティブ・イベントを削除しません。同様に、プリミティブ・イベントが経過時間により継続時間ポリシーを終了する場合、このイベントに依存するコレクション・イベントは影響を受けません。

ルール・クラスは、コレクションである複数のプリミティブ・イベント・タイプに対して構成できます。ただし、このリリースでは、リレーショナル表とは別名の表としてモデル化されたプリミティブ・イベントは、コレクションとして構成できません。また、ルール・クラスに使用されるコンポジット・イベント構成は、同タイプの複数のプリミティブ・イベントを所有できない場合があります。

4.9 パフォーマンスのチューニング

最適なパフォーマンスのためにルール・クラスをチューニングする方法は、3つに分類されます。

式フィルタ索引のチューニング

単純イベントまたはコンポジット・イベントに対して作成されるルール・クラスは、1つ以上の式フィルタ索引を作成し、受け取ったイベントに対してルール条件を処理します。ルール・クラス作成時に作成されるデフォルトの索引では、イベント構造ですべてのスカラー属性を持つ述語がルール条件にほぼ等しいと仮定されます。この仮定は、ほとんどのアプリケーションでは当てはまりません。ルール・アプリケーションのパフォーマンスは、特定のワークロードに索引をチューニングすることで向上します。これは、専門知識を使用するか、ルール・アプリケーションからの典型的なワークロードを分析することで可能です。

ルール・クラスに対して作成される式フィルタ索引のチューニングの専門知識を使用する場合、プリミティブ・イベント構造(または単純イベント構造)を式フィルタの属性セットとして扱います(第11.2項を参照)。

属性セットと関連付けられたデフォルトの索引パラメータは、USER_EXPFIL_DEF_INDEX_PARAMSビューを問い合せることで取得でき、DBMS_EXPFIL.DEFAULT_INDEX_PARAMETERSコールを使用して変更できます(第12.6項を参照)。これらのデフォルトの索引パラメータは、対応する式フィルタ索引が作成されるときに使用されます。ルール・クラスに対して作成されるデフォルトの索引は、DBMS_RLMGR.DROP_EXPFIL_INDEXESコールを使用して削除でき、DBMS_RLMGR.CREATE_EXPFIL_INDEXESコールを使用してユーザーが割り当てた索引パラメータを使用して再作成できます。

ワークロードを使用して、ルール・クラスに対して作成された式フィルタ索引をチューニングする際、ルール条件内の最も一般的な述語構成は、ルール・クラスですでに定義されている典型的なルールセットで統計を収集して識別できます。式フィルタ索引は、DBMS_RLMGR.CREATE_EXPFIL_INDEXESコールのcoll_stats引数をYESに設定することで、これらの統計から作成されます。

ルール・クラスに使用されるイベント構造に、1つ以上のXMLType属性が含まれる場合、デフォルトの式フィルタ索引および統計から作成された索引は、これらの属性でXpath述語に最適ではありません。したがって、Xpath索引パラメータは、第13.2.4項にあるように、明示的にDBMS_RLMGR.DEFAULT_XPINDEX_PARAMETERSコールを使用してイベント構造に割り当てられる必要があります。

ルール・クラス・インタフェース・パッケージの作成

ルール・アプリケーションの実行時のパフォーマンスを向上するには、ルール・クラスに特有のルール・クラス・インタフェース・パッケージを作成します。これにより、一般的なDBMS_RLMGRパッケージを使用する場合に関連するオーバーヘッドを回避できます。イベントへのルールの処理、イベントの使用、セッションのリセットなど、実行時操作に使用されるDBMS_RLMGRプロシージャは、引数の1つとして渡されるルール・クラスの名前を使用して、ルール・クラスに対応する操作にマップします。この手順は、ルール・クラスでの直接操作に使用されるルール・クラス・インタフェース・パッケージの作成により回避できます。ルール・クラス・インタフェース・パッケージは、ルール・クラス内のルールが選択的である場合、または、受け取ったイベントと一致しない場合に最も効果的です。パッケージはDBMS_RLMGR.CREATE_INTERFACEコールを使用して作成され、ルール・クラスでのすべての実行時操作を実行する一連のプロシージャが含まれます。詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』のDBMS_RLMGR.CREATE_INTERFACEコールに関する項を参照してください。

4.10 ルール条件でのデータベースの状態

ルール条件の述語には、データベース表のデータおよびデータベースの状態情報を参照するユーザー定義関数を使用できます。単純イベント(プリミティブ・イベント)に指定される条件の場合は、PROCESS_RULESまたはADD_EVENTコールによって、イベントがルール・クラスに追加された時点の状態情報を使用して、対応する述語が評価されます。これは、コンポジット・イベント内の個々のプリミティブ・イベントに指定されている条件にも適用されます。したがって、複数のプリミティブ・イベントがコンポジットイベントの取得に使用される場合は、各イベントの発生に応じて、個々のプリミティブ・イベントに関連付けられている述語が異なる時点で評価されます。コンポジット条件の結合属性に指定される述語のみが、コンポジット・イベントの作成時に評価されます。したがって、この状況は、データベースの状態またはルール条件のスキーマ・オブジェクト参照を使用する場合に考慮する必要があります。

4.11 開発環境のためのイベントのリセット

ルール・マネージャを使用してルール・アプリケーションを開発する場合、ルール・クラスで定義されたルールは、仮想イベントを使用して検査できます。これらのイベントが部分的にルール・クラス内のルールと一致するために、データベースに格納された増分状態の一因となることがあります。そのため、本番環境にアプリケーションをデプロイする前に、部分的な状態情報をパージして、予想外のルール・アクションを引き起こさないようにする必要があります。DBMS_RLMGR.PURGE_EVENTSプロシージャ・コールを使用して、アプリケーションを本番環境にデプロイする前に、データベースから状態情報およびイベントをパージします。