連載
» 2005年08月26日 00時00分 公開

PL/SQLでBLOBデータを自由自在に入出力SQLクリニック(7)(3/3 ページ)

[林優,株式会社インサイトテクノロジー]
前のページへ 1|2|3       

BLOBデータを出力するサンプル

 次に、Oracleに格納されているデータファイルをPL/SQLでOS上のファイルに書き出すサンプルを作ってみます。

1 set serveroutput on
2 declare
3         v_blob_locater          blob;
4         v_offset                integer := 1;
5         v_buffer                long raw;
6         
7         v_file_buffer_size      integer := 32000;
8         v_amount                integer := 32000;
9
10        v_totalsize             integer;
11        v_filetype              utl_file.file_type;
12        v_filename              varchar2(1000) := 'maguro_out.jpg';
13        v_openmode              varchar2(2) := 'wb';
14         
15 begin
16         select data into v_blob_locater 
                       from test_blob_data where id = 1;
17         v_totalsize := dbms_lob.getlength(v_blob_locater);
18         v_filetype := utl_file.fopen(
                       'LOB_DATA_PATH', 
                        v_filename, 
                        v_openmode, 
                        19 v_file_buffer_size
          );
20
21         while v_offset < v_totalsize loop
22                 if v_offset + v_amount > v_totalsize then
23                         v_amount := v_totalsize - v_offset + 1;
24                 end if;
25                 dbms_lob.read(
26                         v_blob_locater,
27                         v_amount,
28                         v_offset,
29                         v_buffer
30                 );
31
32                 utl_file.put_raw(
33                         v_filetype,
34                         v_buffer,
35                         true
36                 );
37                 v_offset := v_offset + v_amount;
38                 dbms_output.put_line ( 'Offset : ' || v_offset );
39         end loop;
40 
41         utl_file.fflush(v_filetype);
42         utl_file.fclose(v_filetype);
43
44 end;
45 / 
リスト2 BLOBデータを出力するPL/SQLサンプル
(表示の都合で改行している個所があります。コードはlist7_2から参照できます)

 前ページのデータ格納で使用したテーブルとデータを使用しています。では、こちらも順を追って解説します。

BLOBデータを出力するサンプルの解説

5行目

 バッファデータをLONG RAW型で宣言しています。バイナリデータですので、RAWデータが使用されています。

7行目

 UTL_FILE.PUT_RAWサブプログラムのバッファサイズの上限は32767bytesです。そのため、今回は32000bytesを上限として、書き出しを行います。

11行目

 utl_file.file_type型の変数を定義します。これが出力するファイルのファイルIDとなります。

13行目

 openmodeには、バイナリデータを書き込むwbを指定します。

16行目

 SELECT文で、ID=1のレコードのBLOBデータを抽出しています。検索されたBLOBロケータをv_blob_locaterに代入し、この後のDBMS_LOB.READで使用します。

17行目

 UTL_FILE.PUT_RAWの制限(32767bytesまでのバッファ)をクリアするために、ループしながらLOBの読み込みとファイルへの書き出しを行います。そのため、Max値としてDBMS_LOB.GETLENGTHで、対象LOBデータのMAXサイズを取得します。

18行目

 UTL_FILE.FOPENでファイルをオープンします。UTL_FILE.FOPENの引数は以下のとおりです。

location IN VARCHAR2
 VARCHAR2となっていますが、Create Directoryで作成したDirectoryオブジェクトを指定することも可能です。ここに指定するPATHは、今回のようにCreate Directoryで作成したDirectoryオブジェクトか、初期化パラメータファイルのutl_file_dirで指定されたPATHのみが使用できます。

filename IN VARCHAR2
 出力するファイル名を指定します。

open_mode IN VARCHAR2
 オープンするモードを指定します。

r…テキストの読込み
w…テキストの書込み
a…テキストの追加
rb…バイト(バイナリ)の読込み
wb…バイト(バイナリ)の書込み
ab…バイト(バイナリ)の追加

max_linesize IN BINARY_INTEGER
 BLOBデータの場合は、バイナリデータであるため最大バッファの値ということになります。最大は32767bytesで、デフォルトでは1000bytesになります。

20行目

 v_amountで指定したbytes分ずつLOBの読み取りとファイルへの書き出しをv_totalsizeまで繰り返し行います。21〜23行目では、v_totalsizeを上回ってしまった場合(データのEOF)に、全体から書き込みを行ったサイズを引いて、残りのamountを算出します。また、offsetは1からスタートしているので、最後の1byteを取得するために1を加算しています。

24行目

 SELECT文で取得したBLOBロケータから実データを読み込みます。DBMS_LOB.READの引数は以下のとおりです。

lob_loc IN BLOB
 読み込み対象のBLOBロケータを指定します。

amount IN OUT NOCOPY BINARY_INTEGER
 読み取りサイズを指定します。offsetで指定した開始位置からamount分のデータを読み込みます。

offset IN INTEGER
 読み取り開始位置を指定します。

buffer OUT RAW
 読み取ったデータを格納するバッファを指定します。

 サンプルの例では、BLOBロケータで示されるBLOBデータをv_offset目からv_amount分読み込んで、v_buffer変数に格納という指定になります。

31行目

 24行目で取得したBLOBデータをUTL_FILE.PUT_RAWサブプログラムでファイルに書き出しています。3番目の引数(autoflash)をtrueに設定することで、書き込みバッファを自動的にフラッシュし物理ディスクに記録してくれます。


 以上でBLOBデータの格納と出力を行うことができます。実際の現場ではPL/SQLのみで行うケースは、あまりないかもしれませんが開発機などでBLOBの動作を確認したいときなどにすぐ使えると思いますので、ぜひマスターしてくださいね。(次回に続く)

筆者紹介

株式会社インサイトテクノロジー

Oracleに特化した製品開発、コンサルティングを手掛けるエンジニア集団。大道隆久は緊迫したトラブル現場でも常に冷静沈着であり、スマートに解決へと導いていくシステムコンサルタント。



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。