› Fóruns › SQL e PL/SQL › Função UTL_ENCODE.BASE64_DECODE › Função UTL_ENCODE.BASE64_DECODE
Roberto,
Eu achei no MOS um script que consegue burlar a limitação do utl_encode. Na nota o analista faz a leitura do arquivo no modo texto para não ocorrer o erro (nunca pensaria nisso) rs.
Na nota tem 3 procedures:
- Uma que transforma o arquivo em binario e codificado em base64;
- Uma que decodifica o arquivo < 32k;
- Uma que decodifica o arquivo > 32;
[spoiler]connect system/manager
grant create any directory to scott;
connect scott/tiger
set serveroutput on
create or replace procedure BASE64_ENCODE_FILE( P_DIR varchar2, P_INPUT_FILENAME varchar2, P_ENCODED_FILENAME varchar2)
is
WF_INPUT utl_file.file_type;
WF_ENCODE utl_file.file_type;
WB_EXISTS boolean;
WN_FILE_LENGTH number;
WN_BLOCKSIZE number;
WN_OFFSET number := 0;
WR_BUFFER raw(255);
begin
— Use fgetattr to get the file length.
utl_file.fgetattr(
P_DIR,
P_INPUT_FILENAME,
WB_EXISTS,
WN_FILE_LENGTH,
WN_BLOCKSIZE
);
— Open both files in binary mode
WF_INPUT := utl_file.fopen( P_DIR,P_INPUT_FILENAME,’rb’,255);
WF_ENCODE := utl_file.fopen( P_DIR,P_ENCODED_FILENAME,’wb’,255);
— Process the input file in 57 byte chunks since this results
— in an output of one 76 byte record.
while( WN_OFFSET /tmp/test.doc
create or replace directory TEST_DIR as ‘/tmp’;
exec base64_encode_file (‘TEST_DIR’,’test.doc’,’test.enc’);
— Linux/Unix
host cat /tmp/test.enc
— Windows
— host type c:tmptest.enc[/spoiler]
[spoiler]connect system/manager
grant create any directory to scott;
connect scott/tiger
set serveroutput on
create or replace procedure BASE64_DECODE_COMPLETE( P_DIR varchar2, P_INPUT_FILENAME varchar2, P_DECODED_FILENAME varchar2)
is
WF_INPUT utl_file.file_type;
WF_DECODE utl_file.file_type;
WR_BUFFER raw(32000);
begin
WF_INPUT := utl_file.fopen( P_DIR,P_INPUT_FILENAME,’rb’,32000);
WF_DECODE := utl_file.fopen( P_DIR,P_DECODED_FILENAME,’wb’,32000);
utl_file.get_raw( WF_INPUT, WR_BUFFER, 32000);
utl_file.put_raw( WF_DECODE, utl_encode.base64_decode(WR_BUFFER));
utl_file.fclose( WF_INPUT);
utl_file.fclose( WF_DECODE);
exception
when others then
utl_file.fclose( WF_INPUT);
utl_file.fclose( WF_DECODE);
raise;
end BASE64_DECODE_COMPLETE;
/
create or replace directory TEST_DIR as ‘/tmp’;
exec BASE64_DECODE_COMPLETE (‘TEST_DIR’,’test.enc’,’test.dec’);
— Linux/Unix
host cat /tmp/test.dec
— Windows
— host type c:tmptest.dec[/spoiler]
[spoiler]connect system/manager
grant create any directory to scott;
connect scott/tiger
set serveroutput on
create or replace procedure BASE64_DECODE_FILE( P_DIR varchar2, P_INPUT_FILENAME varchar2, P_DECODED_FILENAME varchar2)
is
WF_INPUT utl_file.file_type;
WF_DECODE utl_file.file_type;
WB_EOF boolean := false;
WR_BUFFER varchar2(255);
begin
— Open the input file in text mode (since Base64 encoded data uses
— ascii characters).
— Open the output file in binary.
WF_INPUT := utl_file.fopen( P_DIR,P_INPUT_FILENAME,’r’);
WF_DECODE := utl_file.fopen( P_DIR,P_DECODED_FILENAME,’wb’,255);
— Loop though all records in the file, decoding the data and
— writing it out to an output file, here you could easily write
— to a BLOB instead.
while( WB_EOF = false) loop
begin
utl_file.get_line( WF_INPUT, WR_BUFFER);
utl_file.put_raw(
WF_DECODE,
utl_encode.base64_decode(utl_raw.cast_to_raw(WR_BUFFER))
);
exception
— No data found is raised when the end of the file is reached
when no_data_found then
WB_EOF := TRUE;
end;
end loop;
utl_file.fclose( WF_INPUT);
utl_file.fclose( WF_DECODE);
exception
when others then
utl_file.fclose( WF_INPUT);
utl_file.fclose( WF_DECODE);
raise;
end BASE64_DECODE_FILE;
/
create or replace directory TEST_DIR as ‘/tmp’;
exec BASE64_DECODE_FILE (‘TEST_DIR’,’test.enc’,’test.dec’);
— Linux/Unix
host cat /tmp/test.dec
— Windows
— host type c:tmptest.dec[/spoiler]
No seu caso acho que só seria necessario pegar toda a chave DOCDATA salvar num arquivo em disco e executar a terceira proc.
Depois disso para carregar no banco você precisaria usar a dbms_lob.