Created
December 22, 2011 08:17
-
-
Save seraphy/1509490 to your computer and use it in GitHub Desktop.
Oracleの一時LOBを、32KBを超えるバイナリデータ用の一時バッファとして使い、それを区切りのよい単位てBASE64でファイル出力するサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
-- 32Kを超えるバイナリデータをBLOB上に作成する | |
procedure generate_message(lb in out nocopy blob, cnt number) is | |
mes varchar2(4096); | |
rd raw(4096); | |
begin | |
for idx in 1..cnt | |
loop | |
mes := 'メッセージNo. ' || to_char(idx) || chr(10); | |
rd := UTL_I18N.STRING_TO_RAW(mes, 'UTF8'); | |
DBMS_LOB.WRITEAPPEND(lb, UTL_RAW.LENGTH(rd), rd); | |
end loop; | |
end; | |
-- BLOBから48バイトづつ取り出しBASE64に変換し | |
-- 1行64文字でファイルに出力する | |
procedure write_file(lb in out nocopy blob) is | |
vHandle UTL_FILE.FILE_TYPE; | |
amount BINARY_INTEGER := 768; -- 48の倍数 (3と4で割り切れる数の1行単位); | |
pos pls_integer := 1; | |
blob_len pls_integer := dbms_lob.getlength(lb); | |
buf raw(1152); -- BASE64変換後のサイズ(読み込みバイトの1.5倍) | |
begin | |
vHANDLE := UTL_FILE.FOPEN('TEMP_DIR', 'data.txt', 'wb'); | |
-- 48バイトで端数なしで出力できるBASE64の1行の最大桁. | |
-- その倍数単位のバッファでループを回す. | |
WHILE pos < blob_len | |
LOOP | |
DBMS_LOB.READ(lb, amount, pos, buf); | |
UTL_FILE.PUT_RAW( | |
vHANDLE, | |
UTL_ENCODE.BASE64_ENCODE(buf), -- 自動で改行コードが入る | |
TRUE | |
); | |
buf := NULL; | |
pos := pos + amount; | |
END LOOP; | |
UTL_FILE.FCLOSE(vHANDLE); | |
EXCEPTION WHEN OTHERS THEN | |
UTL_FILE.FCLOSE(vHANDLE); | |
RAISE; | |
end; | |
begin | |
declare | |
lb blob; | |
st timestamp; | |
en timestamp; | |
begin | |
-- 一時BLOBを構築、寿命を呼び出しスコープに設定 | |
DBMS_LOB.CREATETEMPORARY(lb, TRUE, DBMS_LOB.CALL); | |
-- 32Kを超えるデータを作成 | |
generate_message(lb, 23456); | |
-- 長さの検証 | |
st := systimestamp; | |
dbms_output.put_line('len=' || dbms_lob.getlength(lb) || '/' || st); | |
-- ファイルにBASE64として書き出し | |
write_file(lb); | |
en := systimestamp; | |
dbms_output.put_line(en || '/span=' || (en - st)); | |
-- 一時LOBの破棄 | |
DBMS_LOB.FREETEMPORARY(lb); | |
end; | |
end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment