- UDF 本体は保護する必要がある。実行可能な関数本体が DB2 により何らかの方法で収集または保護されることはありません。
CREATE FUNCTION ステートメントは、本体のみを指します。関数および関数に依存するデータベース・アプリケーションの保全性を保持するには、関数を含むディレクトリーへのアクセスを管理したり、関数本体そのものを保護することにより、関数本体が誤ってまたは故意に削除されたり置換されることがないようにしてください。
- DB2 は、DB2 と SQL 間のインターフェースにおけるすべてのバッファー (すなわち、すべての SQL 引き数と関数の戻り値) にポインターを渡す。
UDF 引き数をポインターとして必ず定義してください。
- SQL 引き数値はすべてバッファーに入れられる。これは、その値が複写されて UDF に提供されることを意味します。
UDF がその入力パラメーターを変更する場合、その変更は SQL 値または処理に影響を及ぼしませんが、
DB2 が誤動作を起こすことがあります。
- OLE オートメーションでは、入力パラメーターを変更しないでください。そうでないと、メモリー資源が解放されず、メモリー・リークが発生することがあります。
OLE ライブラリー・バージョンの大きなミスマッチがある場合、または OLE ライブラリーの初期化の時に障害が発生した場合、データベース・マネージャーは、SQLCODE -465 (SQLSTATE 58032) と理由コード 34 を戻します
(Failure to initialize OLE library)。
- UDF は、操作中のすべてのプラットフォーム上で必ず再入可能にする。そうすることで、UDF の 1 つのコピーを複数のステートメントおよびアプリケーションで並行して使用できます。
SCRATCHPAD 機能を使用すると、再入可能に課せられた制限の多くを受けずに済みます。
- 現在使用中の関数の本体を修正すると (再コンパイルおよび再リンクなど)、
DB2 はトランザクション内で関数の変更 を行わない。ただし、こうした修正を動的に行うと、その後のトランザクションで使用されるコピーは変更されることがあります。ご使用のオペレーティング・システムによっては、使用中の UDF 本体を変更できないこともあります。このような修正は行わない方がよいでしょう。
- 動的メモリーを UDF に割り振る際は、DB2 に戻る前にそのメモリーを解放する。これは特に NOT FENCED の場合に重要です。ただし、SCRATCHPAD 機能を使用すると、呼び出し間で UDF が必要とする動的メモリーを備えることができます。スクラッチパッドをこの方法で使用する場合は、ステートメントの終わりの処理で割り振られたメモリーを解放できるように、
UDF に対する CREATE FUNCTION で FINAL CALL 属性を指定してください。このようにするのは、UDF を繰り返し使用することにより、システムが時間とともにメモリーを使い果たしてしまうことがあるためです。
このことは、UDF が使用する他のシステム資源にも当てはまります。
- NOT NULL CALL オプションを使用することに意味がある場合は、これを使用する。この CREATE FUNCTION オプションの場合、それぞれの SQL 引き数がヌルであるかどうか、ヌル値を持つ場合に正しく実行されるかどうかを検査する必要がありません。
- UDF からの結果が入力 SQL 引き数以外の要素に左右される場合は、
NOT DETERMINISTIC オプションを使用してください。このオプションを指定すると、
SQL コンパイラーが最適化を実行する際に矛盾した結果を生じないようにすることができます。
- UDF が内部でも外部でも確実に実行されなければならない結果を持つ場合は、
EXTERNAL ACTION オプションを使用する。
EXTERNAL ACTION を使用すると、
SQL コンパイラーが最適化を実行する際に一定の状況での UDF の呼び出しを妨げないようにすることができます。
- FENCED と UNFENCED のどちらを選択すべきかについての考慮事項:
- FENCED UDF
- FENCED UDF は自己プロセスの中で実行されるため、意識的にであれ無意識にであれ、ほとんどの DB2 内部制御およびデータ域にアクセスできません。したがって、データベースには FENCED UDF を選択するのが無難と言えます。ただし、NOT FENCED UDF を選択した場合ほどではないとはいえ、プログラミング・エラーを含む FENCED UDF が DB2 をダウンさせる可能性は依然としてあります。たとえば、戻り変数を何回も上書きするような UDF は、
DB2 を異常終了させる可能性があります。
- UNFENCED UDF
- NOT FENCED UDF は DB2 のエンジン・プロセスに直接ロードされて実行されるため、
NOT FENCED UDF は FENCED UDF よりもパフォーマンスが優れています。
NOT FENCED UDF は、プロセス通信のオーバーヘッドによるパフォーマンスの低下を防ぎます。ただし、NOT FENCED UDF は DB2 内部制御やデータ域にアクセスしたり更新する場合があります。
NOT FENCED UDF を正しく作成しないと、
DB2 をダウンさせる可能性は FENCED UDF の場合よりも高くなります。
これらのことから明らかなとおり、
FENCED と NOT FENCED UDF を両方とも使用する場合は、以下の点に注意する必要があります。
- UDF を確実に正しく作成する必要があります。
- 十分な考慮の下に UDF を設計し、コードを注意深く検討する必要があります。
- 万が一 UDF が正しく作成されていなくても問題が起きない環境
(たとえば、テスト・データベース) で UDF をテストする必要があります。
UDF が原因で起きる異常終了のほとんどは DB2 によって取り込まれ、
-430 SQLCODE が戻されます。これにより、データベースの破壊が防止されます。とはいえ、特定のタイプの UDF の誤動作
(戻り値バッファーを何回も上書きするなど) は、
UDF だけでなく DB2 をもダウンさせる場合があります。可変長データを戻す UDF や、戻り値バッファーに移動させる必要のあるバイト数を計算する UDF を作成する場合には、特に十分な注意を払ってください。
- UDF と EUC コード・セットの使用に関する考慮事項については、
UDF に関する考慮事項を参照してください。
- NOT FENCED を使用した UDF を実行するアプリケーションでは、そのような UDF を最初に呼び出すときに、
UDF_MEM_SZ 構成パラメーターに指示されたメモリー・サイズのブロックが作成されます。その後は、ステートメント単位で、このメモリーのブロックから必要に応じて、
DB2 と NOT FENCED を使用した UDF との間でのやりとりで使用されるメモリーを割り振ったり割り振り解除したりします。
FENCED UDF の場合、異なるメモリーのブロックが同じ仕方で使用されます。プロセス間でそのメモリーが共用されるという点が異なります。
NOT FENCED を使用した UDF と FENCED を使用した UDF の両方を 1 つのアプリケーションが使用する場合は、
UDF_MEM_SZ パラメーターにそれぞれのサイズが指定された、
2 つの別個のメモリー・ブロックが使用されます。この構成パラメーターの詳細については、
管理の手引き を参照してください。
- 以下の状況では、DISALLOW PARALLELISM オプションを使用する。
- スカラー UDF で、UDF が同一コピーの実行に完全に依存する場合。一般に、NOT DETERMINISTIC SCRATCHPAD UDF の場合にこのようになります。
(例については、スクラッチパッドに関する考慮事項で指定された counter UDF を参照してください。)
- 単一の参照のために同時に複数の区画上で UDF を実行したくない場合。
- 表関数を指定している場合。
そうでない場合、ALLOW PARALLELISM (省略時値) を指定する必要があります。