Desenvolvimento

Ξ Deixe um comentário

Oracle – Compactação de Arquivos via PL/SQL

publicado por Paulo Planez

PL-SQL-DeveloperA geração de arquivos texto em sistemas de banco de dados é muito comum é geralmente um dos responsáveis por uma parte significativa do volume de dados gerado pelo sistema.

Uma solução prática para otimizar o espaço ocupado é a compactação dos arquivos, principalmente se o objetivo é enviá-lo via E-Mail, contribuindo, desta forma, com a otimização da banda de comunicação e com o espaço utilizado para armazenamento nos servidores de E-Mail que vão, porventura, receber os arquivos, minimizando, desta forma, a possibilidade de erros no servidor de E-Mail destino devido ao recebimento de arquivos muito grandes.

Até a versão 9i do banco de dados, para implementar tal recurso de forma a funcionar embutido no sistema, era necessário ou criar um procedimento Java no banco de dados ou criar um Shell script que permitisse tal funcionalidade antes de enviar o arquivo.

A partir da versão 10g, a Oracle disponibilizou tal recurso diretamente no PL/SQL, o que simplifica tal processo e ainda pode ser utilizado para compactar qualquer tipo de arquivo, seja ele um arquivo texto ou binário que vai ser enviado por E-Mail ou vai ser carregado num campo LOB do banco de dados.

Esta demonstração tem por objetivo apresentar a uma opção de código que permita utilizar as funções de compactação do PL/SQL.

Taxas de Compactação

O parâmetro p_qualidade define o nível de compactação que será utilizado. Esse parâmetro pode variar de 1 a 9, sendo que 1 apresenta um menor nível de compactação, gerando um arquivo maior e 9 apresenta um maior nível de compactação, gerando um arquivo menor. Pode-se assumir por padrão a execução em nível 9 com objetivo de se obter um arquivo menor.

Código

O código abaixo pode ser executado a partir da versao 10g:

create or replace procedure compacta_arquivo (p_diretorio   in varchar2       --> Diretorio do arquivo

,p_arq_origem in varchar2       --> Arquivo Origem

,p_arq_destino in varchar2       --> Arquivo destino

,p_qualidade   in binary_integer --> Qualidade da compactação

,p_remove_org in varchar2       --> Remove Origem

,p_retorno     out varchar2) IS   --> Retorno de erro

BEGIN

--> Checando os parametros

IF p_diretorio is null THEN

p_retorno := 'Nome do diretorio deve ser informado';

ELSIF p_arq_origem is null THEN

p_retorno := 'Nome do arquivo de origem deve ser informado';

ELSIF p_arq_destino is null THEN

p_retorno := 'Nome do arquivo de destino deve ser informado';

ELSIF p_arq_origem = p_arq_destino THEN

p_retorno := 'Nome do arquivo de origem deve ser deferente do nome do arquivo de destino';

ELSIF UPPER(p_remove_org) not in ('S','N') THEN

p_retorno := 'Opção de Remoção do arquivo de origem deve ser S para sim e N para não';

ELSIF p_qualidade not in (1,2,3,4,5,6,7,8,9) THEN

p_retorno := 'Qualidade deve estar entre 1 (Menor compressao) e 9 (Maior compressao)';

ELSE

DECLARE

--> Variaveis Auxiliares

v_fp         UTL_FILE.file_type;

v_bin_arq     BFILE;

v_arq_compact BLOB;

v_buffer     RAW(32767);

v_init_pos   NUMBER := 1;

v_end_pos     NUMBER;

v_tam_bloco   BINARY_INTEGER := 32767;

BEGIN

--> Atribuindo o nome do arquivo que queremos compactar.

v_bin_arq := BFILENAME (p_diretorio, p_arq_origem);

--> Atribuindo o arquivo.

DBMS_LOB.fileopen (v_bin_arq);

--> Criando um BLOB que vai ser usado para armazenar o arquivo compactado

DBMS_LOB.createtemporary (v_arq_compact, TRUE, DBMS_LOB.session);

--> Compactando o arquivo em uma variavel BLOB

v_arq_compact := UTL_COMPRESS.lz_compress (v_bin_arq, p_qualidade);

--> Posição final do arquivo.

v_end_pos := DBMS_LOB.getlength (v_arq_compact);

v_fp := UTL_FILE.fopen (p_diretorio, p_arq_destino, 'wb',32767);

--> Gravando o arquivo compactado no arquivo de saída.

WHILE v_init_pos < v_end_pos LOOP

--> Lendo o arquivo

DBMS_LOB.read (v_arq_compact, v_tam_bloco, v_init_pos, v_buffer);

UTL_FILE.put_raw (v_fp, v_buffer);

v_init_pos := v_init_pos + v_tam_bloco;

v_buffer := NULL;

END LOOP;

--> Fechando os arquivos e liberando memória.

UTL_FILE.fclose (v_fp);

DBMS_LOB.filecloseall;

DBMS_LOB.freetemporary (v_arq_compact);

--> Removendo o arquivo

IF UPPER(p_remove_org) = 'S' THEN

UTL_FILE.fremove (p_diretorio,p_arq_origem);

END IF;

EXCEPTION

WHEN others THEN

p_retorno := sqlerrm;

END;

END IF;

END compacta_arquivo;

Autor

Graduado em administração com especialização em Finanças, atua desde 1990 com sistemas de informação, em sua maioria focado em sistemas de gestão financeira. ♪ Atuou com sistemas de informação proprietários dos mais variados como Sistemas de gestão de Grãos, Sistemas de controle financeiro para transações eletrônicas e, no segmento de governo, com Sistemas Financeiros e de Sanidade Animal e Vegetal e com sistemas para processamento de Malha Fiscal. ♪ Atua por mais de 15 anos com sistemas de gestão (ERP) cobrindo ciclos operacionais como "Quote to Cash" e "Purchase to Pay" utilizando software da Oracle Corporation (Oracle EBS) em empresas como Globo, Motorola, Alcoa e Dell. ♪ Possui como linha de estudo e pesquisa a economicidade dos sistemas de informação, de modo a extrair destes o máximo de benefícios com o mínimo de recursos.♪ Contato: paulo.planez@gmail.com

Paulo Planez

Comentários

You must be logged in to post a comment.

Busca

Patrocínio

Publicidade



Siga-nos!

Newsletter: Inscreva-se

Para se inscrever em nossa newsletter preencha o formulário.

Artigos Recentes