5.3 BFILE API
この項では、BFILE
でサポートされる様々な操作について説明します。
BFILENAME
関数または同等のAPIを使用するか、BFILE列に対してSELECT
操作を使用してBFILE
変数を初期化した後は、DBMS_LOB
などのAPIを使用してBFILE
に対して読取り操作を実行できます。BFILE
は読取り専用データ型であることに注意してください。そのため、BFILE
APIを介してBFILE
を使用してアクセスされるオペレーティング・システム・ファイルを更新または削除することはできません。
BFILE
で実行される操作は、次のカテゴリに分かれています。
表5-1 BFILEに対する操作
分類 | 操作 | DBMS_LOB パッケージの関数またはプロシージャの例
|
---|---|---|
健全性チェック | サーバーにBFILE が存在するかどうかをチェック
|
FILEEXISITS |
DIRECTORY オブジェクト名とファイル名を取得
|
FILEGETNAME |
|
ディレクトリまたはファイルが存在するかどうかをチェックせずに、ロケータにBFILE の名前を設定
|
BFILENAME |
|
オープンとクローズ | ファイルをオープン | OPEN |
入力BFILE ロケータを使用してファイルがオープンされたかどうかをチェック
|
ISOPEN |
|
ファイルをクローズ | CLOSE |
|
オープンされているすべてのFILEをクローズします。 | FILECLOSEALL |
|
読取り操作 | BFILE の長さの取得 |
GETLENGTH |
指定されたオフセットからBFILE のデータの読取り
|
READ |
|
SUBSTR を使用して、指定されたオフセット以降のBFILE 値の一部を返す |
SUBSTR |
|
INSTR を使用して、BFILE 内のパターンの一致位置を返す |
INSTR |
|
複数のロケータを含む操作 | BFILE ロケータsrc のBFILE ロケータdst への割当て |
dst := src |
BFILE データのLOBへのロード
|
LOADCLOBFROMFILE、LOADBLOBFROMFILE |
|
2つのBFILE の値の全体または一部を比較
|
COMPARE |
- 健全性チェック
BFILEに対して健全性チェック関数を使用すると、BFILEに関する情報を取得できます。 - BFILEのオープンおよびクローズ
操作を実行する前にBFILE
をOPEN
し、プログラムを終了する前にCLOSE
する必要があります。 - BFILEからの読取り
BFILE
データの長さの読取り、データの一部の読取り、データ全体の読取りなど、様々な読取り操作を実行できます。 - 複数のBFILEロケータの使用
一部のBFILE
操作は、2つのロケータのうちの少なくとも1つがBFILE
ロケータである2つのロケータを受け入れます。BFILEを含む割当ておよび比較操作では、両方のロケータがBFILE
型である必要があります。
親トピック: BFILE
5.3.1 健全性チェック
BFILEに対して健全性チェック関数を使用すると、BFILEに関する情報を取得できます。
BFILENAME()
およびOCILobFileSetName()
関数では、指定したディレクトリおよびパス名が実際に存在するかどうかは検証されないことに注意してください。健全性チェック機能を使用して、BFILE
が存在することを確認し、BFILE
ロケータからディレクトリおよびファイル名を抽出できます。
親トピック: BFILE API
5.3.2 BFILEのオープンおよびクローズ
操作を実行する前にBFILE
をOPEN
し、プログラムを終了する前にCLOSE
する必要があります。
BFILE
ロケータの動作は、ほとんどの従来のプログラミング言語の標準入出力ライブラリの一部として使用可能なファイル記述子と同様です。BFILE
ロケータを定義および初期化し、このロケータによって参照されるファイルをオープンした場合、ファイルをクローズするまでのすべての操作は、ロケータまたはファイルのローカル・コピーを使用して、同じプログラム・ブロック内から実行する必要があることを意味します。BFILE
ロケータ変数は、他のプロシージャ、メンバー・メソッドまたは外部関数コールアウトのパラメータとして使用できます。ただし、ファイルのオープンおよびクローズは、同じネスト・レベルにある、同じプログラム・ブロックから行うことをお薦めします。
アプリケーションに例外が発生した、または異常終了した場合も、オープンしているすべてのBFILE
インスタンスをクローズする必要があります。このような場合にBFILE
インスタンスをクローズしないと、データベースでオープン状態であるとみなされます。このような場合にBFILE
インスタンスがオープン状態のままにならないような例外処理方法を使用していることを確認してください。
DBMS_LOB.FILECLOSEALL
やOCILobFileCloseAll()
などのプロシージャを使用して、オープンしているすべてのBFILE
をまとめてクローズできます。
親トピック: BFILE API
5.3.3 BFILEからの読取り
BFILE
データの長さの読取り、データの一部の読取り、データ全体の読取りなど、様々な読取り操作を実行できます。
大量のBFILE
から読み取る場合は、JDBCまたはOCIでストリーム読取りモードを使用できます。JDBCでは、getBinaryStream()
メソッドを使用してこれを実現できます。OCIでは、次の項で説明される方法に従って実行できます。
OCIでのストリーム読取り
大量のBFILE
データを最も効率よく読み取るには、ストリーム・メカニズムを有効にしたOCILobRead2()
関数をポーリングまたはコールバックを使用します。そのためには、次のようにoffset
パラメータを使用して読取り開始位置を指定します。
ub8 char_amt = 0;
ub8 byte_amt = 0;
ub4 offset = 1000;
OCILobRead2(svchp, errhp, locp, &byte_amt, &char_amt, offset, bufp, bufl,
OCI_ONE_PIECE, 0, 0, 0, 0);
ポーリング・モードを使用した場合は、各OCILobRead2()
コール後にbyte_amt
パラメータの値を調べて、バッファに何バイト読み取られたかを確認してください。これは、バッファがいっぱいになっていない場合があるためです。
コールバックを使用する場合、lenp
パラメータはコールバックへの入力で、バッファ内で格納されたバイト数を示します。バッファの空き領域を確認するため、コールバック処理中にlenp
パラメータを必ずチェックしてください。
量パラメータ
DBMS_LOB.READ
APIをコールする場合、amount
パラメータのサイズはデータのサイズより大きくできます。ただし、このパラメータはバッファのサイズ以下にする必要があります。PL/SQLで、バッファサイズの上限は32Kです。OCILobRead2()
関数をコールする場合は、byte_amt
パラメータに値UB8MAXVAL
を渡して、BFILE
の終わりまで読み取ることができます。
親トピック: BFILE API
5.3.4 複数のBFILEロケータの操作
BFILE
操作は、2つのロケータのうちの少なくとも1つがBFILE
ロケータである2つのロケータを受け入れます。BFILEを含む割当ておよび比較操作では、両方のロケータがBFILE
型である必要があります。
LOBへのBFILE
データのロードには、次の各項で説明する特別な考慮事項が含まれます。
LOBへのBFILEデータのロード
PLSQLでは、DBMS_LOB.LOADBLOBFROMFILE
およびDBMS_LOB.LOADCLOBFROMFILE
が設定されている場合、DBMS_LOB.LOADFROMFILE
プロシージャは非推奨になります。具体的には、DBMS_LOB.LOADCLOBFROMFILE
プロシージャを使用してCLOB
またはNCLOB
インスタンスをロードすると、文字セット変換が実行されます。
BFILEデータのロード量の指定
次の表に示す関数に対する量パラメータでは、次のいずれかの値を渡す必要があります。
- ロードする
BFILE
の実際のサイズ(バイト単位)以下の量。 - 最大許容LOBサイズ(バイトで表されます)。この値を渡すと、
BFILE
全体がロードされます。この方法を使用すると、ロード前にBFILE
のサイズを確認せずにBFILE
全体をロードできます。最大許容LOBサイズを取得するには、次の表で説明する方法を使用します。
表5-2 ファイルからのロード操作用の最大LOBサイズ
環境 | 関数 | 最大LOBサイズを渡すために取得する値 |
---|---|---|
DBMS_LOB |
DBMS_LOB.LOADBLOBFROMFILE |
DBMS_LOB.LOBMAXSIZE |
DBMS_LOB |
DBMS_LOB.LOADCLOBFROMFILE |
DBMS_LOB.LOBMAXSIZE |
OCI |
OCILobLoadFromFile2() |
UB8MAXVAL |
OCI |
OCILobLoadFromFile() (LOBのサイズが4GB未満の場合)
|
UB4MAXVAL |
BFILEデータを使用したBLOBのロード
DBMS_LOB.LOADBLOBFROMFILE
プロシージャは、BLOB
にBFILE
のデータをロードします。これを使用して、任意の永続または一時BLOB
インスタンスにデータをロードできます。このプロシージャは、BLOBの新しいソースおよび宛先オフセットを戻し、ループで使用するときに後続のコールに渡すことができます。
CLOBへのBFILEデータのロード
DBMS_LOB.LOADCLOBFROMFILE
プロシージャは、CLOB
またはNCLOB
にBFILE
の文字データをロードします。これを使用すると、永続または一時的なCLOB
またはNCLOB
インスタンスにデータをロードできます。このプロシージャのコール時にBFILE
文字セットIDを指定し、キャラクタ・セットがBFILE
データの文字セットから宛先のCLOB
またはNCLOB
文字セットに正しく変換されていることを確認できます。このプロシージャは、CLOBまたはNCLOBの新しいソースおよび宛先オフセットを戻し、ループで使用する場合は後続のコールに渡せます。
default csid(0)
の使用方法。BFILE
に対してgetlength
をコールせずに、ファイル全体をロードする方法。- 戻されたオフセット値を使用して、実際にロードしたデータ量を計算する方法。
この例では、ad_source
がUTF8
文字セット・フォーマットのBFILE
で、データベースの文字セットがUTF8
であることを想定しています。
CREATE OR REPLACE PROCEDURE loadCLOB1_proc (dst_loc IN OUT CLOB) IS
src_loc BFILE := BFILENAME('MEDIA_DIR','monitor_3060.txt') ;
amt NUMBER := DBMS_LOB.LOBMAXSIZE;
src_offset NUMBER := 1 ;
dst_offset NUMBER := 1 ;
lang_ctx NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
warning NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE('------------ LOB LOADCLOBFORMFILE EXAMPLE ------------');
DBMS_LOB.FILEOPEN(src_loc, DBMS_LOB.FILE_READONLY);
/* The default_csid can be used when the BFILE encoding is in the same charset
* as the destination CLOB/NCLOB charset
*/
DBMS_LOB.LOADCLOBFROMFILE(dst_loc,src_loc, amt, dst_offset, src_offset,
DBMS_LOB.DEFAULT_CSID, lang_ctx,warning) ;
DBMS_OUTPUT.PUT_LINE(' Amount specified ' || amt ) ;
DBMS_OUTPUT.PUT_LINE(' Number of bytes read from source: ' || (src_offset-1));
DBMS_OUTPUT.PUT_LINE(' Number of characters written to destination: ' ||(dst_offset-1) );
IF (warning = DBMS_LOB.WARN_INCONVERTIBLE_CHAR)
THEN
DBMS_OUTPUT.PUT_LINE('Warning: Inconvertible character');
END IF;
DBMS_LOB.FILECLOSEALL() ;
END;
/
NLS_CHARSET_ID
ファンクションを使用して、文字セット名から文字セットIDを取得する方法。- 戻されたオフセット値および言語コンテキスト
lang_ctx
を使用して、1つのBFILE
から複数のLOBにストリームのデータをロードする方法。 - 警告メッセージの読取り方法
この例では、ad_file_ext_01
がJA16TSTSET
フォーマットのBFILE
で、データベースの各国語文字セットがAL16UTF16
であることを想定しています。
CREATE OR REPLACE PROCEDURE loadCLOB2_proc (dst_loc1 IN OUT NCLOB,dst_loc2 IN OUT NCLOB) IS
src_loc BFILE := BFILENAME('MEDIA_DIR','monitor_3060.txt');
amt NUMBER := 100;
src_offset NUMBER := 1;
dst_offset NUMBER := 1;
src_osin NUMBER;
cs_id NUMBER := NLS_CHARSET_ID('JA16TSTSET'); /* 998 */
lang_ctx NUMBER := dbms_lob.default_lang_ctx;
warning NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE('------------ LOB LOADCLOBFORMFILE EXAMPLE ------------');
DBMS_LOB.FILEOPEN(src_loc, DBMS_LOB.FILE_READONLY);
DBMS_OUTPUT.PUT_LINE(' BFILE csid is ' || cs_id) ;
/* Load the first 1KB of the BFILE into dst_loc1 */
DBMS_OUTPUT.PUT_LINE(' ----------------------------' ) ;
DBMS_OUTPUT.PUT_LINE(' First load ' ) ;
DBMS_OUTPUT.PUT_LINE(' ----------------------------' ) ;
DBMS_LOB.LOADCLOBFROMFILE(dst_loc1, src_loc, amt, dst_offset, src_offset,
cs_id, lang_ctx, warning);
/* the number bytes read may or may not be 1k */
DBMS_OUTPUT.PUT_LINE(' Amount specified ' || amt ) ;
DBMS_OUTPUT.PUT_LINE(' Number of bytes read from source: ' ||
(src_offset-1));
DBMS_OUTPUT.PUT_LINE(' Number of characters written to destination: ' ||
(dst_offset-1) );
if (warning = dbms_lob.warn_inconvertible_char)
then
DBMS_OUTPUT.PUT_LINE('Warning: Inconvertible character');
end if;
/* load the next 1KB of the BFILE into the dst_loc2 */
DBMS_OUTPUT.PUT_LINE(' ----------------------------' ) ;
DBMS_OUTPUT.PUT_LINE(' Second load ' ) ;
DBMS_OUTPUT.PUT_LINE(' ----------------------------' ) ;
/* Notice we are using the src_offset and lang_ctx returned from the previous
* load. We do not use value 1001 as the src_offset here because sometimes the
* actual amount read may not be the same as the amount specified.
*/
src_osin := src_offset;
dst_offset := 1;
DBMS_LOB.LOADCLOBFROMFILE(dst_loc2, src_loc, amt, dst_offset, src_offset,
cs_id, lang_ctx, warning);
DBMS_OUTPUT.PUT_LINE(' Number of bytes read from source: ' ||
(src_offset-src_osin) );
DBMS_OUTPUT.PUT_LINE(' Number of characters written to destination: ' ||
(dst_offset-1) );
if (warning = DBMS_LOB.WARN_INCONVERTIBLE_CHAR)
then
DBMS_OUTPUT.PUT_LINE('Warning: Inconvertible character');
end if;
DBMS_LOB.FILECLOSEALL() ;
END;
/
親トピック: BFILE API