UDF がスクラッチパッドを使用するかどうかに影響を及ぼす要素は重要であるため、この項を特別に設けて説明します。コーディングに関するその他の考慮事項については、 コーディングに関するその他の考慮事項で説明します。
UDF を再入可能にコーディングすることは重要です。これは主に、UDF に対する参照の多くが関数本体の同一コピーを使用するためです。実際は、このような多くの参照 は異なるステートメントやアプリケーションで行われることさえあります。ただし、関数はある呼び出しから次の呼び出しへの状態を保管する必要があることに注意してください。この関数は次の 2 種類に分類されます。
このような関数の例として、最初の呼び出し時に '1' を戻し、 2 回目以降の呼び出しごとに結果を 1 ずつ増分するという、単純な counter 関数を示します。この関数を使用すると、SELECT 結果の行数を数えることができます。
SELECT counter(), a, b+c, ... FROM tablex WHERE ...
このタイプの関数は NOT DETERMINISTIC (または VARIANT) です。その出力は、単にその SQL 引き数の値に左右されません。この counter 関数については、 例: カウンターで説明します。
このような関数の例として、文書アプリケーションの一部の match 関数があり、この関数は指定した文書が与えられたストリングを含む場合には 'Y' を、それ以外の場合は 'N' を戻します。
SELECT docid, doctitle, docauthor FROM docs WHERE match('myocardial infarction', docid) = 'Y'
このステートメントは、最初の引き数で表される特定のテキスト・ストリング値を含む文書すべてを戻します。 match が行おうとすることは以下のとおりです。
ストリング myocardial infarction を含むすべての文書 ID のリストを、 DB2 の外側で保持される文書アプリケーションから検索します。この検索は処理に負荷がかかる処理であるため、関数はこの処理を 1 回だけ行い、検索したリストをその後の呼び出しでの使用に利用しやすい場所に保管します。
この最初の呼び出しで保管された文書 ID のリストを用いて、 2 番目の引き数として渡された文書 ID がこのリストに含まれているかどうかを確認します。
特にこの match 関数は DETERMINISTIC (または NOT VARIANT) です。その結果は、入力される引き数値のみに左右されます。上記の関数は、ある呼び出しから次の呼び出しへ情報を保管できるかどうかによってパフォーマンス (正確さではない) が左右されます。
上述の 2 つの要求を両方とも満たす方法は、 CREATE FUNCTION ステートメントに SCRATCHPAD を指定することです。
CREATE FUNCTION counter() RETURNS int ... SCRATCHPAD; CREATE FUNCTION match(varchar(200), char(15)) RETURNS char(1) ... SCRATCHPAD;
この SCRATCHPAD キーワードは、スクラッチパッドを関数に割り振って保持するよう DB2 に命じます。 DB2 は、スクラッチパッドを 2 進数のゼロに初期化します。表関数に NO FINAL CALL (省略時) が指定されている場合、 DB2 は各 OPEN 呼び出しの前にスクラッチパッドをリフレッシュします。表関数オプション FINAL CALL を指定する場合、 DB2 はその後、スクラッチパッドの内容を検査したり変更したりしません。スクラッチパッドは各呼び出し時に関数に渡されます。関数は再入可能の場合もありますが、 DB2 は関数の状態に関する情報をスクラッチパッドに保存します。
したがって counter の場合、戻される最後の値はスクラッチパッドに保持されます。また match の例は、スクラッチパッドが十分に大きい場合は文書のリストをスクラッチパッドに保持し、それ以外の場合はリスト用にメモリーを割り振って取得したメモリーのアドレスをスクラッチパッドに保持します。
UDF は、システム資源を獲得する必要があると認識されるため、 FINAL CALL キーワードを使って定義できます。このキーワードは、ステートメントの終わりの処理で UDF を呼び出すよう DB2 に命じるため、 UDF はそのシステム資源を解放することができます。特にスクラッチパッドのサイズは固定であるため、UDF はそれ自体にメモリーを割り振り、最終呼び出しを使ってメモリーを解放する必要があります。たとえば上記の match 関数は、与えられたテキスト・ストリングと一致する文書がどのくらいあるかを予測できません。したがって、match の定義は次のように行うとよいでしょう。
CREATE FUNCTION match(varchar(200), char(15)) RETURNS char(1) ... SCRATCHPAD FINAL CALL;
スクラッチパッドを使用し、副照会で参照される UDF の場合、副照会の合間に、DB2 は最終呼び出しをして (UDF がそのように指定されている場合)、スクラッチパッドの内容をリフレッシュすることを決定する場合があります。 UDF を常に副照会で使用している場合、 FINAL CALL や呼び出しタイプ引き数を使って UDF を定義したり、 2 進数のゼロ 条件を必ず検査することによって、この可能性を回避することができます。
FINAL CALL を指定する場合は、UDF がタイプ FIRST の呼び出しを受け取ることに注意してください。これは、永続リソースを獲得して初期化するために使用することができます。