Pular para o conteúdo

Fóruns SQL e PL/SQL Função UTL_ENCODE.BASE64_DECODE Função UTL_ENCODE.BASE64_DECODE

#106581
vanessa 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.