Por:
Edivaldo Vicente dos Santos & Saul Chagas Schead dos Santos
I – Introdução:
Apesar do processo de informatização que a maior parte das organizações vem sofrendo nos últimos anos, tanto da iniciativa privada como as governamentais, a produção e o fluxo de documentos em papel ainda se encontram em crescimento constante. Esse fluxo de documentos, hoje questionado por seu custo ecológico, baixo nível de gerenciamento das informações e fragilidade no armazenamento, necessita de um gerenciamento adequado que diminua o volume e o fluxo de papel, possua uma melhor forma de armazenamento físico e disponibilização de conteúdo, além de integração com mecanismos de indexação mais eficientes. Sabemos, já há algum tempo, que dispomos de todas essas características com os dados estruturados armazenados em Sistemas de Gerenciamento de Bases de Dados(SGBD), e mais recentemente com os dados não estruturados armazenados nesses sistemas. A pergunta que colocamos é a seguinte: Então porque não armazenar e distribuir esses documentos, gerados ou digitalizados, em padrão digital de documentos, gerenciados por SGBDs ?
Existem várias disciplinas que tratam da gestão de documentos: Arquivologia, GED (Gerenciamento Eletrônico de Documentos), ou EDMS (Engineering Document Management System) e mais recentemente ECM (Enterprise Content Mangement), elas propossionam diversos meios para tratar o passivo em papel, seu processo de digitalização, armazenamento e disponibilização, além das políticas de segurança, fidedignidade e de autenticidade, dos documentos digitalizados, e já indicam os caminhos a serem tomados para a mudança do paradigma de papel, para a produção e gerenciamento eletrônico de documento, além de proporcionar tanto um ambiente de alta disponibilização de documentos e informações quanto seguro.
Esse pequeno preâmbulo, que serve de motivação para esse texto, já demonstra a importância e atualidade do tema. Os sistemas dessa natureza devem atender a diversos requisitos técnicos e legais, que devem ser observados e que hoje podem ser alcançados com mais facilidade fazendo uso mais intensivo da tecnologia dos SGBDs.
Os fabricantes de SGBDs há vários anos disponibilizam em seus produtos recursos visando a dar suporte a dados não estruturados e a Grandes Objetos(LOBS) – textos, fotos, vídeos, etc...porém, infelizmente, muito do desenvolvimento nessa área não faz uso desses recursos, que hoje implementam performance, segurança e simplicidade de manutenção. A utilização dessas novas tecnologias também poderiam evitar problemas, que apesar de todo esforço dos desenvolvedores, acabam implicando em problemas para a organização e de seus usuários. Nesse sentido vamos realizar uma descrição geral do ambiente hoje utilizado e demonstraremos a implementação dos recursos mais recentes, testados em sua confiabilidade, para tanto usaremos para fins de ilustração o SGBD Oracle, mas recursos similares também estão disponíveis em outros SGBDs atuais.
II – Conceitos Preliminares Utilizados:
A preservação digital de documento,como já colocamos, trazem grandes vantagens como o uso mais eficiente dos mesmos, maior disponibilidade, possibilidade de economia de papel, espaço físico e tempo para disponibilização das informações, integração de diversas ferramentas, auditoria e controle. Para isso o projeto como um todo deve ser muito bem estruturado e a infraestrutura bem definida.
Partindo das normas técnicas vigentes que tratam de gerenciamento de documentos, temos principalmente três formatos:
1-Open Document Format (ODF) – ABNT ISO/IEC 26300: Sua utilização é para criação de documentos que poderão ser editados antes de serem concluídos para armazenamento final.
2-Portable Document Format(PDF/A) – ABNT ISO/IEC 19005-1, 23 de janeiro de 2009: Utilizado para documentos finalizados que serão armazenados e não mais atualizados.
3-Portable Network Graphiscs(PNG) padrão ISO/IEC: Sua utilização é para armazenamento de documentos gerados através de digitalização, normalmente documentos escaneados.
Aqui vale uma ressalva interessante, as normas da ABNT, exceto quando existir lei afirmando o contrário, são recomendações não obrigatórias. Existem várias razões para segui-las, como padronização e principalmente segurança, caso exista algum problema legal no futuro e você não seguir essas normas poderá ser responsabilizado por negligência.
Também vale citar que para situações especificas existem outros formatos, como o Medial Images (DICOM), para o setor medico.
Nesse artigo consideraremos que estamos lidando com o passivo e que todos os arquivos armazenados deverão ser preferencialmente do tipo PDF/A, formato eletrônico de arquivo de documento para preservação de longo prazo (ABNT NBR ISO 19005-1), onde se tem a garantia legal de que poderão ser lidos e impressos por dezenas de anos.
O armazenamento de grandes objetos nos SGBDS, por razões de armazenamento físico, performance e becape, não eram recomendados até bem pouco. O armazenamento físico desses registros tipicamente era realizado em file systems, muitos com acesso aos usuários comuns, e o SGBD apenas armazenava a localização e o nome desses arquivos, essa descrição é feita geralmente em campos do tipo varchar, a grande vantagem dessa arquitetura é a simplicidade de implementação, a escalabilidade é dependente da forma que a aplicação foi estruturada, não entraremos em detalhes sobre essa arquitetura, mas a portabilidade e a segurança são comprometidos, principalmente se pensarmos na disponibilidade desses documentos à outras ferramentas, outra limitação dessa arquitetura é que esses sistemas geralmente não fazem uso dos recursos de textuais incorporados aos grandes SGBDS,como o Full-Text Search(SQL SERVER), Oracle Text(Oracle), entre outros, nem tampouco dos recursos atuais de compressão de dados, que proporcionam economia no armazrnamento(storange).
Já há algum tempo o SGBD Oracle disponibiliza um campo com essa finalidade, BFILE, para armazenar grandes objetos binários no File System gerenciado pelo SGBD, o SQL Server 2008, a Microsoft, disponibilizou um tipo semelhante FileStream Data Type.
Os SGBDS nos oferecem para armazenamento de documentos, como já colocamos, os campos do tipo LOB (acrônimo para large object), no caso do Oracle temos,entre outros , os campos BLOB - Binary Large Object; CLOB - Character Large Objects e BFILE - Binary File Object. Esse último, objeto de nosso estudo por permitir gerenciamento por parte do SGBD, com armazenamento transparente em um filesystem proporcionando maior segurança e escalabilidade, mesmo com o compartilhamento entre diversas ferramentas.
A forma mais eficiente, nos dias atuais, para uma rede geograficamente espalhada e com necessidade de dispor acesso a diversos documentos eletronicos, também espalhados em locais diferentes, é via protocolos como o HTTP/HTTPS, de forma a permitir sua utilização por diversas plataformas espalhadas em redes heterogêneas.
III – Tipos de Dados para Armazenamento de Arquivos em SGBDs:
LOBs podem armazenar grandes volumes de informação, mas possuem restrições na sua utilização na prática, o armazenamento no SGBD de grandes volumes de dados deve ser acompanhado de cuidados com relação ao planejamento/gerenciamento do SGBD e do becape, além disso a velocidade de recuperação com relação aos arquivos armazenados em file system, acima de uma patamar que pode variar de 1MB à 4MB, podem ser inferiores aos mesmos arquivos armazenados nos file system, para aqueles que querem saber mais recomendo o artigo
To BLOB or Not To BLOB: Large Object Storage in a Database or a Filesystem?- http://research.microsoft.com/apps/pubs/default.aspx?id=64525
Vamos citar alguns tipos de LOBs recomendados para uso no SGBD Oracle, pelo fabricante do mesmo, são os seguintes:
CLOB – Character Large Object – Para armazenar caracteres single-byte ou multibytes, seu tamanho máximo é (4GB-1) * DB_BLOCK_SIZE;
NCLOB - Similar a anterior, os caracteres UNICODE podem ser armazenados tanto com largura variável quanto fixa.
BLOB - Binary Large Object; Armazenamento de grandes objetos binários, arquivos de música, vídeo, etc.... O tamanho máximo é (4GB -1) * DB_BLOCK_SIZE.
BFILE - Ponteiros para um BLOB(Grande arquivo Binário de qualquer tipo) armazenado fora do SGBD, portanto no file system, O tamanho máximo é de 4GB.
O Datatype BFILE é usado para armazenar ponteiros (links) que apontam para um arquivo armazenado fora do SGBD, mas mapeados em DIRECTORY Oracle, que nada mais é que um file sytem mapeado pelo SGBD, de forma a permitir a criação, manipulação e leitura pelo mesmo dos arquivos lá existentes no caso do BFILE ele permite que os arquivos sejam manipulados e gerenciados como BLOBs, porém com várias vantagens inerentes aos arquivos armazenados em file system. O tamanho máximo para esse tipo de arquivo é de 4G, são arquivo armazenado somente para leitura, porém com um pouco de programação podemos realizar outras operações sobre os mesmos, não trataremos disso nesse artigo, outra vantagem é que podemos criar índices para buscas internas nos documentos armazenados com o ferramentas textuais, como Oracle Text, não implementaremos nesse artigo as funções de busca indexada desses arquivos, mas caso queiram conhecer mais com relação a esse assunto, deixamos alguns links interessantes na seção Para Saber Mais
Um exemplo simples de utilização dos arquivos BFILE seria o seguinte:
CREATE TABLE TableBfile (
C_Chave NUMBER NOT NULL,
Nom_Arquivo VARCHAR2(200),
C_bfile BFILE);
Nesse momento vamos criar o DIRECTORY:
CREATE OR REPLACE DIRECTORY DIR_ARQ AS ''C:\arquivos\'';
E finalmente vamos inserir os arquivos:
INSERT INTO TableBfile
(c_chave,Nom_Arquivo,c_bfile)
VALUES
(1,''Manual 01'' ,BFILENAME(''DIR_ARQ'', ''pdf1.pdf''));
INSERT INTO TableBfile
(c_chave,Nom_Arquivo,c_bfile)
VALUES
(2,''Manual 02 BFILENAME(''DIR_ARQ'', ''pdf2.pdf''));
IV – Salvando um arquivo BFILE a partir de um executavel::
Nesse momento, o desenvolvedor se questiona qual a vantagem sobre a abordagem anterior, salvar os arquivos em um servidor e na base de dados, em campo varchar, a sua localização, pois ele terá que carregar efetivamente os arquivos em um file system mapeado como já realizava. Tem razão, usado dessa maneira não temos muitas vantagens, pois a maioria das linguagens de programação não possuem bibliotecas para carregar arquivos Bfile em DIRECTORY.
Caso desenvolva em Microsoft .NET uma boa opção seria .NET Framework Class Library OracleBFile Class(http://msdn.microsoft.com/pt-br/library/system.data.oracleclient.oraclebfile.aspx ), mas para aqueles que se utilizam de outras linguagens, que permitem o carregamento de arquivos BLOB, não se preocupem, pois existe uma solução ainda mais transparente, o uso de STORED PROCEDURES.
Podemos adicionar um campo do tipo BLOB, carregar via aplicação esse campo, e em seguida transferir o arquivo para o DIRECTORY e apagar o conteúdo BLOB que já fora transferido, tudo com uma STORED PROCEDURE, que pode ser chamada via código ou Trigger.
Dessa forma o script de criação da tabela seria o seguinte:
CREATE TABLE TableBfile (
C_Chave NUMBER NOT NULL,
BLOB_ARQ BLOB,
Nom_Arquivo VARCHAR2(200),
C_bfile BFILE);
Abaixo código de procedure que copia um BLOB armazenado, no SGBD para o file system, cria o BFILE e em seguida apaga o conteúdo do BLOB.
CREATE OR REPLACE PROCEDURE CRIA_BFILE
( v_seq varchar)
IS
v_blob_ori BLOB;
v_file UTL_FILE.FILE_TYPE;
v_offset integer:=1;
v_amount integer:=32767;
v_binary_buffer raw(32767);
v_nome_campo varchar2(255);
begin
-- obtém o localizador de LOB do BLOB
select
BLOB_ARQ,Nom_Arquivo
into
v_blob_ori,v_nome_campo
from
TableBfile
where
C_Chave =v_seq;
-- abre o arquivo para gravar os bytes(até v_amount bytes por vez)
v_file:= UTL_FILE.FOPEN(''DIR_ARQ'', v_nome_campo, ''wb'' , v_amount);
-- copia os dados do blob para o arquivo
loop
begin
-- lê caracteres de v_blob_ori em v_binary_buffer
dbms_lob.read(v_blob_ori, v_amount, v_offset,v_binary_buffer);
-- copia os dados binários de v_binary_buffer no arquivo
utl_file.put_raw(v_file,v_binary_buffer);
-- adiciona v_amount em v_offset
v_offset:= v_offset + v_amount;
exception
-- quando não há mais dados no arquivo, sai
when no_data_found then
exit;
end;
end loop;
-- descarrega os dados restantes no arquivo
utl_file.fFlush(v_file);
-- fecha o arquivo
utl_file.fclose(v_file);
-- altera o campo da tabela indicando o caminho do BFILE
UPDATE TableBfile SET C_bfile = BFILENAME(''DIR_ARQ'',v_nome_campo)
where C_Chave =v_seq;
-- altera o campo blob da tabela deixando ele como nulo
UPDATE TableBfile SET BLOB_ARQ = null
where C_Chave =v_seq;
end CRIA_BFILE;
/
Com essa solução simples a localização do arquivo é completamente transparente à aplicação, e qualquer aplicação com suporte a carregamento de arquivos BLOB, pode realizar a carga do arquivo BFILE corretamente.
V – PL/SQL Web Toolkit:
Por si só esse item mereceria já teria méritos para uma artigo completo. Esse Toolkit permite a geração de páginas web diretamente do SGBD Oracle, versão 8i ou superior. Nesse artigo utilizamos o Oracle HTTP, instalado por default com o Oracle 9i, por facilidade de uso e configuração para uso didático, também informo que para muitos usos o APEX - Oracle Application Express - (http://apex.oracle.com/) pode substituir o PL/SQL Web Toolkit.
A programação em ambos os casos se dá em PL/SQL, produzimos as chamadas Aplicações WEB PL/SQL, a documentação da Oracle descreve que o produto resultante é similar a um Script CGI Perl, gerando páginas WEB dinamicamente, onde se pode usar comandos DML, SQL dinâmico, cursores e possui um baixo nível de overhead na execução de novas solicitações(http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_web.htm#i1006197 ).
Para disponibilização dos arquivos que salvamos no DIRECTORY mapeado, utilizaremos o próprio SGBD, com a utilização de PL/SQL, para tanto usaremos mão do PL/SQL Web Toolkit. Esse recurso é default de instalação no Oracle 9i, para o Oracle 10G se faz necessário baixar o companion cd do sítio da Oracle, compatível com a versão do Oracle utilizada.
Partindo do principio que a instalação foi realizada em Oracle 9i, vá para Iniciar -> Programas -> Oracle OraHome92 -> Oracle http Server -> Iniciar o http Server .
Inicie o Navegador, no meu caso eu configurei a porta padrão, a tela de configuração no Oracle 9i é a seguinte:
Quando aparecer a tela do HTTP Server selecione a opção: Mod Plsql Configuration Menu, para que possamos configurar o módulo Plsql, em seguida devemos configurar o Database Acess Descriptor – DAD.
O próximo item a selecionar é no Menu de Configurações de Gateway a opção é: Definições de DAD do Gateway em seguida escolha a opção Adicionar Default, neste momento entramos com o nome do Schema, e dados da conexão(Usuário, Password e string de conexão), nenhuma outra informação é necessária para esse exemplo.
Para que possamos visualizar os arquivos carregados, no nosso caso no Formato PDF, temos que criar uma procedure, conforme código abaixo:
CREATE OR REPLACE PROCEDURE READ_PDF (seq IN NUMBER) IS
l_src bfile;
l_dest blob;
l_length binary_integer;
BEGIN
-- obtém o localizador de BFILE
SELECT C_bfile
INTO l_src
FROM TableBfile
where
C_Chave=seq;
l_length := dbms_lob.getlength(l_src);
dbms_lob.fileopen(l_src, dbms_lob.file_readonly);
dbms_lob.createtemporary(l_dest, true);
dbms_lob.loadfromfile(l_dest, l_src, l_length);
dbms_lob.fileclose(l_src);
owa_util.mime_header(''application/pdf'', false);
htp.p(''Content-length: '' || l_length);
owa_util.http_header_close;
wpg_docload.download_file(l_dest);
dbms_lob.freetemporary(l_dest);
END;
/
Para podemos visualizar esses arquivos, estamos simplificando com a finalidade de exemplificação, podemos realizar sua chamada diretamente ao navegador, no nosso exemplo: http://192.168.127.132/pls/exemplo/READ_PDF?seq=1, onde seq=1, trará o arquivo c_chave=1, no exemplo o arquivo PDF1.pdf
Conseguimos acessar um arquivo de 5.689KB(434 páginas) rapidamente e de forma transparente inclusive para o programador, com controle pelo SGBD.
Podemos utilizar outras abordagens para disponibilizar arquivos via WEB com linguagens de programação como JAVA, ASP .NET e PHP, abaixo um exemplo de página em PHP :
<?php
session_start();
error_reporting(0);
header(''Content-type: application/pdf'');
/* Banco de Dados : $dbname
usuario : $usuario
senha : $senha */
$dbname ="babylon5";
$usuario = "babylon5";
$senha = "babylon5";
if (!($connection = oci_pconnect($usuario, $senha,$dbname)))
{
$oerr=ocierror();
if($oerr["code"])
{
//$oerr=OCIERROR($connectionection);
echo "Não foi possível estabelecer uma conexão com o Banco de Dados".''
'';
echo "Código: ".$oerr["code"].''
'';
echo "Mensagem: ".$oerr["message"].''
'';
exit;
}
}
$sql=” SELECT C_bfile FROM TableBfile where C_Chave=’$seq’”;
$stmt = oci_parse($connection, $sql);
// Execute the statement using , OCI_DEFAULT - as a transaction
oci_execute($stmt)
or die("Não foi possível executar a Query\n");
while ($row = oci_fetch_assoc($stmt) )
{
print $row[''c_bfile'']->load()."\n";
}
OCIFetch($stmt);
OCILogoff($stmt);
// Free resources
OCIFreeStatement($stmt);
?>
Podemos concluir que com os recursos disponíveis nos SGDBs, juntamente com as linguagens atuais de programação, pode-se criar sistemas de gerenciamento eletrônicos de documentos totalmente funcionais e que atendam aos padrões exigidos, com recursos já disponíveis nos principais produtos já utilizados no mercado.
VI – Para saber mais
Informações sobre Oracle Text