アプリケーション開発の手引き

Java ユーザー定義の関数の作成および使用

Java の UDF は、他の言語の場合と同じように作成して使用できますが、ほんのわずかな違いもあります。 UDF のコーディングが終了した後、CREATE FUNCTION ステートメントを使用して、その UDF をデータベースに登録します。このステートメントを使用して Java UDF を登録することについては、 SQL 解説書 を参照してください。その後ご使用のアプリケーションの SQL でそれを参照することができます。 UDF は FENCED または NOT FENCED を使用することができます。オプションを使用して、UDF の実行の仕方を変えることも可能です。 Java UDF の実行の仕方の変更を参照してください。

UDFsrv.java のサンプルでは、いくつかの Java UDF 方式の本体のサンプルが示されています。 UDFcli.java と UDFclie.sqlj には、関連した CREATE FUNCTION ステートメントとそれらの UDF を呼び出すサンプルがあります。そのサンプルと、それをコンパイルして実行するための README の指示については、 sqllib/samples/java ディレクトリーをご覧ください。

Java UDF のコーディング

一般的に、SQL タイプの引き数 t1t2、および t3、戻りタイプの引き数 t4 を取る UDF を宣言する場合、予期される Java シグニチャーを指定して、Java メソッドとして呼び出されます。

     public void name ( T1 a, T2 b, T3 c, T4 d)  { .....}

ここで、各パラメーターは以下のとおりです。

たとえば、INTEGER を戻し、CHAR(5)、BLOB(10K)、および DATE タイプの引き数を取る sample!test3 を UDF で呼び出す場合、DB2 は、次のシグニチャーを持つ UDF の Java インプリメンテーションを予期します。

     import COM.ibm.db2.app.*;
     public class sample extends UDF {
        public void test3(String arg1, Blob arg2, String arg3,
                          int result) { ... }
     }

表関数を実行する Java UDF は、さらに多くの引き数を必要とします。変数が入力を表すのに比べて、追加の変数は結果行の各列を表しています。たとえば、表関数は次のように宣言されます。

     public void test4(String arg1, int result1,
                       Blob result2, String  result3);

SQL NULL 値は、初期化されていない Java 変数によって示されます。これらの変数は、それらがプリミティブ・タイプの場合、ゼロ値です。それらがオブジェクト・タイプの場合、Java 規則と一致して、Java null です。 SQL NULL に普通のゼロ以外を知らせるには、どんな入力引き数でも関数 isNull を呼び出します。

     { ....                                               
        if (isNull(1)) { /* argument #1 was a SQL NULL */ }
        else           { /* not NULL */ }
     }

上記の例では、引き数番号は 1 から始まります。以下の他の関数のように isNull() 関数は、 COM.ibm.db2.app.UDF クラスから継承されます。

スカラーまたは表 UDF から結果を戻すには、次のように UDF の set() メソッドを使用します。

     { .... 
        set(2, value);
     } 

ここで、'2' は出力引き数の索引で、value は互換タイプのリテラルまたは変数です。引き数の番号は、選択された出力の引き数リストの索引になっています。この項の最初の例で、int result 変数は 4 の索引を持っています。 2 番目の例では、result1result3 は、2 〜 4 を指しています。 UDF が戻す前には設定されていない出力引き数の値は、NULL になります。

UDF とストアード・プロシージャーで使用される C モジュールのように、 Java UDF では Java 標準 I/O ストリーム (System.in、System.out、および System.err) を使用できません。 Java UDF の例は、 sqllib/samples/java ディレクトリーのファイル DB2Udf.java を参照してください。

UDF を実行するのに使用するすべての Java クラス・ファイルは、 sqllib/function ディレクトリーか、対応するサブディレクトリーに常駐する必要があることに注意してください。 Java クラスを置く場所を参照してください。

Java UDF の実行の仕方の変更

一般的に DB2 は照会の結果セットの行ごとに 1 度 UDF を呼び出し、それを何回も繰り返します。 UDF の CREATE FUNCTION ステートメント中で SCRATCHPAD が指定される場合、 UDF の連続した呼び出しには何らかの「連続性」が必要であるので、 Java クラスのインプリメントが呼び出しのたびにではなく、一般的に言ってステートメントの UDF 参照ごとに 1 回インスタンス化されることを DB2 は識別します。通常、それは最初の呼び出しの前にインスタンス化され、その後使用されますが、表関数ではもっと頻繁にインスタンス化されることがあります。詳細については、この次のサブセクションにある NO FINAL CALL 実行モデルを参照してください。

ただし、スカラー関数か表関数のどちらかで、UDF に対して NO SCRATCHPAD が指定されている場合、 UDF の呼び出しごとに新しいインスタンスがインスタンス化されます。

スクラッチパッドは、UDF への呼び出しの合間に情報を保管するために役立つことがあります。 Java および OLE UDF では、呼び出し間の連続性をもたせるためにインスタンス変数を使用するかスクラッチパッドを設定することができますが、 C および C++ UDF では、スクラッチパッドを使用する必要があります。 Java UDF は、COM.ibm.db2.app.UDF で入手可能な getScratchPad() および setScratchPad() 方式を使用してスクラッチパッドにアクセスします。

スクラッチパッドを使用する Java の表関数の場合、 Java の表関数実行モデルの実行モデルによって示されているように、 CREATE FUNCTION ステートメント上で FINAL CALL または NO FINAL CALL オプションを使用して、新しいスクラッチパッド・インスタンスをいつ取得するかを制御してください。

スクラッチパッドによって UDF の呼び出し間の連続性をもたせる機能は、 DB2 スクラッチパッドまたはインスタンス変数のどちらが使用されるかにかかわらず、 CREATE FUNCTION の SCRATCHPAD および NO SCRATCHPAD オプションによって制御されます。

スカラー関数の場合、全ステートメントで同じインスタンスが使用されます。

同じ UDF が複数回参照されても、照会内の Java UDF に対するすべての参照は別個に扱われることに注意してください。これは、OLE、C、および C++ の UDF でも同じです。照会の終わりに、スカラー関数に FINAL CALL オプションを指定すると、オブジェクトの close() メソッドが呼び出されます。表関数の場合、この次のサブセクションに示されているように、 close() メソッドが必ず呼び出されます。 UDF クラスに close() メソッドを定義していない場合、スタブ関数が引き継ぎ、イベントは無視されます。

CREATE FUNCTION ステートメントで Java UDF に ALLOW PARALLEL 文節を指定する場合、 DB2 は並列で UDF を評価するよう選択します。このようになる場合、別の区画に別個の Java オブジェクトを作成できます。各オブジェクトは、行のサブセットを受け取ります。

他の UDF のように、Java UDF では FENCED または NOT FENCED を使用することができます。 NOT FENCED を使用した UDF は、データベース・エンジンのアドレス空間内部で実行されます。 FENCED を使用した UDF は、分割されたプロセスで実行されます。 Java UDF は、その組み込み処理で偶然にアドレス空間を破壊することはありませんが、処理を終了したり、遅くしたりする場合があります。したがって、Java で作成された UDF をデバッグする場合、 FENCED を使用した UDF として実行する必要があります。

COM.ibm.db2.app.UDF インターフェースの詳細は、 COM.ibm.db2.app.UDF を参照してください。このインターフェースには、UDF 内部に組み込める便利な呼び出し (setSQLstategetDBinfo など) が記述されています。

Java の表関数実行モデル

Java で作成された表関数の場合、表関数において重要な特定のステートメントを DB2 が処理する各時点で生じることを理解しておくことは大切です。この情報の詳細は、以下の表で説明されています。それぞれの囲みの下部では、Web から情報を引き出す一般的な表関数に対して、コードを作成して実行できることを示しています。 NO FINAL CALL の場合と FINAL CALL の場合の両方が取り上げられており、どちらも SCRATCHPAD が指定されていると想定しています。
スキャンの時点
NO FINAL CALL
LANGUAGE JAVA
SCRATCHPAD


FINAL CALL
LANGUAGE JAVA
SCRATCHPAD

表関数に対する最初の OPEN の前 呼び出しなし。
  • クラス・コンストラクターが呼び出される (すなわち、新しいスクラッチパッド)。 FIRST 呼び出しで UDF メソッドが呼び出される。
  • コンストラクターが、クラスおよびスクラッチパッド変数を初期化する。メソッドが Web サーバーに接続する。

表関数に対する各 OPEN 時
  • クラス・コンストラクターが呼び出される (すなわち、新しいスクラッチパッド)。 OPEN 呼び出しで UDF メソッドが呼び出される。
  • コンストラクターが、クラスおよびスクラッチパッド変数を初期化する。メソッドが Web サーバーに接続し、Web データのスキャンをオープンする。

  • OPEN 呼び出しで UDF メソッドがオープンされる。
  • メソッドが、必要な Web データのスキャンをオープンする。 (スクラッチパッドに保管されるものに応じて、CLOSE 位置変更後の再オープンを避けることができる。)

新しい行の表関数データに対する各 FETCH 時
  • FETCH 呼び出しで UDF メソッドが呼び出される。
  • メソッドが、次の行のデータまたは EOT を取り出して戻す。

  • FETCH 呼び出しで UDF メソッドが呼び出される。
  • メソッドが、次の行のデータまたは EOT を取り出して戻す。

表関数に対する CLOSE 時
  • CLOSE 呼び出しで UDF メソッドが呼び出される。 close() メソッドがクラスに対してあれば、呼び出される。
  • メソッドがその Web スキャンをクローズし、Web サーバーから切断する。 close() は必要とされない。

  • CLOSE 呼び出しで UDF メソッドが呼び出される。
  • メソッドはスキャンの最上部に位置変更するか、スキャンをクローズする。持続されるどんな状態でも、スクラッチパッドに保管できる。

表関数に対する最後の CLOSE の後 呼び出しなし。
  • FINAL 呼び出しで UDF メソッドが呼び出される。 close() メソッドがクラスに対してあれば、呼び出される。
  • メソッドは Web サーバーから切断する。 close() メソッドは必要とされない。

注:

  1. 「UDF メソッド」とは、UDF をインプリメントする Java クラス・メソッドのことです。これは、CREATE FUNCTION ステートメントの EXTERNAL NAME 文節で識別されるメソッドです。

  2. NO SCRATCHPAD が指定された表関数では、 UDF メソッドの呼び出しはこの表で示されているとおりですが、ユーザーはスクラッチパッドによる連続性を求めないために、クラス・コンストラクターが DB2 によって呼び出され、各呼び出しの前に新しいオブジェクトがインスタンス化されます。 NO SCRATCHPAD が指定された (したがって連続性がない) 表関数が役立つかどうかは不明ですが、それらはサポートされています。

  3. これらのモデルは、C/C++ および OLE の他の UDF 言語と完全に互換性があります。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]