Pular para o conteúdo
  • Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 10 anos, 6 meses atrás por Avatar de vanessa mortago amatovanessa mortago amato.
Visualizando 2 posts - 1 até 2 (de 2 do total)
  • Autor
    Posts
  • #101964
    Avatar de rwarstatrwarstat
    Participante

      No post
      https://www.profissionaloracle.com.br/modules.php?name=Forums&file=viewtopic&t=5632

      Eu 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 mensagem

      ORA-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,
      Roberto

      #106581
      Avatar de vanessa mortago amatovanessa mortago amato
      Participante

        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;
        • [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]

        • Uma que decodifica o arquivo < 32k;
        • [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]

        • 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_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.

      Visualizando 2 posts - 1 até 2 (de 2 do total)
      • Você deve fazer login para responder a este tópico.
      plugins premium WordPress