Click here to load reader
Upload
nikochu
View
116
Download
2
Embed Size (px)
Citation preview
10g Base64 Encoding/DecodingAsked by hsnl_support in Oracle 10.x
Tags: Oracle, Base64, Encoding, Decoding, Lobs
Hi,
I have a range of documents, mainly pdf and word documents stored in a table as a blob. I need to output this blob in XML as base64 encoded data.
I have written a procedure to select the blob from a table, read a chunk of the blob, encode the raw data with utl_encode.base64_encode, convert this to a string and then append it to a clob. The clob is then stored in a table for easy retrieval for xml output.
I then read the clob from the table, read a chunk of the clob, convert the character data back to the raw format, decode the raw data using utl_encode.base64_decode and then append this to a blob. The blob is then stored back in a table so it can be opened.
The problem I encounter is that the blob I have decoded is different at the binary level and does not open properly. I have used SQL Detective to compare the original blobs binary code to the encoded/decoded blobs binary code. I have searched the internet and found a bizarre post that suggests the base64 encoding utility prefers chunks of data that are a multiple of 48 rather than 64. I have successfully encoded and decoded a 3kb pdf file using a chunk size of 1080, however if I use a chunk size of 1024 it does not work. I tired the exact same size on a 29kb file and found it did not work, however with the file size being approx 10x larger I decided to try a 10x larger chunk size of 10080, this worked fine. Neither of the above methods work on a 20kb word document which I find bizarre.
Can anyone help me work out a solution to this problem, is there something fundamental I am missing? The code I am using is below, its quite rough but does work.
set serveroutput on declare l_enc_str varchar2(32767); l_clob clob; l_blob blob; l_blob2 blob; buffer raw(32767); l_len number; l_chunk varchar2(16000); l_offset number := 1; l_chunk_len number; l_raw raw(32767); l_decoded_raw raw(16000);begin dbms_lob.createtemporary(l_clob, true); dbms_lob.createtemporary(l_blob, true); --Encode blob and store as clob. select doc_blob into l_blob from doc_lob where doc_id = 33539; l_len :=dbms_lob.getlength(l_blob); while l_offset < l_len loop if (l_len - l_offset) < 10080 then l_chunk_len := (l_len-l_offset); else l_chunk_len := 10080; end if; dbms_lob.read(l_blob, l_chunk_len, l_offset, buffer); l_raw:=utl_encode.base64_encode(buffer); l_enc_str := utl_raw.cast_to_varchar2(l_raw); dbms_lob.append(l_clob, l_enc_str); l_offset := l_offset + l_chunk_len; end loop; insert into wd_temp_clob_blob (doc_clob) values (l_clob); dbms_lob.freetemporary(l_clob); dbms_lob.createtemporary(l_clob, true); --Decode clode and store as blob select doc_clob into l_clob from wd_temp_clob_blob; l_len := dbms_lob.getlength(l_clob); l_offset:=1; dbms_lob.createtemporary(l_blob2, true); while l_offset < l_len loop if (l_len - l_offset) < 10080then l_chunk_len := (l_len-l_offset); else l_chunk_len := 10080; end if;
l_enc_str := dbms_lob.substr(l_clob,l_chunk_len,l_offset); l_raw:= utl_raw.cast_to_raw(l_enc_str); buffer:= utl_encode.base64_decode(l_raw); dbms_lob.append(l_blob2, buffer); l_offset := l_offset + l_chunk_len; end loop; insert into wd_temp_clob_blob (dob_bloc) values (l_blob2); end;/