Oracle Database 10gの1機能であるOracle Expression Filterは、アプリケーション開発者が条件式(式)をリレーショナル表の1つ以上の列に格納し、索引を付けて評価できるようにするルール・マネージャのコンポーネントです。式は、求めるデータについて、関心対象を記述できる便利な方法です。
式フィルタでは、受け取ったデータが列に格納されている式と照合され、該当する行が識別されます。また、ある表のデータを第2の表の式と照合することで複雑な関係を導出できます。式フィルタによりSQL問合せが単純化され、アプリケーションを変更せずに式を挿入、更新および削除できます。また、条件式をアプリケーションから分離してデータベースに格納することで、ルールでの再利用を可能にします。情報の配布、需要分析およびタスク割当てに関係するアプリケーションは、式フィルタを使用するとメリットが得られます。
式フィルタは、データ項目や情報の関心対象を記述する式を格納、評価および索引付けするためのデータ型、演算子および索引タイプを提供します。これらの用語の説明は、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。式はユーザー表の1列に格納されます。式フィルタでは、列にある式がSQL文から渡されたデータ項目、または1つ以上の表に格納されているデータと照合され、それぞれの式がTRUEであるかFALSEであるかが評価されます。Oracle DatabaseのEnterprise Editionを使用している場合は、オプションで式に索引を付けることができます。式フィルタに組み込まれている要素は次のとおりです。
属性セット: イベントとその属性セットの定義です。
Expressionデータ型: 式を格納するユーザー表のVARCHAR2
列に対する制約を介して作成される仮想データ型です。
EVALUATE
演算子: データ項目ごとに式を評価する演算子です。
管理ユーティリティ: 式の妥当性をチェックして最適な索引構造を提案する一連のユーティリティです。
式の索引付け: 大きい式セットについてEVALUATE
演算子のパフォーマンスを拡張する索引です。式の索引付けは、Oracle Database Enterprise Editionで使用可能です。
この項では、式フィルタの使用例を示します。
受け取ったデータと条件式との照合
式フィルタでは、受け取ったデータをデータベースに格納されている条件式と照合し、該当する行を識別できます。たとえば、自動車の買い手と売り手を一致させるアプリケーションを考えてみます。Consumer
表には、Expressionデータ型のBUYER_PREFERENCES
列が含まれています。BUYER_PREFERENCES
列には、製造業者、型式、年、走行距離数、色、オプションおよび価格など、顧客が購入を希望している車種を記述する顧客別の式が格納されています。販売されている自動車に関するデータは、SQLのWHERE
句にEVALUATE
演算子とともに指定されます。SQLのEVALUATE
演算子により、受け取った自動車データが式と照合され、見込み客が検索されます。
また、SQLのEVALUATE
演算子を使用して受け取ったデータをバッチ処理することもできます。データをCARS
という表に格納し、CONSUMER
表に格納されている式と照合できます。そのためには、2つの表の結合を使用します。
SQLのEVALUATE
演算子では、受け取ったデータが式セットと照合され、また、大きな式セットには索引を付けてパフォーマンスを向上できるため、処理時間を短縮できます。アプリケーションを変更せずに式を挿入、更新および削除でき、また、その結果セットに対し、同じSQL文内で結果の順序付けやグループ化などの操作が可能なため、労力も削減されます。これに対して、手続き型アプローチでは結果が一時表に格納されるため、さらに処理するためには問い合せる必要があり、式に索引を付けることもできません。
複雑な表関係の維持
式フィルタでは、表間にN 対M (多対多)の関係を持たせることができます。前述の例を使用します。
1台の自動車に1人以上の買い手が関心を示す場合があります。
1人の買い手が1台以上の自動車に関心を示す場合があります。
1人の売り手が1人以上の買い手に関心を示す場合があります。
このような関係に関する質問に回答するために、自動車に関する受け取ったデータはSELLER_PREFERENCES
というExpression列(Expressionデータ型の列)を使用してCARS
表に格納されます。CONSUMERS
表には、BUYER_PREFERENCES
という列があります。SQLのEVALUATE
演算子を使用すると、次のような質問に対する回答を得ることができます。
各顧客が関心を持っている自動車。
各売り手が関心を持っている買い手。
各自動車に対する既存需要。この情報は、最適な価格設定の決定に役立ちます。
未達需要があるかどうか。この情報は、在庫所要量の決定に役立ちます。
この宣言的なアプローチでは、労力が削減されます。データまたは式に変更があっても、アクションは不要です。このアプローチを、マッピング表が作成され2つの表の関係を格納していた従来のアプローチと比較してみます。データや式に変更があった場合は、トリガーを定義して関係を再計算し、マッピング表を更新する必要があります。この場合は、新しいデータをすべての式と比較し、新しい式をすべてのデータと比較する操作が必要になります。
アプリケーションの属性
式フィルタは、データが次の属性を持つアプリケーションに適しています。
評価対象のデータ項目が多数存在する場合。
各データ項目が構造化されたデータ属性(VARCHAR、NUMBER、DATE、XMLTYPE
など)を持つ場合。
受け取るデータが、式を含む一意の永続的な多数の問合せにより評価される場合。
式(SQLのWHERE
句)が、受け取るデータ項目の関心対象を記述するものである場合。
式で関係演算子(=、!=、<、>など)を使用して属性が値と比較される場合。
式には、データ項目の関心対象を記述します。式はユーザー表の列に格納され、SQLのEVALUATE
演算子を使用して、SQLのWHERE
句に指定されている受け取ったデータ項目、またはデータ表と比較されます。式はTRUEまたはFALSEとして評価されるか、行に対する式が存在しない場合はNULL値が戻されます。
式には、要素属性と呼ばれる1つ以上の変数を使用してデータ項目の関心対象を記述します。また、リテラル、オラクル社が提供する関数、ユーザー定義関数および表の別名を含めることもできます。有効な式は、述語と呼ばれる1つ以上の単純な条件で構成されます。式の述語は論理演算子AND
およびOR
で連結されます。式はSQLのWHERE
句の形式に従う必要があります。(SQLのWHERE
句の詳細は、『Oracle Database SQL言語リファレンス』を参照。)定義済の要素属性をすべて式に使用する必要はありませんが、受け取るデータで要素属性ごとに値が提供される必要があります。NULLは許容値です。
たとえば、次の式にはオラクル社が提供するUPPER
関数が含まれており、型式、価格および年の要素属性を使用してユーザーが関心を持っている自動車(データ項目)が取得されます。
UPPER(Model) = 'TAURUS' and Price < 20000 and Year > 2000
式はExpressionデータ型を使用してユーザー表の1列に格納されます。この型の列に格納される値には、式であるという制約が適用されます。(第11.2.2項を参照。)ユーザー表には、1つ以上のExpression列を格納できます。Expression列の内容を表示するための問合せでは、式が文字列形式で表示されます。
式の挿入、更新および削除には、標準SQLを使用します。1つの列に格納されている式のグループを式セットと呼び、式セットでは共通の要素属性セットが共有されます。この要素属性セットと式に使用される関数は、式セットのメタデータです。このメタデータを属性セットと呼びます。属性セットは、式に使用される要素属性の名前、データ型および関数で構成されます。Expression列では、属性セットを使用して式セットに対する変更および追加の妥当性がチェックされます。Expression列に格納された式に使用できるのは、対応する属性セットに定義されている要素属性と関数のみです。式に副問合せは使用できません。
式フィルタには、式のデータを管理するためのプロシージャを含むDBMS_EXPFIL
パッケージが用意されています。
Expression列を作成して使用する操作には、次の4つの基本手順があります。
属性セットの定義。第11.2.1項を参照してください。
ユーザー表でのExpression列の定義。第11.2.2項を参照してください。
表への式の挿入。第11.2.3項を参照してください。
SQLのEVALUATE
演算子の適用による、式と受け取ったデータ項目との比較。第11.3項を参照してください。
図11-1に、式フィルタに基づくルール・アプリケーションの作成と実装の処理手順を示します。この章の以降の項では、この手順について説明します。
属性セットの作成には、特殊な形式のOracleオブジェクト型を使用します。(オブジェクト型の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照。)
属性セットでは、式セットの要素属性を定義します。式セットでは、オラクル社が提供するすべてのSQL関数を有効な参照として暗黙的に使用できます。式セットでユーザー定義関数を参照する場合は、属性セットに明示的に追加する必要があります。属性セットに含まれる要素属性では、表の別名の構成メンバーを使用して、他のデータベース表に格納されているデータを参照できます。属性セットの1つ以上またはすべての要素属性として表の別名を使用できます。要素属性が表の別名である場合、その要素属性に割り当てられる値は対応する表からのROWID
です。表の別名の詳細は、付録Aを参照してください。
既存のオブジェクト型を使用し、そのオブジェクト型と同じ名前の属性セットを作成する方法。この方法が最も適しているのは、属性セットに表の別名である要素属性が含まれていない場合です。この方法にはDBMS_EXPFIL
パッケージのCREATE_ATTRIBUTE_SET
プロシージャを使用します。例11-1を参照してください。
既存の属性セットに要素属性を個別に追加する方法。式フィルタでは、要素属性をカプセル化するオブジェクト型が自動的に作成され、属性セットと同じ名前が与えられます。この方法が最も適しているのは、属性セットに表の別名として定義された1つ以上の要素属性が含まれている場合です。この方法にはDBMS_EXPFIL
パッケージのADD_ELEMENTARY_ATTRIBUTE
プロシージャを使用します。例11-2を参照してください。
式でユーザー定義関数を参照する場合は、DBMS_EXPFIL
パッケージのADD_FUNCTIONS
プロシージャを使用して、その関数を対応する属性セットに追加する必要があります。例11-3を参照してください。
例11-1に、既存のオブジェクト型を使用して属性セットを作成する方法を示します。この方法ではCREATE_ATTRIBUTE_SET
プロシージャを使用します。
例11-1 既存のオブジェクト型を使用した属性セットの定義
CREATE OR REPLACE TYPE Car4Sale AS OBJECT (Model VARCHAR2(20), Year NUMBER, Price NUMBER, Mileage NUMBER); / BEGIN DBMS_EXPFIL.CREATE_ATTRIBUTE_SET(attr_set => 'Car4Sale', from_type => 'YES'); END; /
CREATE_ATTRIBUTE_SET
プロシージャの詳細は、「CREATE_ATTRIBUTE_SET
プロシージャ」を参照してください。
例11-2に、Car4Sale
属性セットを作成する方法と一度に複数の変数を定義する方法を示します。この方法ではCREATE_ATTRIBUTE_SET
およびADD_ELEMENTARY_ATTRIBUTE
プロシージャを使用します。
例11-2 属性セットの段階的定義
BEGIN DBMS_EXPFIL.CREATE_ATTRIBUTE_SET(attr_set => 'Car4Sale'); DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE( attr_set => 'Car4Sale', attr_name => 'Model', attr_type => 'VARCHAR2(20)'); DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE( attr_set => 'Car4Sale', attr_name => 'Year', attr_type => 'NUMBER', attr_defv1 => '2000'); DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE( attr_set => 'Car4Sale', attr_name => 'Price', attr_type => 'NUMBER'); DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE( attr_set => 'Car4Sale', attr_name => 'Mileage', attr_type => 'NUMBER'); END;/
ADD_ELEMENTARY_ATTRIBUTE
プロシージャの詳細は、「ADD_ELEMENTARY_ATTRIBUTES
プロシージャ」を参照してください。
式でユーザー定義関数を参照する場合は、その関数を対応する属性セットに追加する必要があります。例11-3に、ADD_FUNCTIONS
プロシージャを使用してユーザー定義関数を属性セットに追加する方法を示します。
例11-3 属性セットへのユーザー定義関数の追加
CREATE or REPLACE FUNCTION HorsePower(Model VARCHAR2, Year VARCHAR2) return NUMBER isBEGIN -- Derive HorsePower from other relational tables uisng Model and Year values.-- return 200; END HorsePower; / CREATE or REPLACE FUNCTION CrashTestRating(Model VARCHAR2, Year VARCHAR2) return NUMBER is BEGIN -- Derive CrashTestRating from other relational tables using Model -- -- and Year values. -- return 5; END CrashTestRating; / BEGIN DBMS_EXPFIL.ADD_FUNCTIONS (attr_set => 'Car4Sale', funcs_name => 'HorsePower'); DBMS_EXPFIL.ADD_FUNCTIONS (attr_set => 'Car4Sale', funcs_name => 'CrashTestRating'); END; /
ADD_FUNCTIONS
プロシージャの詳細は、「ADD_FUNCTIONS
プロシージャ」を参照してください。
属性セットを削除するには、DROP_ATTRIBUTE_SET
プロシージャを使用します。詳細は、「DROP_ATTRIBUTE_SET
プロシージャ」を参照してください。
Expressionは仮想データ型です。ユーザー表のVARCHAR2
列に属性セットを割り当てると、Expression列が作成されます。属性セットにより、式セットに使用できる要素属性とユーザー定義関数が決定されます。属性セットを使用すると、同じスキーマの同じ表または他の表にEXPRESSION
データ型の列を複数作成できます。あるスキーマ内の属性セットを別のスキーマの列に関連付けることはできないことに注意してください。
表にVARCHAR2
列を追加するか、またはVARCHAR2
列を含む表を作成します。この操作には、ユーザー表の既存のVARCHAR2
列も使用できます。次の例では、属性セットで使用されるInterest
というVARCHAR2
列を含む表を作成しています。
CREATE TABLE Consumer (CId NUMBER, Zipcode NUMBER, Phone VARCHAR2(12), Interest VARCHAR2(200));
ASSIGN_ATTRIBUTE_SET
プロシージャを使用して、この列に属性セットを割り当てます。次の例では、Consumer
表のInterest
列に属性セットを割り当てています。
BEGIN DBMS_EXPFIL.ASSIGN_ATTRIBUTE_SET ( attr_set => 'Car4Sale', expr_tab => 'Consumer', expr_col => 'Interest'); END; /
ASSIGN_ATTRIBUTE_SET
プロシージャの詳細は、「ASSIGN_ATTRIBUTE_SET
プロシージャ」を参照してください。
図11-2は、Consumer
表で取得される顧客の関心の対象(自動車取引)を示す概念図です。
列から属性セットを削除するには、DBMS_EXPFIL
パッケージのUNASSIGN_ATTRIBUTE_SET
プロシージャを使用します。「UNASSIGN_ATTRIBUTE_SET
プロシージャ」を参照してください。
どの式セットにも使用されていない属性セットを削除するには、DBMS_EXPFIL
パッケージのDROP_ATTRIBUTE_SET
プロシージャを使用します。「DROP_ATTRIBUTE_SET
プロシージャ」を参照してください。
スキーマ間で属性セットをコピーするには、DBMS_EXPFIL
パッケージのCOPY_ATTRIBUTE_SET
プロシージャを使用します。「COPY_ATTRIBUTE_SET
プロシージャ」を参照してください。
式の挿入、更新および削除には、標準SQLを使用します。式を挿入または更新するときには、構文が正しいかどうかがチェックされ、対応する属性セットに指定されている要素属性と関数を使用するように制約が課されます。式が正しくない場合は、エラー・メッセージが戻されます。評価のセマンティクスの詳細は、第11.4項を参照してください。
例11-4に、SQLのINSERT
文を使用してConsumer
表に式(図11-2に示した自動車取引に対する顧客の関心)を挿入する方法を示します。
例11-4 Consumer表への式の挿入
INSERT INTO Consumer VALUES (1, 32611, '917 768 4633', 'Model=''Taurus'' and Price < 15000 and Mileage < 25000'); INSERT INTO Consumer VALUES (2, 03060, '603 983 3464', 'Model=''Mustang'' and Year > 1999 and Price < 20000');
式でユーザー定義関数を参照する場合は、その関数を対応する属性セットに追加する必要があります(例11-3を参照)。例11-5に、ユーザー定義関数HorsePower
を参照する式をConsumer
表に挿入する方法を示します。
例11-5 ユーザー定義関数を参照する式の挿入
INSERT INTO Consumer VALUES (3, 03060, '603 484 7013', 'HorsePower(Model, Year) > 200 and Price < 20000');
式のデータは、SQL*Loaderを使用してExpression列にバルク・ロードできます。バルク・ロードの詳細は、第15.1項を参照してください。
SQL文のWHERE
句にSQLのEVALUATE
演算子を使用して、格納されている式を受け取ったデータ項目と比較します。SQLのEVALUATE
演算子は、データ項目と一致する式については1
を、一致しない式については0
を戻します。Expression列に格納されているNULL値については、SQLのEVALUATE
演算子はNULL
を戻します。
SQLのEVALUATE
演算子は2つの引数を取ります。一方は式が格納されている列の名前、他方は式の比較対照となるデータ項目です。データ項目引数では、Expression列に関連付けられている属性セット内の要素属性すべてについて値を指定する必要があります。NULLは許容値です。データ項目は、文字列形式の名前/値ペアまたはAnyData
インスタンスとして指定できます。
次の例の問合せでは、Interest
列の式がデータ項目についてTRUEと評価されると、Consumer
表の1行が戻されます。
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, <data item>) = 1;
属性セット内のすべての要素属性の値がVARCHAR
、DATE
およびNUMBER
データ型などで格納される、判読可能な表現のできる値で、コンストラクタが文字列形式の場合は、データ項目を文字列形式で表現できます。
演算子の書式
EVALUATE (VARCHAR2, VARCHAR2) returns NUMBER;
例
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, 'Model=>''Mustang'', Year=>2000, Price=>18000, Mileage=>22000' ) = 1;
データ項目の要素属性値のいずれにもコンストラクタが不要な場合は、その属性セットに関連付けられているオブジェクト型の2つのgetVarchar
メソッド(STATIC
メソッドとMEMBER
メソッド)を使用して、データ項目について提供する値リストを文字列形式(名前/値ペア)で指定できます。STATIC
メソッドは、オブジェクト・インスタンスを作成せずにデータ項目を書式設定します。オブジェクト・インスタンスがすでに使用可能になっている場合は、MEMBER
メソッドを使用できます。
STATIC
およびMEMBER
メソッドはオブジェクト型に対して暗黙的に作成され、次の例に示すように使用できます。
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, Car4Sale.getVarchar('Mustang', -- STATIC getVarchar API -- 2000, 18000, 22000) ) = 1; SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, Car4Sale('Mustang', 2000, 18000, 22000).getVarchar() -- MEMBER getVarchar() API -- ) = 1;
AnyData
インスタンスを使用すると、任意のデータ項目を書式設定できます。AnyData
はオラクル社が提供するオブジェクト型であり、すべてのOracleデータ型(オラクル社が提供するデータ型およびユーザー定義のデータ型)のインスタンスを保持できます。詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。
演算子の書式
EVALUATE (VARCHAR2, AnyData) returns NUMBER;
対応する属性セットを取得するオブジェクト型のインスタンスは、AnyData
のconvertObject
メソッドによってAnyData
インスタンスに変換されます。前述の例では、Car4Sale
オブジェクト型のインスタンスをAnyData
に変換して、データ項目をSQLのEVALUATE
演算子に渡すことができます。この方法を次の例に示します。
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, AnyData.convertObject( Car4Sale('Mustang', 2000, 18000, 22000)) ) = 1;
SQLのEVALUATE
演算子の構文の詳細は、第16章のEVALUATEに関する項を参照してください。SQLのEVALUATE
演算子の他の例については、付録Bを参照してください。
式が挿入または更新されると、式フィルタは構文の妥当性をチェックし、式が属性セットに関連付けられている有効な要素属性と関数を参照していることを確認します。SQLのEVALUATE
演算子は、式が格納されている表の所有者の権限を使用して式を評価します。たとえば、式にユーザー定義関数への参照が含まれている場合は、評価時にその関数が表の所有者の権限を使用して実行されます。スキーマ拡張のないスキーマ・オブジェクトへの参照は、表の所有者のスキーマ内で解決されます。
ユーザー定義関数を参照する式は、その関数が変更または削除されると無効になる場合があります。無効な式があると、その式を評価するSQL文が失敗します。このエラーからリカバリするには、削除または変更された関数を元の関数に置き換えます。
式セットの検証にはExpression Validationユーティリティが使用されます。このユーティリティでは、ユーザー定義関数または表に変更があったために、挿入後に無効になっている式が識別されます。無効な式への参照は、例外表に収集されます。例外表が用意されていない場合は、式セット内で無効な最初の式が検出された時点でユーティリティが失敗します。
次のコマンドでは、Consumer
表で検出された無効な式への参照が収集されます。BUILD_EXCEPTIONS_TABLE
プロシージャにより、現行のスキーマに例外表InterestExceptions
が作成されます。VALIDATE_EXPRESSIONS
プロシージャにより式が検証され、無効な式がInterestExceptions
表に格納されます。
BEGIN DBMS_EXPFIL.BUILD_EXCEPTIONS_TABLE (exception_tab => 'InterestExceptions'); DBMS_EXPFIL.VALIDATE_EXPRESSIONS (expr_tab => 'Consumer', expr_col => 'Interest', exception_tab => 'InterestExceptions'); END; /
詳細は、「BUILD_EXCEPTIONS_TABLE
プロシージャ」および「VALIDATE_EXPRESSIONS
プロシージャ」を参照してください。
式を評価するには、その式が格納されている表に対するSELECT
権限が必要です。SQLのEVALUATE
演算子は、式が格納されている表の所有者の権限を使用して式を評価します。問合せを発行するユーザーの権限は考慮されません。
表の所有者は式を挿入、更新および削除できます。他のユーザーの場合は表に対するINSERT
およびUPDATE
権限が必要であり、表の特定のExpression列を変更するには、INSERT
EXPRESSION
およびUPDATE
EXPRESSION
権限が必要です。
次の例では、Consumer
表の所有者がGRANT_PRIVILEGE
プロシージャを使用して、Interest
列に対するEXPRESSION権限をユーザーAndy
に付与しています。
BEGIN DBMS_EXPFIL.GRANT_PRIVILEGE (expr_tab => 'Consumer', expr_col => 'Interest', priv_type => 'INSERT EXPRESSION', to_user => 'Andy'); END; /
権限を取り消すには、REVOKE_PRIVILEGE
プロシージャを使用します。
権限の付与と取消しの詳細は、「GRANT_PRIVILEGE
プロシージャ」および「REVOKE_PRIVILEGE
プロシージャ」を参照してください。
式フィルタのエラー・メッセージ番号は38401〜38600です。各エラー・メッセージについては、『Oracle Databaseエラー・メッセージ』を参照してください。
Oracleエラー・メッセージのドキュメントは、HTML形式でのみ配布されます。Oracle Database JP Documentation Libraryにのみアクセスする場合は、範囲を指定してエラー・メッセージを参照できます。特定の範囲を検索した後、ブラウザの「このページの検索」機能を使用して、特定のメッセージを検索してください。インターネットに接続している場合は、Oracleオンライン・マニュアルのエラー・メッセージ検索機能を使用して特定のエラー・メッセージを検索できます。