Páginas

segunda-feira, 28 de abril de 2014

Como enviar e-mail a partir do Banco de Dados

Criando funcionalidade em PL/SQL

Olá a todos.

Neste post vou compartilhar conhecimentos gerais sobre como enviar e-mails a partir de um SGBD Oracle e mostrarei como evitar alguns problemas que você poderá encontrar tentando realizar esta tarefa.
De imediato vale lembrar que, dependendo da sua necessidade, já existe a facilidade embutida em alguns pacotes, como por exemplo, o DBMS_SCHEDULER já envia e-mail em alguns status que o JOB se encontra, não havendo a necessidade de criar essa facilidade para esse fim.

Para enviar e-mails a partir de um SGBD Oracle, obrigatoriamente utilizaremos as packages UTL_MAIL e UTL_SMTP, mas é possível utilizar também a package UTL_TCP. 

A UTL_SMTP é mais antiga, existe desde o Oracle 8i e já vem instalada, por padrão no BD. 
A UTL_MAIL está disponível a partir do Oracle 10GR2, e utiliza as packages UTL_SMTP e UTL_TCP. Ela foi criada para facilitar o envio de e-mails, mas infelizmente, ela possui algumas restrições.

Utilizar a package UTL_SMTP para mandar e-mail é bastante complexo e trabalhoso. É mais fácil e mais rápido utilizar a package UTL_MAIL do que a package UTL_SMTP, mas ela possui algumas restrições, tais como: enviar somente 1 anexo e o tamanho do anexo deve ser de no máximo 32K. Estas restrições não existem na package UTL_SMTP, que não vou abordar neste artigo.

Nesse post, o código que vou utilizar poderá servir como referência para quem pretende ver como usar qualquer uma delas (UTL_SMTP ou UTL_MAIL).

Explicarei abaixo como usar a UTL_MAIL, por ser a opção mais simples e atualmente a mais utilizada. Para utilizá-la é necessário cumprir alguns pré-requisitos:
  1. Instalar a package a partir do script : $ORACLE_HOME/rdbms/admin/utlmail.sql e $ORACLE_HOME/rdbms/admin/prvtmail.plb (necessário privs administrativos);
  2. Configurar o parâmetro de sistema SMTP_OUT_SERVER, com um valor de um servidor SMTP válido. Você pode omitir o endereço da porta, que será utilizada como padrão a porta 25.
    Ex.: ALTER SYSTEM SET smtp_out_server = 'smtp.server.com.br:25'; (necessário privs administrativos)
  3. O remetente (sender) do e-mail deve ser uma conta de e-mail que não requer autenticação para envio de mensagens.
  4. Os scripts parecem não conceder a necessária permissão EXECUTE para PUBLIC ou o usuário que você irá usar para encaminhar os e-mails. Assim, depois de executar os scripts, enquanto ainda estiver conectado como SYS você deve executar a seguinte linha:
    grant execute on UTL_MAIL to usuario;
Após os pré-requisitos acima, você já poderá utilizar a package UTL_MAIL. Segue abaixo, um bloco PL/SQL simples, que contém comentários sobre o que deve ser passado como valor em cada parâmetro, e que pode ser utilizado para enviar um e-mail :
BEGIN
  UTL_MAIL.SEND (
  SENDER => 'email@oracle.com',  -- remetente da mensagem
  RECIPIENTS => 'destino@gmail.com', -- destinatário da mensagem
  CC => NULL,  -- destinatário copiado na mensagem
  BCC => NULL,  -- destinatário com cópia oculta da  mensagem
  SUBJECT => 'Assunto do e-mail', -- assunto da mensagem
  MESSAGE => 'Mensagem do e-mail', -- mensagem do e-mail
  MIME_TYPE => 'text/plain; charset=iso-8859-1' -- mime type + character set
  );
END;

Como pode ser observado no bloco PL/SQL acima, é muito fácil enviar uma mensagem usando a package UTL_MAIL, mas a coisa complica quando você tem que mandar mensagens com anexo, e fica impossível quando o anexo é maior que 32K. Um detalhe em que muitos profissionais encontram problemas e dificuldades, é a configuração dos caracteres do texto das mensagens e do texto dos anexos, que podem apresentar, em muitos casos, os chamados "caracteres desconfigurados". Para evitar estes caracteres desconfigurados é necessário passar o valor adequado para os parâmetros MIME_TYPE, que indicam o tipo de aplicação e o conjunto de caracteres que será utilizado para compor o texto da mensagem ou do anexo. Eu normalmente configuro o valor 'text/plain; charset=iso-8859-1'. Se para você esta configuração apresentar caracteres desconfigurados, troque o valor iso-8859-1 por utf-8 ou us-ascii (valor padrão). Para aqueles que ainda assim tiverem problemas e precisarem de mais informações sobre mime types, sugiro a leitura do artigo http://en.wikipedia.org/wiki/MIME.

Se você tentar mandar um e-mail em um BD 11G, possivelmente você irá se deparar com o erro ORA-24247: acesso à rede negado pela ACL (access control list), pois nesta versão do Oracle, para aumentar a segurança do BD, foi acrescentado um controle de acesso mais rígido às packages UTL_MAIL, UTL_SMTP e outras, em que é necessário conceder privilégios especiais ao usuários que irão executá-las. Não iremos entrar em detalhes sobre ACL, mas para conceder estes privilégios a um usuário chamado RICARDO, por exemplo, execute os blocos PL/SQL abaixo:
begin
  dbms_network_acl_admin.create_acl (
        acl => 'grant_acl.xml',
        description => 'Permite enviar e-mail e usar outras packages',
        principal => 'RICARDO', -- veja que o nome do usuário deve ser MAIÚSCULO
        is_grant => TRUE,
        privilege => 'connect'  -- este privilégio concedido é que permite que o usuário envie email através do servidor que será especificado no próximo bloco 
        );
  commit;
end;
/

begin
   dbms_network_acl_admin.assign_acl(
        acl => 'grant_acl.xml',
        host => 'hostname'  -- preencha aqui o nome do host do servidor SMTP
        );
   commit;
end;
 /

É isso ai pessoal, bem simples, rápido e fácil....
Um forte abraçõ