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:
 
 
Imagem
    
 
        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.
 
 
     Imagem
 
 
 
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.
 
Imagem
        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
 
Imagem
 
 
 
 
            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