AS LOCATOR は、任意の LOB データ・タイプや、 CREATE FUNCTION ステートメントの LOB タイプに基づいた任意の特殊タイプに追加できます。これは、渡されるパラメーターと戻される結果の両方に適用されます。この場合、DB2 は次のことを行います。
ロケーター値は修正しないでください。修正すると値は使用できなくなり、API がエラーを戻します。
これらの特殊 API は、NOT FENCED として定義された UDF でのみ使用できます。これは、バグのある UDF によってシステムが損害を受ける可能性があるので、テスト段階にある UDF を実動データベース上で使用してはならない、ということを暗に示しています。テスト・データベースでの作業であれば、 UDF にバグがあったとしても、永続する損害は生じません。 UDF にエラーがないことが分かったら、実動データベースに適用できます。
次の API は、sqludf.h UDF インクルード・ファイルに含まれている関数プロトタイプを使って定義されています。
extern int sqludf_length( sqludf_locator* udfloc_p, /* in: User-supplied LOB locator value */ sqlint32* Return_len_p /* out: Return the length of the LOB value */ ); extern int sqludf_substr( sqludf_locator* udfloc_p, /* in: User-supplied LOB locator value */ sqlint32 start, /* in: Substring start value (starts at 1) */ sqlint32 length, /* in: Get this many bytes */ unsigned char* buffer_p, /* in: Read into this buffer */ sqlint32* Return_len_p /* out: Return the length of the LOB value */ ); extern int sqludf_append( sqludf_locator* udfloc_p, /* in: User-supplied LOB locator value */ unsigned char* buffer_p, /* in: User's data buffer */ sqlint32 length, /* in: Length of data to be appended */ sqlint32* Return_len_p /* out: Return the length of the LOB value */ ); extern int sqludf_create_locator( int loc_type, /* in: BLOB, CLOB or DBCLOB? */ sqludf_locator** Loc_p /* out: Return a ptr to a new locator */ ); extern int sqludf_free_locator( sqludf_locator* loc_p /* in: User-supplied LOB locator value */ );
次に、これらの API がどのように動作するかを説明します。データ・タイプに関係なく、すべての長さはバイト数で、 1 バイト文字や 2 バイト文字単位ではないことに注意してください。
戻りコード。各 API ごとに DB2 によって UDF に戻される戻りコードは以下のとおりです。
LOB ロケーターが与えられると、そのロケーターが表す LOB 値の長さを戻します。該当するロケーターは通常、DB2 によって UDF に渡されるロケーターですが、 UDF が (sqludf_append() を使って) 作成中の結果値を表すロケーターである場合もあります。
通常、UDF はロケーターを受け取ったときに LOB 値の長さを調べる場合に、この API を使用します。
戻りコード 3 は以下のことを示します。
LOB ロケーター、LOB 内の開始位置、要求する長さ、およびバッファーへのポインターが与えられると、この API は、バイトをバッファーに入れ、移動できたバイトの数を戻します。 (当然ながら、UDF は、要求する長さに十分足りるバッファーを提供しなければなりません。) 移動されるバイトの数は、要求した長さよりも短いことがあります。たとえば、位置 101 から始まる 50 バイトを要求したときに LOB 値の長さが 120 だけである場合、この API は 20 バイトのみを移動します。
通常、UDF は、ロケーターを受け取ったときに LOB 値のバイトを調べる場合、この API を使用します。
戻りコード 3 は以下のことを示します。
LOB ロケーター、データが入っているデータ・バッファーへのポインター、および追加されるデータの長さが与えられると、この API は LOB 値の終わりにデータを追加して、追加されたバイトの長さを戻します。 (追加される長さが、追加するために与えられた長さと常に等しいことに注意してください。全体の長さを追加できない場合、 sqludf_append() の呼び出しは、戻りコード other を出して失敗します。)
通常、UDF は、結果が AS LOCATOR で定義され、 sqludf_create_locator() を使ってロケーターを作成した後で結果値を 1 つずつ追加して作成するときに、この API を使用します。この場合、作成処理を完了した後、UDF は結果引き数が指す場所にロケーターを移動します。
この API を使って入力ロケーターに追加することもできます。これは、UDF 内で値を操作する際に最大の柔軟性が得られるという点では便利ですが、 SQL ステートメントの LOB 値やデータベースに保管されている LOB 値には影響を及ぼしません。
この API を使用して、かなり大きい LOB 値であっても少しずつ作成することができます。結果が作成されるまでにかなりの追加をする場合、このタスクのパフォーマンスは以下を行うことによって改善することができます。
sqludf_append() API によって大きな LOB 値を大量に作成する SQL アプリケーションは、使用可能なディスク・スペース容量の制限によってエラーを検出することがあります。これらのエラーが発生する可能性は、以下を行うことによって削減することができます。
戻りコード 3 は以下のことを示します。
データ・タイプ (たとえば SQL_TYP_CLOB) が与えられると、ロケーターを作成します。 (データ・タイプ値は、外部アプリケーション・ヘッダー・ファイル sql.h で定義されています。)
通常、UDF は、UDF 結果が AS LOCATOR を指定して定義されており、 sqludf_append() を使って結果値を作成する場合に、この API を使用します。他には、LOB 値を内部的に操作する場合にこの API を使用します。
戻りコード 3 は以下のことを示します。
渡されたロケーターを解放します。
この API を使用して、 sqludf_create_locator() API を使用して作成されて内部操作でしか使用されなかったロケーターを解放します。 UDF に渡されたロケーターは必ずしも解放する必要はありません。 sqludf_create_locator() を介して UDF によって作成されたロケーターが、出力として UDF の外に渡される場合、それは必ずしも解放する必要はありません。
戻りコード 3 は以下のことを示します。
これらの API の使用には、以下の注意事項が適用されます。
注:
ここでは、実際に起こりうる、LOB ロケーターの有用性を示すシナリオを簡単に要約します。次の 4 つのシナリオは、ロケーターの使用のあらましで、必要な空間を減らして効率を上げる方法を示します。
UDF は、sqludf_substr() を使って LOB 値の最初の部分を調べ、そこで見つかったサイズ変数に基づき、再び sqludf_substr() を使って 1 億バイトの LOB 値の中から自由に数バイトを読み取ることができます。
この UDF は、LOB 値内で何かを検索しています。大抵の場合は初めの方で見つかりますが、ときには 1 億バイトの値全体を走査しなければならないこともあります。 UDF は、sqludf_length() を使ってこの特定の値のサイズを検出し、 sqludf_substr() への呼び出しをループに入れることによって、この値を 1 000 バイトずつ調べます。このとき、開始位置として変数を使用し、ループをまわるたびに変数を 1 000 ずつ増やします。検索しているものが見つかるまで、この方法を続行します。
この UDF は入力として 2 つの LOB ロケーターを取り、出力として 1 つの LOB ロケーターを戻します。まず、2 つの入力を検査して比較し、受け取ったバイトを sqludf_substr() を使って読み取り、何らかのアルゴリズムに基づいて 2 つのうちのどちらを選択するかを決定します。決定したら、選択した方の入力のロケーターを UDF 結果引き数で示されたバッファーに複写して、終了します。
UDF に、LOB 値と、たいていは前もって想定された処理方法を示す他の引き数が渡されます。 UDF は、出力としてロケーターを作成し、出力値を順番に作成します。このとき、結果値のほとんどは、他の入力引き数に含まれる指示に基づき、 sqludf_substr() を使って読み取る入力 LOB の異なる部分から取ります。この処理が終わると、最後に結果ロケーターを UDF 結果引き数が指すバッファーに複写し、終了します。