ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Complex Event Processing EPL言語リファレンス
11gリリース1 (11.1.1.6.2)
B55579-04
  目次へ移動
目次
索引へ移動
索引

前
戻る
 
次
次へ
 

2 EPLリファレンス: 句

この章では、イベント処理言語(EPL)の句のリファレンスについて説明します。EPLは非推奨になったことに注意してください。新たな開発ではOracle Continuous Query Language (Oracle CEP)を使用する必要があります。

この項では、以下のトピックについて説明します。

2.1 EPL文で使用可能な句の概要

イベント処理言語(EPL)の上位レベルBNFは以下のとおりです。

  [ INSERT INTO insert_into_def ]
    SELECT select_list
  { FROM stream_source_list /  MATCHING pattern_expression }
  [ WHERE search_conditions ]
  [ GROUP BY grouping_expression_list ]
  [ HAVING grouping_search_conditions ]
  [ ORDER BY order_by_expression_list ]
  [ OUTPUT output_specification ]

リテラル・キーワードでは大文字と小文字が区別されません。以降の節では、それぞれの句について詳しく示します。組込みの演算子と関数の詳細は、第3章「EPLリファレンス: 演算子」および第4章「EPLリファレンス: 関数」を参照してください。

2.2 SELECT

すべてのEPL文にはSELECT句が必要です。SELECT句を使用して、ワイルドカード*ですべてのプロパティを選択するか、イベント・プロパティおよび式のリストを指定できます。SELECT句は、文でパブリッシュされる、または文から抽出される結果イベントのイベント・タイプ(イベント・プロパティの名前と型)を定義します。

SELECT句では、文にアタッチされている更新リスナーにイベントがポストされるしくみを制御する省略可能なISTREAMおよびRSTREAMキーワードも提供されます。

SELECT句の構文の概要を次に示します。

  SELECT [RSTREAM | ISTREAM] ( expression_list | * )

次の例では、イベント・データのソースを定義するFROM句を使用します。FROM句については、2.3項「FROM」で説明しています。

2.2.1 特定のイベント・プロパティの選択

返される特定のイベント・プロパティを選択するには:

  SELECT event_property [, event_property] [, ...] 
  FROM stream_def

次の文では、直前の100の株価表示イベントで、量のカウントと標準偏差が選択されます。

  SELECT COUNT, STDDEV(volume) 
  FROM StockTick RETAIN 100 EVENTS

2.2.2 式の使用

SELECT句には1つまたは複数の式を含めることができます。

  SELECT expression [, expression] [, ...] 
  FROM stream_def

次の文では、株価表示イベントの直前30秒間の時間バッチで価格と量の乗算値が選択されます。

  SELECT volume * price 
  FROM StockTick RETAIN BATCH OF 30 SECONDS

2.2.3 イベント・プロパティのエイリアス

以下の構文で、イベント・プロパティおよび式のエイリアスを指定できます。

  SELECT [event_property | expression] AS identifier [,…]

次の文では、価格と量の乗算値が選択され、イベント・プロパティの名前volPriceが指定されます。

  SELECT volume * price AS volPrice 
  FROM StockTick RETAIN 100 EVENTS

2.2.4 すべてのイベント・プロパティの選択

ストリーム内のすべてのイベント・プロパティを選択する構文は以下のとおりです。

  SELECT * 
  FROM stream_def

次の文では、直前の30秒間のすべてのStockTickイベント・プロパティが選択されます。

  SELECT * 
  FROM StockTick RETAIN 30 SECONDS

結合文では、SELECT *構文を使用すると、結合されたストリーム自身を表すイベントが含まれるイベント・プロパティが選択されます。

SELECT句ではワイルドカード*と式を組み合せることもできます。この組み合わせにより、すべてのイベント・プロパティのほか、SELECT句の一部として含まれる追加の式で指定された計算値が選択されます。この例では、株価表示イベントのすべてのプロパティのほか、pricevolumeという名前が指定された、価格と量により計算された乗算値が選択されます。

  SELECT *, price * volume AS pricevolume 
  FROM StockTick RETAIN ALL

2.2.5 STREAMおよびRSTREAMキーワードによる新しいイベントと古いイベントの選択

SELECT句の省略可能なISTREAMおよびRSTREAMキーワードは、文の更新リスナーにポストされるイベント・ストリームを定義します。いずれのキーワードも指定しない場合、エンジンでは挿入ストリームおよび削除ストリームの両方のイベントが文のリスナーにポストされます。挿入ストリームはそれぞれの枠、ストリーム、または集約に入れられたイベントで構成され、削除ストリームはそれぞれの枠または変更された集約結果を離れたイベントで構成されます。挿入イベントおよび削除イベントの詳細は、1.2.7項「イベント・シンク」で説明しています。

STREAMキーワードを指定することにより、更新リスナーに挿入ストリーム・イベントのみをポストするようエンジンに通知できます。エンジンでは削除ストリーム・イベントがポストされなくなります。RSTREAMキーワードを指定することにより、更新リスナーに削除ストリーム・イベントのみをポストするようエンジンに通知できます。エンジンでは挿入ストリーム・イベントがポストされなくなります。

次の文では、30秒の時間枠を離れるイベントのみが選択されます。

  SELECT RSTREAM * 
  FROM StockTick RETAIN 30 SECONDS

SELECT句のISTREAMおよびRSTREAMキーワードは、2.11項「INSERT INTO」で説明しているとおり、INSERT INTO句で使用可能な同じ名前のキーワードに対応します。SELECT句のキーワードが文に対する更新リスナーにポストされるイベント・ストリームを制御するのに対し、INSERT INTO句の同名のキーワードはエンジンによって他の文で使用できるようになるイベント・ストリームを指定します。

2.3 FROM

すべてのEPL文にはFROMまたはMATCHING句のいずれかが必要です。FROM句は、イベント・データのソースとして1つまたは複数のイベント・ストリームを指定します。MATCHING句については、2.5項「MATCHING」で説明しています。

  FROM stream_expression [ inner_join | outer_join ] 

inner_joinではストリーム式のカンマ区切りのリストとして指定します。

  (, stream_expression )*

outer_joinの定義は次のとおりです。

((LEFT|RIGHT|FULL) OUTER JOIN stream_expression ON prop_name = prop_name)*

内部結合の詳細は、2.3.1項「内部結合」、外部結合の詳細は、2.3.2項「外部結合」で説明しています。

stream_expressionはストリーム・データのソースとして使用されるイベント・タイプ名を定義し、より複雑なシナリオでは、ネストされたEPL文としての副問合せ式、またはJDBCデータにアクセスするパラメータ化されたSQL問合せを定義します。これらのすべてのケースで、stream_expressionにはオプションとして他の式のあいまいなプロパティ名参照を修飾する識別子としてのエイリアスと、残りの問合せで処理されるストリーム・データの枠を定義するRETAIN句を含むことができます。

  (stream_name | subquery_expr | param_sql_query) [[AS] alias]] [RETAIN retain_expr]
  subquery_expr: ( epl_statement )
  param_sql_query: database_name ('parameterized_sql_query')

subquery_exprは副問合せまたはネストされたEPL文をカッコで囲んで定義します。副問合せは外部EPL文で処理されるイベント・ストリーム・データを事前にフィルタ処理するために使用されます。たとえば、次の問合せでは、外部EPL問合せで処理されるデータはReutersフィードからのStockTickイベントのみに制限されます。

  SELECT stockSymbol, AVG(price)
  FROM (SELECT * FROM StockTick WHERE feedName = 'Reuters' ) 
  RETAIN 1 MINUTE PARTITION BY stockSymbol
  GROUP BY stockSymbol

副問合せは任意にネストできますが、INSERT INTOまたはOUTPUT句を含むことはできません。上位レベルのEPL文とは異なり、副問合せ内ではRETAIN句を省略できます。副問合せ式の詳細は、2.3.3項「副問合せ式」で説明しています。

param_sql_queryはパラメータ化されたSQL問合せをカッコで囲まれた引用符で指定し、これによりJDBCを通じてアクセス可能な参照および履歴データを取得できます。database_nameは問合せが実行されるデータベースの名前を識別します。データベース接続の確立、接続の作成および切断の制御、および問合せ結果のキャッシュ・ポリシーの設定のための構成情報はこのデータベース名に関連付けられています。パラメータ化されたSQL問合せの詳細は、2.3.4項「パラメータ化されたSQL問合せ」で説明しています。

RETAIN句は、問合せ処理の前にFROM句にリストされたストリームから読み取られるイベント・データの量を定義します。保持の異なるポリシーが必要な場合は、ストリームごとに独自のRETAIN句を指定できます。それ以外の場合、RETAIN句は、すべてのストリームに適用されるようにFROM句の末尾に追加します。本質的に、RETAIN句はFROM句内で自身の前にあるすべてのストリームに適用されます。

たとえば、次のEPL文では、StockTickイベントは5件保持され、Newsイベントは3件保持されます。

  SELECT t.stockSymbol, t.price, n.summary
  FROM StockTick t RETAIN 5 EVENTS, News n RETAIN 3 EVENTS
  WHERE t.stockSymbol = n.stockSymbol

ただし、次の文では、StockTickイベントは4件、Newsイベントは4件保持されます。

  SELECT t.stockSymbol, t.price, n.summary
  FROM StockTick t, News n RETAIN 4 EVENTS
  WHERE t.stockSymbol = n.stockSymbol

副問合せ式の例外を除いて、すべてのストリーム・ソースにはRETAIN句による制約が必要です。このため、上位レベルのEPL文としてFROM句には少なくとも末尾に1つのRETAIN句が含まれている必要があります。パラメータ化されたSQL問合せからの外部データはRETAIN句の影響を受けません。RETAIN句の詳細は、2.4項「RETAIN」で説明しています。

2.3.1 内部結合

FROM句には2つ以上のイベント・ストリームを含めることができるため、両方のストリームにより結果イベントが決定されます。2つ以上のストリームのイベントを関連付けるためにEPLが使用する結合条件はWHERE句にリストされます。たとえば、結合されたストリーム・ソースのいずれにもイベント・データが発生しなかった場合など、条件が満たされない場合、出力は生成されません。

いずれかのイベント・ストリームにイベントが到着した各時点で、2つのイベント・ストリームが結合され、WHERE句に応じて出力イベントが生成されます。

この例では、2つのイベント・ストリームが結合されます。最初のイベント・ストリームは、直前の30分間が保持される不正警告イベントから成ります。2つ目のストリームは、直前の30秒が考慮される引出しイベントです。これらのストリームは口座番号で結合されます。

  SELECT fraud.accountNumber AS accntNum, 
    fraud.warning AS warn, withdraw.amount AS amount,
    MAX(fraud.timestamp, withdraw.timestamp) AS timestamp, 
    'withdrawlFraud' AS desc
  FROM FraudWarningEvent AS fraud RETAIN 30 MIN,
       WithdrawalEvent AS withdraw RETAIN 30 SEC
  WHERE fraud.accountNumber = withdraw.accountNumber

2.3.2 外部結合

EPLでは、個数制限のないイベント・ストリーム間の左外部結合、右外部結合、および完全外部結合がサポートされています。ストリーム・ソースにイベント・データが存在しない場合でも、LEFTRIGHT、またはFULL修飾子に応じて出力が生成されます。

外部結合が左外部結合の場合、句の左側にあるストリームの各イベントについて出力イベントが発生します。たとえば、下の左外部結合では、イベント・ストリームOrderList内のイベントにイベントが一致しない場合であっても、ストリームRfidEvent内の各イベントの出力が取得されます。

  SELECT * 
  FROM RfidEvent AS rfid 
                 LEFT OUTER JOIN
             OrderList AS orderlist 
                 ON rfid.itemId = orderList.itemId
  RETAIN 30 SECONDS

同様に、結合が右外部結合の場合、句の右側にあるストリームの各イベントについて出力イベントが発生します。たとえば、下の右外部結合では、イベント・ストリームRfidEvent内のイベントにイベントが一致しない場合であっても、ストリームOrderList内の各イベントの出力が取得されます。

  SELECT * 
  FROM RfidEvent AS rfid 
                 RIGHT OUTER JOIN
             OrderList AS orderlist 
                 ON rfid.itemId = orderList.itemId
  RETAIN 30 SECONDS

すべてのタイプの外部結合では、結合条件が満たされない場合、到着したイベントのイベント・プロパティで選択リストが計算され、他のすべてのイベント・プロパティはnullと見なされます。

  SELECT * 
  FROM RfidEvent AS rfid 
                 FULL OUTER JOIN
             OrderList AS orderlist 
                 ON rfid.itemId = orderList.itemId
  RETAIN 30 SECONDS

外部結合の最後のタイプは完全外部結合です。完全外部結合では、いずれかのイベント・ストリームにイベントが到着した各時点で、1つまたは複数の出力イベントが生成されます。下の例では、RfidEventまたはOrderListイベントが到着すると、1つまたは複数の出力イベントが生成されます。

2.3.3 副問合せ式

副問合せ式は、FROM句のカッコ内にネストされたEPL文です。副問合せにはINSERT INTO句またはOUTPUT句を含めることはできません。また、上位レベルのEPL文とは異なり、RETAIN句は省略可能です。

副問合せ式は、式を包含しているEPL文の前に実行されるため、外部の文で処理されるイベント・データを事前にフィルタ処理する際に便利です。たとえば、次の問合せでは、直前の100のStockTickイベントで特定の銘柄の変化する平均値が計算されます。

  SELECT AVG(price)
  FROM (SELECT * FROM StockTick WHERE stockSymbol = 'ACME' ) 
  RETAIN 100 EVENTS

WHERE句が外部問合せ内に置かれた場合は、他の銘柄記号のStockTickイベントが枠に入れられ、平均価格の計算に使用されるイベント数が軽減されます。

また、副問合せを使用する目的には、a)内部のイベント・ソース構造を外部EPL文で必要とされる構造に変換する場合、またはb)複数のイベント・ストリームを結合して単一のイベント・ストリームを形成する場合があります。これにより、INSERT INTO句を使用して複数のEPL文を接続する代わりに、単一のEPL文を使用できます。たとえば、次の問合せでは、EventAおよびEventBからのトランザクション・データが結合され、結合されたデータが外部問合せで使用されます。

  SELECT custId, SUM(latency)
  FROM (SELECT A.customerId AS custId, A.timestamp -B.timestamp AS latency
                FROM EventA A, EventB B
                WHERE A.txnId = B.txnId)
  RETAIN 30 MIN
  GROUP BY custId

副問合せ自身に副問合せを含めることができるため、任意のレベルのネストが許可されます。

2.3.4 パラメータ化されたSQL問合せ

パラメータ化されたSQL問合せでは、EPL文に含まれるSQLを介して、JDBCを通じてアクセス可能な参照および履歴データに対する問合せを実行できます。EPLからこれらのデータ・ソースにアクセスできるようにするには、いくつかの構成が必要です。

現在適用される制限には、以下のものがあります。

  • 1つのイベント・ストリームのみを1つのSQL問合せに結合できます。2つ以上のイベント・ストリームとSQL問合せの結合はサポートされていません。

  • SQL問合せのストリームではRETAIN句に指定された制限が無視されます(つまり、SQL問合せに時間ベースまたはイベント・ベースの枠を作成することはできません)。ただし、INSERT INTO構文を使用して、結合の結果を他の文に対して使用可能にできます。

  • データベース・ソフトウェアではコンパイル時に文のメタデータを提供するJDBCのプリコンパイルされた文をサポートしている必要があります。ほとんどの主なデータベースではこの機能が提供されます。

問合せ文字列は一重または二重引用符を付けてカッコで囲みます。問合せには1つまたは複数の置換パラメータを含めることができます。問合せ文字列は変更されずにデータベース・ソフトウェアに渡されるため、ストアド・プロシージャ・コールを含む、データベースで認識される任意のSQL問合せ構文を作成できます。

SQL問合せ文字列の置換パラメータは${event_property_name}という形式を取ります。エンジンでは文の実行時にevent_property_nameが結合イベント・ストリーム内のイベントで提供される実際のイベント・プロパティ値に解決されます。

エンジンではSQL問合せの出力列の型がデータベース・ソフトウェアで返される文の結果セットのメタデータによって決定されます。実際の問合せ結果はjava.sql.ResultSetgetObjectを通じて取得されます。

次のEPL文の例では、CustomerCallEventイベントで構成されるイベント・ストリームが、データベースMyCustomerDBおよび表Customerに対するSQL問合せの結果と結合されます。

  SELECT custId, cust_name 
  FROM CustomerCallEvent,
  MyCustomerDB (' SELECT cust_name FROM Customer WHERE cust_id = ${custId} ')
  RETAIN 10 MINUTES

前述の例ではCustomerCallEventcustIdというイベント・プロパティが提供されていると想定します。SQL問合せではCustomer表から顧客名が選択されます。SQLのWHERE句ではCustomer表の列cust_idが各CustomerCallEventイベントのcustIdの値と照合されます。エンジンでは新しいCustomerCallEventが検出されるたびにSQL問合せが実行されます。

指定の顧客IDの列がSQL問合せで返されなかった場合、エンジンは出力イベントを生成しません。列が返された場合、エンジンではSQL問合せで返される列ごとに1つの出力イベントが生成されます。次の節で説明しているように、外部結合を使用して、SQL問合せで列が返されない場合でもエンジンで出力イベントが生成されるかどうかを制御できます。

次の例では、イベント・ストリームCustomerCallEventに30秒の時間枠が追加されます。また、選択されたプロパティの名前がcustomerNameおよびcustomerIdに変更されます。これは、EQL問合せのSELECT句でSQL問合せによる列名の指定がどのように使用されるかを示しています。この例ではASキーワードを介して明示的なストリーム名を使用します。

  SELECT customerId, customerName 
  FROM CustomerCallEvent AS cce RETAIN 30 SECONDS,
    MyCustomerDB 
    ("SELECT cust_id AS customerId, cust_name AS customerName 
      FROM Customer WHERE cust_id = ${cce.custId}") AS cq 

時間枠などの任意の枠では、イベントが枠に入ると挿入イベントが生成され、イベントが枠を離れると削除イベントが生成されます。エンジンでは挿入ストリームおよび削除ストリームの両方のケースで、各CustomerCallEventに対して指定のSQL問合せが実行されます。パフォーマンスの最適化として、SELECT句のISTREAMまたはRSTREAMキーワードを使用して、挿入イベントまたは削除イベントのみを結合するようエンジンに通知し、SQL問合せの実行数を軽減できます。

パラメータ化されたSQL問合せを外部結合で使用することもできます。SQL問合せで行が返されるかどうかにかかわらず各イベントの出力イベントが必要な場合は、次の文のように、左外部結合を使用します。SQL問合せで行が返されない場合は、結合の結果によって選択されたプロパティにnull値が挿入されます。

  SELECT custId, custName 
  FROM CustomerCallEvent AS cce
    LEFT OUTER JOIN
    MyCustomerDB 
      ("SELECT cust_id, cust_name AS custName
        FROM Customer WHERE cust_id = ${cce.custId}") AS cq
    ON cce.custId = cq.cust_id
  RETAIN 10 MINUTES

前述の文では、SQL問合せで行が返されない場合でも、SQL問合せで選択されたすべての列を含む出力イベントが各CustomerCallEventに対して常に少なくとも1つ生成されます。外部結合ではON式が必要なことに注意してください。ONはSQL問合せで返された行に対する追加のフィルタとして動作します。

2.4 RETAIN

FROM句には少なくとも1つのRETAIN句が必要です。RETAIN句はFROM句で自身の前にリストされているすべてのストリーム・ソースに適用されます。概念的に、問合せの実行対象となる各ストリーム・ソースのイベント・データの枠が定義されます。RETAIN句の構文は以下のとおりです。

  RETAIN
  ( ALL [EVENTS] ) |
  ( [BATCH OF] 
    ( integer (EVENT|EVENTS) ) | ( time_interval (BASED ON prop_name)* )
    ( WITH [n] (LARGEST | SMALLEST | UNIQUE) prop_name )* 
    ( PARTITION BY prop_name )* )

RETAIN句の各側面について、詳細を次に示します。

2.4.1 すべてのイベントの保持

ストリーム・ソースのすべてのイベントを保持するには、RETAIN句でALL [EVENTS]を指定します。

  SELECT AVG(price) 
  FROM StockTick RETAIN ALL EVENTS

この場合、発生するすべてのStockTickイベントに基づいて平均価格が計算されます。ただし、数量が大きいシナリオでの計算時に各イベント・オブジェクトの全体または部分を保持する必要があるとメモリーが不足する可能性があるため、このオプションは慎重に使用する必要があります。この例としては重み設定された平均値の計算などがあります。

2.4.2 枠のサイズの指定

問合せの実行時に保持されるイベント・データの量を決定するには2つの方法があります。最初のオプションでは、保持されるイベントの最大数を指定します。たとえば、次の問合せでは、平均価格を計算するStockTickイベントが最大100件保持されます。

  SELECT AVG(price) 
  FROM StockTick RETAIN 100 EVENTS

新しいStockTickイベントが到着するたびに、最大100件のイベントを使用して平均価格が計算されます。

2つ目のオプションでは、イベント・データが収集される時間間隔を指定します。たとえば、次の問合せでは1分間相当のStockTickイベントが保持され、このデータに対して平均価格が計算されます。

  SELECT AVG(price) 
  FROM StockTick RETAIN 1 MINUTE

この場合、新しいStockTickイベントが到着するたびに平均価格が計算されます。ただし、1分以上前に到着したイベントは枠から削除され、枠内の残りのイベントに基づいて平均価格が再計算されます。

2.4.3 バッチ枠とスライド枠の指定

デフォルトでは、イベント・データが保持される枠はスライド枠です。スライド枠では、枠が一杯になると新しいイベントが枠に入るときに古いイベントが削除されます。スライド枠では、新しいイベントが枠に入れられた場合または古いイベントが枠を離れた場合、あるいはその両方の場合に、問合せが再実行されます。もう1つの方法としては、問合せ実行の前にイベント・データのバッチを指定します。枠が一杯にならないと問合せは実行されません。それ以降は、枠がまた一杯になるまで新しいイベント・データが再び収集されてから、問合せが再実行されます。

たとえば、次の問合せでは100件のイベントがバッチで収集された後、平均価格を計算する問合せが実行されます。

  SELECT AVG(price) 
  FROM StockTick RETAIN BATCH OF 100 EVENTS

実行後は、次の100件のイベントがバッチ収集されてから問合せが再実行されます。

スライド枠とバッチ枠の詳細は、1.3項「処理モデル」を参照してください。

2.4.4 時間間隔の指定

RETAIN句の時間間隔は、日数、時間、分、秒、またはミリ秒単位で指定します。

  time_interval: [day-part][hour-part][minute-part][seconds-part][milliseconds-part]
  day-part: number ("days" | "day")
  hour-part: number ("hours" | "hour" | "hr")
  minute-part: number ("minutes" | "minute" | "min")
  seconds-part: number ("seconds" | "second" | "sec")
  milliseconds-part: number ("milliseconds" | "millisecond" | "msec" | "ms")

時間間隔のいくつかの例を示します。

  10 seconds
  10 minutes 30 seconds
  20 sec 100 msec
  0.5 minutes
  1 day 2 hours 20 minutes 15 seconds 110 milliseconds

2.4.4.1 BASED ON句

デフォルトでは、時間間隔の経過は内部システム・クロックに基づいています。ただし、場合によっては、イベント・プロパティのタイム・スタンプの値に基づいた時間が必要になることもあります。この場合は、BASED ON句を使用してlong型のタイム・スタンプ値が含まれるプロパティ名を指定できます。この例では、StockTickイベントにlong型のtimestampプロパティが含まれていることが予期され、この値によってイベントの枠への参加と終了が制御されます。

  SELECT AVG(price) 
  FROM StockTick RETAIN 1 MINUTE BASED ON timestamp

BASED ON句を使用する場合、FROM句の各ストリーム・ソースには関連付けられたtimestampプロパティが含まれている必要があり、そうでない場合はOracle CEPによって例外がスローされます。

2.4.5 プロパティ名の指定

RETAIN句ではプロパティは単純にプロパティ名を使用して参照されます。ただし、FROM句の複数のストリーム・ソースに同名のプロパティが含まれているためあいまいさが存在する場合は、エイリアス名の接頭辞を付け、ピリオドを後に付ける必要があります(SELECT句で参照されるプロパティの動作と同じです)。

2.4.6 PARTION BY句を使用した枠の分割

PARTITION BY句を使用すると、リストされたプロパティの一意な値に基づいて、枠をさらに複数の枠に分割できます。たとえば、次の問合せでは、ユニークな銘柄記号ごとに3件のイベントが保持されます。

  SELECT stockSymbol, price 
  FROM StockTick RETAIN 3 EVENTS PARTITION BY stockSymbol

これは概念的にSQLまたはEPLのGROUP BY関数と同じです。ただし、PARTITION BY句では枠のサイズと分割のみが制御され、GROUP BY句のようにイベント・データは集約されません。ただし、多くの場合、PARTITION BY句は同じプロパティを指定してGROUP BY句と共に使用します。

次の例は、PARTITION BYGROUP BYの間の対話を示しています。最初の例にはPARTITION BY句がありませんが、すべての銘柄記号にわたり合計10件のイベントが保持されます。

  SELECT stockSymbol, AVG(price) 
  FROM StockTick RETAIN 10 EVENTS
  GROUP BY stockSymbol

これらの10件のイベントに基づいてユニークな銘柄記号のセットごとに平均価格が計算されます。銘柄記号AAAが枠に入れられた場合、BBBなどの異なる銘柄記号は枠から離れます。これにより、AAAグループとBBBグループの両方の平均価格が変更されます。

2つ目の例はPARTITION BY句とGROUP BY句を使用します。

  SELECT stockSymbol, AVG(price) 
  FROM StockTick RETAIN 10 EVENTS PARTITION BY stockSymbol
  GROUP BY stockSymbol

この場合、ユニークな銘柄記号ごとに10件のイベントが保持されます。銘柄記号AAAが枠に入れられた場合は、その銘柄に関連付けられたサブ枠のみに影響し、異なる銘柄記号の他の枠は影響を受けません。このため、この場合はAAAの平均価格のみに影響します。

2.4.7 WITH句を使用した最大/最小/一意な値の保持

WITH句を使用すると、プロパティの最大値、最小値、および一意な値を枠内に保持できます。たとえば、2つの最高値の株価を保持するには、次の文を使用します。

  SELECT stockSymbol, price 
  FROM StockTick RETAIN ALL WITH 2 LARGEST price

時間ベースの枠の場合、LARGESTまたはSMALLESTキーワードの前にある[n]修飾子は保持される値の個数を決定します。たとえば、次の文では1分間で発生した2つの最小価格が保持されます。

  SELECT stockSymbol, price 
  FROM StockTick RETAIN 1 MINUTE WITH 2 SMALLEST price

この修飾子がない場合は、1つの最大値または最小値が保持されます。

UNIQUE修飾子により、特定のプロパティに対して同じ値を持つイベントのうち最新のイベントのみが枠に保持されます。たとえば、次の問合せでは、ユニークな銘柄記号ごとに直前の株価表示のみが保持されます。

  SELECT * 
  FROM StockTick RETAIN 1 DAY WITH UNIQUE stockSymbol

同じプロパティ値の古いイベントはエンジンにより古いイベントとしてポストされます。

2.5 MATCHING

すべてのEPL文にはMATCHINGまたはFROM句のいずれかが必要です。MATCHING句はEPL文で使用されるイベントを決定するためのもう1つのメカニズムです。これにより、指定されたパターンを満たす1つまたは複数の一連のイベントの発生が検出されます。パターン式は、パターンを形成するイベント・シーケンスを定義し、ANDOR、およびFOLLOWED BYなどの論理演算子で区切られたストリームへの参照で構成されます。2.4項「RETAIN」で指定されているとおり、省略可能なRETAIN句を使用して、一致したイベントが含まれる枠の特性を定義します。MATCHING句はWHEREまたはHAVING句よりも前に実行されます。

MATCHING句の構文は次のとおりです。

  MATCHING pattern_expression [RETAIN retain_clause]

pattern_expressionの構文は次のとおりです。

  [NOT|EVERY] stream_expression 
      ( ( AND | OR | [NOT] FOLLOWED BY ) stream_expression )* 
  [WITHIN time_interval]

NOT演算子を使用すると、イベントの欠落を検出でき、EVERY演算子を使用すると、パターン照合が一致した後に継続する場合の動作を制御できます。stream_expressionは、オプションで変数にバインドされカッコ内の式でフィルタ処理される、ストリーム・ソース名です。

  stream_expression: [var_name:=]stream_name [( filter_expression )]

また、stream_expressionpattern_expressionにすることができ、これにより任意の複雑な式のネスト化が許可されます。

var_nameは、照合が起動される発生中のイベント・オブジェクトにバインドされます。これは、後に続くフィルタ式や、SELECTWHERE句などの他の句で、他の任意のイベント・プロパティのように参照されます。stream_nameの後には、省略可能な、そのタイプの一致するイベントをフィルタ処理するカッコ内の式が続きます。式はイベントを適切な枠に入れるための事前条件のように動作し、WHERE句の式と同じ構文を持ちます。すでに一致したイベントと関連付けるために、式の内部では前にバインドされた変数が使用されます。

time_intervalは、2.4.4「時間間隔の指定」で指定されている時間間隔であり、省略可能なWITHINキーワードの後に置かれ、前述の式が条件を満たすまで待機する時間を決定します。

次の例では、カテゴリが"Perishable"で、10秒以内にRFIDErrorが後に続き、idが一致したRFIDEventオブジェクトのIDと一致するRFIDEventイベントが参照されます。

  SELECT * 
  MATCHING a:=RFIDEvent(category="Perishable") 
      FOLLOWED BY RFIDError(id=a.id) WITHIN 10 seconds
  RETAIN 1 MINUTE

以降の節では、パターン照合の時相的な制約を表すためにMATCHING句で使用できる構文、セマンティクス、および追加の演算子について説明します。

2.5.1 FOLLOWED BY演算子

FOLLOWED BY時相演算子は、複数のイベント条件が特定の順序で発生した場合に一致します。まず左側の式がtrueになる必要があり、その場合にのみ右側の式で一致するイベントが評価されることが指定されます。

たとえば、次のパターンではイベントAが検索され、これが検出された場合にイベントBが検索されます。

  A FOLLOWED BY B

イベントAの直後にイベントBが続く必要はありません。イベントAとイベントBの間で他のイベントが発生する場合でも、この式はtrueに評価されます。この動作が適切でない場合は、2.5.4項「NOT演算子」で説明しているNOT演算子を使用してください。

2.5.2 AND演算子

AND論理演算子では、式全体がtrueを返す前に両方のネストされたパターン式がtrueになる必要があります。MATCHING句のコンテキストでは、演算子は複数のイベント条件が発生した場合に一致しますが、必ずしも特定の順序である必要はありません。

たとえば、次のパターンは、イベントAとイベントBの両方が見つかった場合に一致します。

  A AND B

パターンは、Aの後にBが続く任意のシーケンスでいずれの順序でも一致します。また、Aイベントの直後にBイベントが続く必要はありません。AイベントおよびBイベントの発生の間に他のイベントが発生してもこの式ではtrueが返されます。

2.5.3 OR演算子

OR論理演算子では、式全体がtrueを返す前にいずれかの式がtrueになる必要があります。MATCHING句のコンテキストでは、演算子は複数のイベント条件のいずれかが発生した場合に一致しますが、必ずしも特定の順序である必要はありません。

たとえば、次のパターンは、イベントAまたはイベントBのいずれでも一致します。

  A OR B

次の例では、特定の価格を超える、または特定の量を超えるすべての株価表示が検出されます。

  StockTick(price > 1.0) OR StockTick(volume > 1000)

2.5.4 NOT演算子

NOT演算子は式の実際の値を否定します。MATCHING句のコンテキストでは、演算子によってイベント条件の欠落が検出されます。

次のパターンでは、イベントBの前にイベントCが検出された場合は除いて、イベントAの後にイベントBが検出された場合にのみ一致します。

  ( A FOLLOWED BY B ) AND NOT C

2.5.5 EVERY演算子

EVERY演算子は、EVERYキーワードで修飾されたサブ式がtrueまたはfalseに評価された場合に、パターンのサブ式を再度開始するよう通知します。EVERY修飾子を指定しない場合は、NOT式の内部に含まれていないパターン内の最初のイベント・ストリームのソースに暗黙的なEVERY演算子が修飾子として挿入されます。

EVERY演算子は包含されているパターンのサブ式のファクトリのように動作します。含まれているパターンのサブ式が発動し、イベントのチェックを終了すると、EVERYによって同じイベントまたはイベント・セットの以降の発生をリスンする新しいパターンのサブ式が開始されます。

EVERY演算子内のパターンのサブ式がtrueになるたびに、エンジンでは新しいアクティブなサブ式が開始され、それ以降のイベント、またはパターンのサブ式に一致するタイミング条件が参照されます。

以下のようなイベント・シーケンスの例を考えます。

A1 B1 C1 B2 A2 D1 A3 B3 E1 A4 F1 B4

表2-1 EVERY演算子の例

説明
EVERY ( A FOLLOWED BY B )

イベントAとその後に続くイベントBが検出されます。Bが発生した時点でパターンが一致し、パターン照合が再開されてイベントAが再び検索されます。

組合せ{A1, B1}B1で一致します。

組合せ{A2, B3}B3で一致します。

組合せ{A4, B4}B4で一致します。

EVERY A FOLLOWED BY B

パターンはすべてのイベントAとその後に続くイベントBで発動します。

組合せ{A1, B1}B1で一致します。

組合せ{A2, B3}および{A3, B3}B3で一致します。

組合せ{A4, B4}B4で一致します。

EVERY A FOLLOWED BY EVERY B

パターンはすべてのイベントAとその後に続くすべてのイベントBで発動します。つまり、イベントAの後にイベントBが来るすべての組み合わせです。

組合せ{A1, B1}B1で一致します。

組合せ{A1, B2}B2で一致します。

組合せ{A1, B3}{A2, B3}および{A3, B3}B3で一致します。

組合せ{A1, B4}{A2, B4}{A3, B4}および{A4, B4}B4で一致します。


これらの例では、パターン式に一致するイベントの複数の組み合わせでパターンが発動できることを示しています。

相互に続く3つのイベントに一致するサブ式でEVERY演算子を使用する場合を考えます。

  EVERY (A FOLLOWED BY B FOLLOWED BY C)

パターンでは最初にイベントAが検索されます。イベントAが到着すると、イベントBが検索されます。イベントBの到着後、イベントCが検索されます。最終的にイベントCが到着するとパターンが一致します。エンジンではイベントAの検索が再開されます。

イベントBとイベントCの間に2つ目のイベントA2が到着すると想定します。パターンはその時点でイベントCを探しているため、A2は完全に無視されます。前の例で見てきたとおり、EVERY演算子ではサブ式が発動された場合にのみ、サブ式A FOLLOWED BY B FOLLOWED BY Cが再開されます。

次の文では、EVERY演算子はサブ式全体ではなく、Aイベントにのみ適用されます。

  EVERY A FOLLOWED BY B FOLLOWED BY C

このパターンでは、イベントAが到着するタイミングにかかわらず、すべてのイベントAについてその後にイベントBとイベントCが続く場合にパターンが一致します。これは、AND NOT構文やRETAIN構文と共に使用してイベントが枠内にとどまる期間に制約を設けない限り、多くの場合に実用的でなくなります。

2.5.6 WITHIN演算子

WITHIN修飾子の動作はストップウォッチと同じです。関連付けられているパターン式が指定の時間内にtrueにならなかった場合、エンジンではfalseとして評価されます。WITHIN修飾子は、2.4.4項「時間間隔の指定」で指定されているとおり、時間間隔をパラメータとして受け取ります。

このパターンは、文の作成後5秒以内にAイベントが到着すると発動します。

  A WITHIN 5 SECONDS

このパターンは5秒以内に到着するすべてのAイベントで発動します。

このパターンは、次の5秒間の任意の1つのAまたはBイベントに一致します。

  (A or B) WITHIN 5 SECONDS

このパターンは、相互に10秒以内に発生する任意の2つのエラーに一致します。

  A(status='ERROR') FOLLOWED BY B(status='ERROR') WITHIN 10 SECONDS

このパターンは、10秒以内にStatusイベントが発生しない場合に一致します。

  NOT Status WITHIN 10 SECONDS

2.5.7 一致したパターンのイベント構造

パターンが一致した場合に生成されるイベントの構造は、MATCHING句内にバインドされている変数の共用体の構造によって決定されます。このため、一致したイベントからデータを取得するには変数のバインドが存在している必要があります。

たとえば、次のパターンがあるとした場合:

  tick:=StockTick FOLLOWED BY news:=News(stockSymbol = tick.stockSymbol)

一致するイベントには、StockTick型のtickプロパティおよびNews型のnewsプロパティという2つのプロパティを持つ複合イベント型が含まれています。

2.6 WHERE

WHERE句はEPL文の省略可能な句です。WHERE句を使用してイベント・ストリームを結合し、イベントをフィルタ処理できます。WHERE句に集約関数を含めることはできません。集約関数を使用してフィルタ処理するには、HAVING句を使用する必要があります。

  WHERE aggregate_free_expression

WHERE句では、比較演算子=<>>=<=!=<>IS NULLIS NOT NULL、およびANDORを使用した論理結合がサポートされています。以下にいくつかの例を示します。

  ...WHERE fraud.severity = 5 AND amount > 500
  ... WHERE (orderItem.orderId IS NULL) OR (orderItem.class != 10)
  ... WHERE (orderItem.orderId = NULL) OR (orderItem.class <> 10)
  ... WHERE itemCount / packageCount > 10

2.7 GROUP BY

GROUP BY句はEPL文で省略可能です。GROUP BY句はEPL文の結果をグループに分割します。1つまたは複数のイベント・プロパティ名、または式の計算結果によるグループ化が可能です。集約関数と共に使用した場合、GROUP BYでは各サブグループで計算が取得されます。GROUP BYは集約関数なしに使用できますが、通常は混乱した結果が生成されます。

たとえば、次の文では、直前の30秒間のすべてのStockTickEventsの銘柄ごとの合計価格が返されます。

  SELECT symbol, SUM(price) 
  FROM StockTickEvent RETAIN 30 SEC 
  GROUP BY symbol

GROUP BY句の構文は次のとおりです。

  GROUP BY arregate_free_expression [, arregate_free_expression] [, …]

EPLでは、GROUP BY句の式に次の制限があります。

GROUP BY句に複数の式をリストしてグループをネストできます。GROUP BYでセットが確立されると、集約関数が適用されます。この文では、直前の30秒間のすべての株価表示イベントの中央量が、銘柄および表示データ・フィード別にグループ化されてポストされます。EPLにより、各グループごとに1つのイベントが文の更新リスナーにポストされます。

  SELECT symbol, tickDataFeed, MEDIAN(volume)
  FROM StockTickEvent RETAIN 30 SECONDS
  GROUP BY symbol, tickDataFeed

前述の文では、SELECTリスト内のイベント・プロパティ(symbolおよびtickDataFeed)がGROUP BY句にもリストされています。このため、この文は、SELECTリスト内の非集約イベント・プロパティがGROUP BY列に一致する必要があることを規定しているSQL標準に従っています。

EPLでは、SELECTリスト内の1つまたは複数のイベント・プロパティがGROUP BY句にリストされていない文もサポートされています。下の文はこのようなケースを示しています。この文では、直前の30秒間の株価表示の標準偏差が計算され、銘柄別に集約され、各イベントごとにsymboltickDataFeed、およびpriceの標準偏差がポストされます。

  SELECT symbol, tickDataFeed, STDDEV(price)
  FROM StockTickEvent RETAIN 30 SECONDS
  GROUP BY symbol

上の例では、priceイベント・プロパティは依然としてsymbolに基づいて集約されますが、グループごとに1つのイベントではなく、着信イベントごとに1つのイベントが生成されます。

また、EPLでは、GROUP BY句の1つまたは複数のイベント・プロパティがSELECTリストに含まれていない文がサポートされています。この例では、symbolおよびtickDataFeedごとの平均偏差が計算され、グループごとに1つのイベントがポストされ、生成されたイベントにはsymbolpriceの平均偏差が含まれています。ポストされた結果にtickDataFeedが含まれていないため、混乱が生じる可能性があります。

  SELECT symbol, AVEDEV(price)
  FROM StockTickEvent RETAIN 30 SECONDS
  GROUP BY symbol, tickDataFeed

GROUP BYリストには式も使用できます。

  SELECT symbol * price, count(*)
  FROM StockTickEvent RETAIN 30 SECONDS
  GROUP BY symbol * price

GROUP BY式の結果がnull値の場合、null値は固有のグループになります。すべてのnull値が同じグループに集約されます。COUNT(expression)集約関数ではnull値が考慮されず、null値のみが検出された場合、COUNTでは0が返されます。

文ではWHERE句をGROUP BYとともに使用できます。WHERE句の条件を満たしていないイベントはグループ化が実行される前に消去されます。たとえば、下の文では、量が100を超える直前の30秒間の株価表示数がポストされ、グループ(symbol)ごとに1つのイベントがポストされます。

  SELECT symbol, count(*)
  FROM StockTickEvent RETAIN 30 SECONDS
  WHERE volume > 100
  GROUP BY symbol

2.8 HAVING

HAVING句はEPL文で省略可能です。HAVING句を使用して、GROUP BY句で定義されたイベントを承認または拒否します。WHERESELECT句の条件を設定するのと同様、HAVING句はGROUP BY句の条件を設定します。ただし、WHERE句には集約関数を含めることができず、HAVINGでは多くの場合に集約関数が使用される点が異なります。

  HAVING expression

この文は、HAVING句で集約関数を使用する例です。直前の30秒間の株価表示イベントで、合計価格が1000を超える銘柄についてのみ銘柄ごとの合計価格がポストされます。HAVING句により合計価格が1000以下のすべての銘柄が消去されます。

  SELECT symbol, SUM(price)
  FROM StockTickEvent RETAIN 30 SEC
  GROUP BY symbol
  HAVING SUM(price) > 1000

HAVING句に複数の条件を含めるには、ANDOR、またはNOTを使用して条件を組み合せます。これを示す下の文では、合計価格が1000を越え、平均量が500未満のグループのみが選択されます。

  SELECT symbol, SUM(price), AVG(volume)
  FROM StockTickEvent RETAIN 30 SEC
  GROUP BY symbol
  HAVING SUM(price) > 1000 AND AVG(volume) < 500

HAVING句を使用する文ではGROUP BY句も使用する必要があります。GROUP BYを省略すると、WHERE句で除外されないすべてのイベントが1つのグループとして返されます。この場合、HAVINGには集約関数を含めることができる点を除いて、HAVINGWHEREと同様に動作します。

次の例が示すように、HAVING句はGROUP BY句なしでも使用できます。この例では、直前の30秒間のすべての株価表示イベントで価格が現在実行中の平均価格に満たないイベントがポストされます。

  SELECT symbol, price, AVG(price)
  FROM StockTickEvent RETAIN 30 SEC
  HAVING price < AVG(price)

2.8.1 MATCHING、WHEREおよびGROUP BY句との対話

EPL文に副問合せ、MATCHING句、WHERE条件、GROUP BY句、およびHAVING条件が含まれている場合、最終結果はそれぞれの句が実行される順序によって決定されます。

  1. 文に出現する副問合せが最初に実行されます。副問合せは、イベントが外部問合せの枠に入れられるためのフィルタとして動作します。

  2. MATCHING句にイベント・ストリームのフィルタ条件が存在する場合は、この条件により枠に入れられるイベントが指定されます。フィルタ条件を満たさないイベントはすべて破棄されます。

  3. WHERE句により、検索条件に一致しないイベントが除外されます。

  4. SELECTリストの集約関数で各グループの概略値が計算されます。

  5. HAVING句により、検索条件に一致しないイベントが最終結果から除外されます。

次の問合せでは、SELECT句で集約関数を使用し、フィルタ、WHEREGROUP BY、およびHAVING句を1つの文で使用する場合を示しています。

  SELECT tickDataFeed, STDDEV(price)
  FROM (SELECT * FROM StockTickEvent WHERE symbol='ACME')
  RETAIN 10 EVENTS
  WHERE volume > 1000
  GROUP BY tickDataFeed
  HAVING STDDEV(price) > 0.8

EPLではイベント・ストリームStockTickEventに対する副問合せを使用してイベントがフィルタされます。上の例では、直前の10件のイベントに対し銘柄ACMEのイベントのみが枠に入れられ、他のすべてのイベントは単に破棄されます。WHERE句により、枠にポストされたイベントのうち、量が1000を超えるという条件に一致しないイベント(枠に入れられるイベントおよび枠を離れるイベント)が削除されます。GROUP BY句に指定されているとおり、各表示データ・フィードごとに、残りのイベントにSTDDEV標準偏差の集約関数が適用されます。各tickDataFeed値につき1つのイベントが生成されます。EPLではHAVING句が適用され、priceの標準偏差が0.8を超えるtickDataFeedグループのイベントのみが承認されます。

2.9 ORDER BY

ORDER BY句はEPLで省略可能です。これを使用して、プロパティまたはプロパティを使用する式で出力イベントを順序付けします。たとえば、次の文では1分間の株価表示イベントがバッチ処理され、最初に価格、次に量によって並べ替えられます。

  SELECT symbol 
  FROM StockTickEvent RETAIN BATCH OF 1 MINUTE
  ORDER BY price, volume

ORDER BY句の構文は次のとおりです。

  ORDER BY expression [ASC | DESC] [, expression [ASC | DESC] [,…]]

EPLでは、ORDER BY句の式に次の制限があります。

他の点では、SELECT句に使用できる任意の種類の式、およびSELECT句に定義されている任意のエイリアスは、ORDER BY句でも有効です。

2.10 OUTPUT

OUTPUT句はEPLで省略可能で、この句を使用してイベント出力の割合を制御または安定化させます。たとえば、次の文では新しいイベントと古いイベントがバッチ処理され、これらが90秒間隔で出力されます。

  SELECT * 
  FROM StockTickEvent RETAIN 5 EVENTS 
  OUTPUT EVERY 90 SECONDS

出力の割合を制限する構文は以下のとおりです。

  OUTPUT [ALL | ( (FIRST | LAST) [number]] EVERY number [EVENTS | time_unit]

各項目は次のとおりです。

  time_unit: MIN | MINUTE | MINUTES | SEC | SECOND | SECONDS | MILLISECONDS | MS

ALLキーワードはデフォルトであり、バッチ内のすべてのイベントが出力されることを指定します。バッチ・サイズは時間またはイベント数で指定できます。

FIRSTキーワードは出力バッチ内の最初のイベントのみが出力されることを指定します。省略可能な数値修飾子を使用して複数のイベントを出力できます。FIRSTキーワードでは、最初に一致したイベントが到着後すぐに出力されるようエンジンに指示され、その後は指定された時間間隔またはイベント数の一致するイベントは無視されます。時間間隔が経過するか、または一致するイベント数に到達した後は、同じサイクルが開始されます。

LASTキーワードは、指定の時間間隔内で最後のイベントのみを出力するか、または指定された数の一致するイベントが蓄積された後で最後のイベントのみを出力することを指定します。省略可能な数値修飾子を使用して複数のイベントを出力できます。

時間間隔は分またはミリ秒でも指定できます。次の文は最初の文と同じです。

  SELECT * 
  FROM StockTickEvent RETAIN 5 EVENTS 
  OUTPUT EVERY 1.5 MINUTES

出力を安定化する2つ目の方法は、特定の数のイベントが収集されるまでイベントをバッチ処理する方法です。次の文では、新しい5件(またはそれ以上)あるいは古い5件(またはそれ以上)のイベントがバッチ処理された後で初めて出力されます。

  SELECT * 
  FROM StockTickEvent RETAIN 30 SECONDS 
  OUTPUT EVERY 5 EVENTS

また、省略可能なLASTキーワードを使用してイベント出力をさらに変更できるため、最後のイベント(複数可)の出力のみが出力バッチに到着します。下の例では、最後の5件のイベントが3分ごとに出力されます。

  SELECT * 
  FROM StockTickEvent RETAIN 30 SECONDS 
  OUTPUT LAST 5 EVERY 3 MINUTES

FIRSTキーワードを使用すると、間隔の開始時に通知を受け取ることができます。この例では、rateがしきい値を下回るたびに直ちに通知されます。

  SELECT * 
  FROM TickRate RETAIN 30 SECONDS
  WHERE rate < 100
  OUTPUT FIRST EVERY 60 SECONDS

2.10.1 GROUP BYおよびHAVING句との対話

OUTPUT句がGROUP BYおよびHAVING句と対話する方法には2種類あります。まず、OUTPUT EVERY n EVENTSの場合、数字nはGROUP BY句に到着するイベントの数を指します。つまり、GROUP BY句でグループにつき1つのイベントのみが出力される場合、または到着するイベントがHAVING句の条件を満たしていない場合、実際に文で出力されるイベント数はnより少ない場合があります。

2つ目に、LASTおよびALLキーワードは、集約関数とGROUP BY句が含まれている文で使用する場合に特別な意味を持ちます。LASTキーワードは、集約値が最新のイベント・バッチで更新されているグループのみが出力されることを指定します。ALLキーワード(デフォルト)は、グループの集約値が更新されているかどうかに関係なく、これまでに見つかったすべてのグループの最新のデータが出力されることを指定します。

2.11 INSERT INTO

INSERT INTO句はEPLで省略可能です。この句を指定して、文の結果を後続の文で使用できるイベント・ストリームとして作成できます。また、この句を使用して、複数のイベント・ストリームを結合して1つのイベント・ストリームを作成できます。

  INSERT INTO CombinedEvent
  SELECT A.customerId AS custId, A.timestamp - B.timestamp AS latency
  FROM EventA A, EventB B RETAIN 30 MIN
  WHERE A.txnId = B.txnId

前述の文のINSERT INTO句ではタイプCombinedEventのイベントが生成されます。生成されたそれぞれのCombinedEventイベントには、custIdおよびlatencyという2つのイベント・プロパティが含まれています。上の文で生成されたイベントを後続の文で使用できます。たとえば、下の文では生成されたイベントを使用しています。

  SELECT custId, SUM(latency)
  FROM CombinedEvent RETAIN 30 MIN
  GROUP BY custId

INSERT INTO句にはイベント・タイプ・エイリアスのみを含めるか、またはイベント・タイプ・エイリアスおよび1つまたは複数のイベント・プロパティ名を含めることができます。INSERT INTO句の構文は以下のとおりです。

  INSERT [ISTREAM | RSTREAM] INTO event_type_alias [(prop_name [,prop_name, [,…]] ) ]

ISTREAM(デフォルト)およびRSTREAMキーワードは省略可能です。いずれのキーワードも指定しない場合、エンジンでは文で生成された挿入ストリーム・イベントがアタッチされた更新リスナーに提供されます。挿入ストリームはそれぞれの枠またはストリームに入れられるイベントで構成されます。RSTREAMキーワードを指定した場合、エンジンでは文で生成された削除ストリーム・イベントが提供されます。削除ストリームはそれぞれの枠を離れるイベントで構成されます。

event_type_aliasはエンジンで生成されたイベントを指定する識別子です。文中では識別子を使用して、指定の名前のイベントをフィルタおよび処理できます。

また、エンジンでは、INSERT INTO句が含まれている文に更新リスナーがアタッチされることが許可されます。

イベント・ストリームを結合するには、結合する任意のEPL文で同じevent_type_alias識別子を使用するだけで済みます。使用するイベント・プロパティの数と名前が同じであり、イベント・プロパティのタイプが一致することを確認します。

EPLでは、INSERT INTO句に次の制限があります。

次の例では、使用するプロパティ名が明示的に定義されたもう1つの形式のINSERT INTO句を示します。

  INSERT INTO CombinedEvent (custId, latency)
  SELECT A.customerId, A.timestamp - B.timestamp
  FROM EventA A, EventB B RETAIN 30 MIN
  WHERE A.txnId = B.txnId

RSTREAMキーワードを使用して、削除ストリーム・イベントのみを生成するようエンジンに指示します。これは、イベントが枠に入れられたときでなく枠を離れたときにアクションを起動する必要がある場合に便利です。下の文では、EventAEventBが30分後に枠を離れたときにCombinedEventイベントが生成されます。

  INSERT RSTREAM INTO CombinedEvent
  SELECT A.customerId AS custId, A.timestamp - B.timestamp AS latency
  FROM EventA A, EventB B RETAIN 30 MIN
  WHERE A.txnId = B.txnId

2.12 単純副問合せと相関副問合せ

副問合せは別の文の内部にあるSELECTです。EPLでは、EPL文のSELECT句およびWHERE句内の副問合せがサポートされています。副問合せでは、複雑な結合を必要とするような操作を実行するためのもう1つの手段が提供されます。また、副問合せでは複雑な結合よりも文が読みやすくなります。

EPLでは、単純副問合せと相関副問合せの両方がサポートされています。単純な副問合せでは、内部問合せが外部問合せの要素(行)を参照しません。次の例は、SELECT句内の単純な副問合せを示します。

  SELECT assetId, 
    (SELECT zone 
     FROM ZoneClosed.std:lastevent) AS lastClosed  
  FROM RFIDEvent
  SELECT assetId, 
    (SELECT zone 
     FROM ZoneClosed RETAIN ALL EVENTS) AS lastClosed  
  FROM RFIDEvent

次の例に示すように、外部問合せに依存している内部問合せは相関問合せと呼ばれます。問合せでは、内部問合せ内のWHERE句が外部問合せからのストリームを使用しています。

  SELECT * 
  FROM RfidEvent AS RFID 
  WHERE 'Dock 1' =
    (SELECT name 
     FROM Zones RETAIN ALL EVENTS WITH UNIQUE  zoneId 
      WHERE zoneId = RFID.zoneId)

前述の例はWHERE句内の副問合せを示します。文では、ゾーンIDに基づいて文字列定数とゾーン名が一致するRFIDイベントが選択されます。文ではRETAIN句にWITH UNIQUEサブ句を使用することで、ゾーンIDごとの最後のイベントのみが副問合せによる処理で保持されることが保証されます。

次の例はSELECT句内の相関副問合せです。この問合せのSELECT句では、ゾーンIDで関連付けられたZonesイベント・セットに対する副問合せによってゾーン名が取得されます。

  SELECT zoneId, 
    (SELECT name 
     FROM Zones RETAIN ALL EVENTS WITH UNIQUE zoneId
     WHERE zoneId = RFID.zoneId) AS name 
  FROM RFIDEvent

単純副問合せまたは相関副問合せで複数の行が返される場合、Oracle CEPでは副問合せの結果としてnull値が返されます。副問合せで返されるイベント数を制限するには、RETAIN句でWITH UNIQUEまたはPARTITION BYを使用することを検討します。

副問合せのSELECT句ではワイルドカードによる選択も可能であり、FROM句で定義されているイベント・タイプの基になるイベント・オブジェクトがイベント・プロパティとして返されます。例を示します。

  SELECT 
    (SELECT * 
     FROM MarketData RETAIN 1 EVENT) AS md
  MATCHING WITHIN 10 SECONDS

前述の文の出力イベントには、基になるMarketDataイベントがmdというプロパティに含まれています。文では、パターン定義に従って、10秒ごとに最後のMarketDataイベントがmdというプロパティに挿入されるか、またはMarketDataイベントがそれまで検出されなかった場合はnull値が挿入されます。

副問合せに適用される制限は以下のとおりです。

1つまたは複数の副問合せが含まれている文のパフォーマンスは、主に2つの要因に応じて変化します。1つ目には、副問合せによって、副問合せストリーム内の1つまたは複数の列がイコール記号(=)を使用して外側の文のストリームと関連付けられている場合、Oracle CEPでは行の迅速な取得のために、関連付けられた(結合された)キー値に基づいて適切な索引が自動的に構築されます。2つ目の要因には、副問合せストリーム内の行数とフィルタ条件(WHERE句)の複雑さがあります。これは、副問合せ・ストリーム内の各行がWHERE句のフィルタに対して評価される必要があるためです。

2.13 パラメータ化された問合せ

パラメータ化された問合せを使用すると、EPL問合せの内部に疑問符の形式でプレースホルダーを含めることができます。プレースホルダーは実行時に値とバインドされ、通常の文にコンパイルされます。プロセスはJDBCのPreparedStatementとほぼ同じです。

パラメータ化された問合せを使用すると、考えられるパラメータ値のそれぞれに個別のルールを作成する必要がなくなります。たとえば、シグナル・トレーディング・アプリケーションには照合の対象となる銘柄記号を選択する値のみが異なる300のルールが含まれています。実世界のアプリケーションでは、ルールのロジックが変更されるとそれによって300のルールすべてに同一の変更を加える必要が生じるため、300の個別のルールを管理することは厄介な作業です。代わりに、パラメータ化された問合せの手法によって、開発者は後から特定の銘柄記号の値にバインドされるプレースホルダーを問合せに配置できます。パラメータ化された問合せは、値とバインドされた後は通常の問合せにコンパイルされるため、問合せのパフォーマンスに悪影響を及ぼすことはありません。

パラメータ化されたEPL問合せに関連付けられたパラメータをJavaコードを作成せずに実行時に変更するには、『Oracle Fusion Middleware Oracle Complex Event Processing管理者ガイド』のwlevs.Adminコマンドライン・リファレンスを使用します。

2.13.1 一般的な使用法

パラメータ化されたEPL問合せでは疑問符を使用してプレースホルダーの場所を指定します。現在定数を使用できる任意の式でプレースホルダーを使用できます。定数を使用するのと同じ場所にプレースホルダーを配置します。これは実際には、問合せのSELECTおよびWHERE句にのみプレースホルダーを指定できることを意味しています。RETAIN句でプレースホルダーを使用することはできません。

次の例は、パラメータ化された問合せを示します。

  SELECT symbol, AVG(price) AS average, ? AS market
  FROM StockTick t RETAIN ALL EVENTS
  WHERE symbol = ?

この例では、SELECTおよびWHERE句の両方でプレースホルダーを指定する方法を示しています。実行時に、2つのプレースホルダーはNASDAQORCLなどの値にバインドされるため、実行される実際のEPL文は以下のようになります。

  SELECT symbol, AVG(price) AS average, NASDAQ AS market
  FROM StockTick t RETAIN ALL EVENTS
  WHERE symbol = ORCL

2.13.2 プロセッサ構成ファイルでのパラメータ化されたEPL文の使用

特定のプロセッサのEPLルールをコンポーネント構成ファイルで構成した場合は、<rule>要素を使用してEPL文を通常どおり指定します。2.13.1項「一般的な使用法」で説明しているように、疑問符を使用してプレースホルダーを指定します。

次に、<binding>要素を使用して、実行時にパラメータ化されたEPL文に渡す必要のあるカンマ区切りの値リストに対応する1つまたは複数の<params>要素を指定します。各<params>要素によって、新しいEPL問合せが新しいパラメータを使用して効率的に実行されます。<binding>id属性を使用して、バインドが適用される特定のEPLルールを参照します。各<params>要素にはパラメータの単一のセットが含まれています。パラメータの順序はパラメータ化された問合せに出現する疑問符の順序に対応しています。

<params>id属性を使用して個別のパラメータ・セットを一意に識別し、後からJMXまたはwlevs.Adminを使用して単一のパラメータ・セットを動的に削除できます。

構成ファイルのEPLルールのように、親要素<bindings>を使用して<binding>要素をグループにまとめます。

次の例では、2.13.1項「一般的な使用法」で説明している問合せについて、パラメータ化された問合せとランタイム・パラメータを指定する方法を示します。

<n1:config xmlns:n1="http://www.bea.com/ns/wlevs/config/application" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <processor>
        <name>myProcessor</name>
        <rules>
            <rule id="MarketRule"><![CDATA[ 
                 SELECT symbol, AVG(price) AS average, ? AS market
                 FROM StockTick t RETAIN ALL EVENTS
                 WHERE symbol = ?
            ]]></rule>
        </rules>
        <bindings>
            <binding id="MarketRule">
                <params id="nasORCL">NASDAQ,ORCL</params>
                <params id="nyJPM">NYSE,JPM</params>
                <params id="nyWFC">NYSE,WFC</params>
            </binding>
        </bindings>
    </processor>
</n1:config>

前述の例では、MarketRule EPL問合せに2つのプレースホルダーが含まれており、1つはSELECT句、もう1つはWHERE句にあります。<binding id="MarketRule">要素は、実行時にMarketRuleに渡されるパラメータ・セットのリストを指定します。各パラメータ・セットは単一の<params>要素で指定されます。パラメータ化された問合せには2つのプレースホルダーが含まれているため、各<params>要素にはカンマ区切りの2つの値が指定されています。

実行時に、上記のパラメータ化された問合せは以下の3つの問合せに効率的に分解されます。

  SELECT symbol, AVG(price) AS average, NASDAQ AS market
  FROM StockTick t RETAIN ALL EVENTS
  WHERE symbol = ORCL
  SELECT symbol, AVG(price) AS average, NYSE AS market
  FROM StockTick t RETAIN ALL EVENTS
  WHERE symbol = JPM
  SELECT symbol, AVG(price) AS average, NYSE AS market
  FROM StockTick t RETAIN ALL EVENTS
  WHERE symbol = WFC

2.13.3 プログラムでのプリペアドEPL文の使用

アプリケーションでOracle CEP APIを使用してEPLルールを作成および実行し、パラメータ化されたルールを使用する場合は、com.bea.wlevs.ede.api.PreparedStatementインタフェースを使用して、提供されたパラメータ値に基づいたインタフェースを持つcom.bea.wlevs.ede.api.BoundStatementのインスタンスを作成します。

PreparedStatementおよびBoundStatementは両方とも、コンパイルされたEPL問合せを表す基本オブジェクトであるStatementを拡張します。PreparedStatementには、パラメータを問合せ内のプレースホルダーにバインドし、問合せ内のプレースホルダーの数を返し、バインドIDに基づいてBoundStatementのインスタンスを返す追加のメソッドがあります。BoundStatementには、EPL問合せのバインドに使用されるパラメータ値を取得し、実際のパラメータ化された問合せ自体を取得する追加のメソッドがあります。

PreparedStatementstart()またはstop()メソッドが呼び出されると、Oracle CEPではPreparedStatementから作成されたすべてのBoundStatementsが起動または停止されます(これは、パラメータ化された問合せはそれ自身では実行不能であり、実際には固有のパラメータ値を使用して作成されたBoundStatementsのみが実行可能であるためです)。

これらのAPIの参照ドキュメントの詳細は、『Oracle Fusion Middleware Oracle Complex Event Processing Java APIリファレンス』を参照してください。

次のJavaの例は、2.13.1項「一般的な使用法」で説明している問合せを使用してBoundStatementを作成する方法を示します。

    String stmtString =
        "select symbol, avg(price) as average, ? as market " +
        "from StockTick t " +
        "retain all events " +
        "where symbol = ?"
        ;
    processorImpl.createStatement(stmtString);
    PreparedStatement preparedStmt = (PreparedStatement)processorImpl.createStatement(stmtString);
    BoundStatement orclBoundStmt = preparedStmt.bind(new String[] {"NASDAQ","ORCL"});