では、逆にLOBデータをファイルに直接出力するにはどうすればいいのでしょうか?
DBMS_LOBパッケージにはLOBデータをファイルに直接出力するプロシージャはなぜか用意されていません。
そこでDBMS_LOBパッケージに代わる方法としてJavaストアドプロシージャを利用する方法のみを説明します。
※ここではBLOBデータを例に説明します。
JavaストアドプロシージャでLOBデータをファイルに直接出力する場合、まず、BLOBデータを読み込んでファイルに出力するメソッドを持つJavaのクラスを用意します。
package orcl; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.FileInputStream; import java.io.OutputStream; import oracle.sql.BLOB; public class UtlLob { public static long downLoadBlob( BLOB blob, String dirName, String fileName ) { File dir = null; File file = null; FileOutputStream fos = null; InputStream ins = null; try { //ディレクトリのFileオブジェクトを生成します。 dir = new File( dirName ); //ディレクトリが存在しない場合、終了します。(失敗) if( !dir.exists() ) { return -1L; } //出力ファイルのFileオブジェクトを生成します。 file = new File( dir, fileName ); //出力ファイルへの出力ストリームを生成します。 fos = new FileOutputStream( file ); //BLOBファイルの入力ストリームを生成します。 ins = blob.getBinaryStream(); //BLOBデータの読み込みに最適なバッファ・サイズを算出し、バッファを生成します。 byte[] buffer = new byte[ blob.getChunkSize() ]; //BLOBデータが空の場合、終了します。 if( ins == null ){ return 0; } else { //バッファ・サイズ単位でBLOBデータを読み込み、出力ファイルに書き込みます。 int length = -1; while( ( length = ins.read( buffer ) ) != -1 ) { fos.write( buffer , 0 , length ); } } return blob.length(); } catch (Exception e) { e.printStackTrace(); return -1L; } finally { try { ins.close(); } catch( Exception ignore ) {} try { fos.close(); } catch( Exception ignore ) {} } } }
このJavaクラスでは、BLOBロケータ、ディレクトリ名、ファイル名を引数として受け取り、指定されたBLOBロケータからBLOBデータを読み込んで指定されたファイルに流し込んでいます。
そして、このJavaクラスをCREATE JAVA文を使ってOracleにロードし、以下のような呼び出しの仕様(コール・スペック)を定義します。
CREATE OR REPLACE FUNCTION UTLLOB_DOWNLOADBLOB_FUNC ( p_blob BLOB, p_dir VARCHAR2, p_file VARCHAR2 ) RETURN NUMBER AS LANGUAGE JAVA NAME 'orcl.UtlLob.downLoadBlob( oracle.sql.BLOB, java.lang.String, java.lang.String ) return long'; /
そして、このJavaクラスがファイルにアクセスできるようJAVAのセキュリティを設定する。
CALL dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '<>', 'read' ) / CALL dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '< >', 'write' ) / CALL dbms_java.grant_permission( 'SCOTT', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '' ) / CALL dbms_java.grant_permission( 'SCOTT', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '' ) /
以上でようやくファイルにアクセスするJavaストアロプロシージャが準備ができたことになります。
このJavaストアドプロシージャを利用して、BLOBデータをファイルに直接出力するには以下のような手順をとります。
DECLARE wk_blob BLOB; --BLOBロケータ wk_length NUMBER(38); --BFILEロケータ BEGIN --BLOBロケータ取得 SELECT COL3 INTO wk_blob FROM TABLEA WHERE COL1 = 1; --ファイルをBLOBロケータにロード wk_length := UTLLOB_DOWNLOADBLOB_FUNC( wk_blob, 'C:\\Temp', 'TEST.DAT' ); END; /
ご覧の通り、Javaストアドプロシージャさえ準備できれば、あとはSELECT文で出力するBLOBデータのBLOBロケータを取得し、Javaストアドプロシージャを呼び出すだけ。
非常に簡単です。
【関連エントリ】
[Oracle] LOBデータの基本的な扱い方 2004/12/03
[Oracle] JDBCによるLOBの操作方法 2004/12/06
[Oracle] LOBデータをファイルから直接登録する方法(その1) 2005/01/25
[Oracle] LOBデータをファイルから直接登録する方法(その2) 2005/01/27
[Oracle] LOBデータをファイルに直接出力する方法 2005/02/01
[Oracle] JavaでLOBデータを読み込む際の最適なバッファサイズは? 2005/02/02
[Oracle] LOB記憶特性 その1(STORAGE IN ROW) 2005/08/23
[Oracle] LOB記憶特性 その2(CHUNK) 2005/08/24