- Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 10 anos, 6 meses atrás por vanessa mortago amato.
-
AutorPosts
-
1 de dezembro de 2011 às 2:57 pm #101964rwarstatParticipante
No post
https://www.profissionaloracle.com.br/modules.php?name=Forums&file=viewtopic&t=5632Eu estava com dificuldade para ler um arquivo XML que havia sido carregado no banco. Depois disso feito a minha dúvida é a seguinte: a chave DocData do arquivo possui um arquivo PDF codificado em base 64. Preciso pegar esse conteúdo, decodificá-lo e gravar em um BLOB no banco.
Nesse ponto aparecem 2 problemas:
– ao ler a chave DocData aparece a mensagemORA-01706: o valor do resultado da função do usuário era grande demais
– a função UTL_ENCODE.BASE64_DECODE aceita como parâmetro um raw e gera um raw. Mas o raw é limitado a 32.767 bytes.
A questão do dia é, como conseguir pegar esse valor e transfomrar em um BLOB para gravar no banco?
Abraço,
Roberto2 de maio de 2014 às 10:57 pm #106581vanessa mortago amatoParticipanteRoberto,
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)
isWF_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)
isWF_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)
isWF_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.
-
AutorPosts
- Você deve fazer login para responder a este tópico.