Enviando e-mails com PL/SQL em Bancos de Dados Oracle

Olá pessoal,

O assunto de hoje é a 1ª parte de um artigo (dividido em 2 partes) em que vou compartilhar conhecimentos gerais sobre como enviar e-mails a partir de um SGBD Oracle e mostrarei como evitar os principais problemas que você poderá encontrar tentando realizar esta tarefa. Alguns que eu mesmo passei, outros que alguns leitores do meu blog passaram e me pediram ajuda e outros que vi em fóruns.

Para enviar e-mails a partir de um SGBD Oracle, comumente utilizamos as packages UTL_MAIL UTL_SMTP, mas é possível utilizar também a package UTL_TCP. Todas elas foram desenvolvidas pela própria Oracle e algumas precisam de instalação adicional. 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 nada mais é do que um wrapper que 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. É bem mais fácil e mais rápido utilizar a package UTL_MAIL, mas como eu havia dito no parágrafo acima, ela possui 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 explicar neste artigo. Na 2a. parte vou compartilhar uma package que usa tanto a UTL_SMTP quanto a UTL_MAIL para enviar e-mails. O código desta package poderá servir como referência para quem pretende ver como usar qualquer uma delas.

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 executando os scripts: $ORACLE_HOME/rdbms/admin/utlmail.sql e $ORACLE_HOME/rdbms/admin/prvtmail.plb. A instalação deve ser efetuada por um usuário que tenha privilégios de DBA;

2–  Configurar o parâmetro de sistema SMTP_OUT_SERVER, com um valor contendo o nome ou IP + porta de um servidor SMTP válido. Se você omitir o endereço da porta, será utilizada como padrão, a porta 25. É importante salientar que a máquina host do BD tenha comunicação com o servidor SMTP, e  também, autorização para enviar mensagens (no software do servidor SMTP não deve existir regras que bloqueiem mensagens da máquina host do BD).

Ex.: ALTER SYSTEM SET smtp_out_server = ‘smtp.empresa.com.br:25’;

Obs.: Para executar o comando acima é necessário ter privilégios de DBA.

3– O remetente (sender) do e-mail deve ser uma conta de e-mail que não requer autenticação para envio de mensagens.

Após cumprir 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 sem anexo, utilizando a procedure SEND desta package:

BEGIN
UTL_MAIL.SEND
(SENDER => '[email protected]', -- remetente da mensagem
RECIPIENTS => '[email protected]',  -- 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 do texto da mensagem
);
END;

Como pode ser observado no bloco PL/SQL acima, é muito fácil enviar uma mensagem sem anexo 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. Eu normalmente configuro o valor  ‘text/plain; charset=iso-8859-1’ e isso já é suficiente para resolver os meus problemas. 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 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 neste artigo, mas para conceder estes privilégios a um usuário chamado FABIO, por exemplo, execute os blocos PL/SQL abaixo:

begin
dbms_network_acl_admin.create_acl ( acl => 'grant_acl', description => 'Permite enviar e-mail e usar outras packages', principal => 'FABIO', is_grant => TRUE, privilege => 'connect' );
commit; end; /

begin
dbms_network_acl_admin.add_privilege ( acl => 'grant_acl', principal => 'FABIO', is_grant => TRUE, privilege => 'resolve' );
commit; end; /

begin
dbms_network_acl_admin.assign_acl( acl => 'grant_acl',  host => 'hostname' );
commit; end; /

Na próxima parte deste artigo, compartilharei com vocês, uma package que eu desenvolvi para facilitar o trabalho de envio de e-mails com ou sem anexo. Essa package internamente utiliza a package UTL_MAIL para enviar mensagens sem anexo e a package UTL_SMTP para enviar mensagens com anexo. O objetivo de criá-la foi para padronizar o código de envio de e-mails na empresa em que eu trabalho e facilitar o envio de e-mails com anexos maiores que 32K, pois não é muito fácil utilizar a package UTL_SMTP  para essa finalidade.

Por hoje é só! Aguardem a 2a. parte!

[]s

Artigo origem: http://www.fabioprado.net/2013/01/enviando-e-mails-com-plsql-em-bancos-de.html


Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!