WEBCODELOG

free codes, enjoy

Enviando e-mail com PL/SQL

with 4 comments

Em continuidade a nossa série “as mil-e-uma utilidades do seu banco de dados Oracle”, agora você poderá descobrir como é fácil enviar e-mails a partir do PL/SQL e saber o quanto isto é produtivo.

Vamos lá, para o envio de e-mails é necessário que o pacote UTL_MAIL esteja instalado.

Conectando como sysdba na instância ORCL.

C:\>set oracle_sid=orcl
C:\>sqlplus sys/oracle as sysdba

Instalando o pacote UTL_MAIL. Isto não é nenhuma novidade, mas a variável de ambiente %ORACLE_HOME% indica o caminho a qual o banco de dados foi instalado, neste caso, foi utilizada a versão 10.2.0 – C:\oracle\product\10.2.0\db_1. Os sub-diretórios, contém os pacotes necessários para o UTL_MAIL funcionar.

SQL> set serveroutput on
SQL> @%ORACLE_HOME%/rdbms/admin/utlmail.sql
SQL> @%ORACLE_HOME%/rdbms/admin/prvtmail.plb
SQL> show errors;

Pronto, isto é o suficiente para o nosso próximo passo, a criação da procedure de envio de e-mails.

Crie uma package para agrupar todas as funcionalidades que podem ser comuns a diversos projetos, e reutilize o código quando necessário.

create or replace package PKG_BLOG_UTIL is

-- Author  : LUCIANO
-- Created : 05/07/2009

PROCEDURE enviar_email_auth(p_USUARIO   IN VARCHAR2,
p_SENHA     IN VARCHAR2,
p_TO        IN VARCHAR2,
p_COPIA     IN VARCHAR2,
p_SUBJECT   IN VARCHAR2,
p_MESSAGE   IN VARCHAR2);
end PKG_BLOG_UTIL;

Veja agora a versão 1.0 desta implementação:

CREATE OR REPLACE PACKAGE BODY PKG_BLOG_UTIL IS

PROCEDURE ENVIAR_EMAIL_AUTH(P_HOST    IN VARCHAR2,
P_USUARIO IN VARCHAR2,
P_SENHA   IN VARCHAR2,
P_TO      IN VARCHAR2,
P_COPIA   IN VARCHAR2,
P_SUBJECT IN VARCHAR2,
P_MESSAGE IN VARCHAR2)
IS

MAIL_CONN   UTL_SMTP.CONNECTION;
V_HEADER    VARCHAR2(4000);
CRLF        VARCHAR2(2) := CHR(13) || CHR(10); -- quebra de linha

BEGIN

-- Abre a conexão
MAIL_CONN   := UTL_SMTP.OPEN_CONNECTION(P_HOST, 25);
UTL_SMTP.HELO(MAIL_CONN, P_HOST);

-- Faz a autenticação para envio de mensagem
UTL_SMTP.COMMAND(MAIL_CONN, 'AUTH LOGIN');
UTL_SMTP.COMMAND(MAIL_CONN, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USUARIO))));
UTL_SMTP.COMMAND(MAIL_CONN, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_SENHA))));

-- Prepara o cabeçalho de
V_HEADER := 'Date:'    || TO_CHAR(SYSDATE, 'dd Mon yy hh24:mi:ss') || CRLF ||
'From:'    || p_USUARIO || CRLF ||
'Subject:' || p_SUBJECT || CRLF ||
'To:'      || p_TO      || CRLF ||
'Cc:'      || p_COPIA   || CRLF ||
CRLF || CRLF ||
p_MESSAGE;

--
UTL_SMTP.MAIL(MAIL_CONN, '<' || P_USUARIO || '>');
UTL_SMTP.RCPT(MAIL_CONN, '<' || P_TO || '>');
UTL_SMTP.DATA(MAIL_CONN, V_HEADER);

-- Fecha a conexão
UTL_SMTP.QUIT(MAIL_CONN);

END ENVIAR_EMAIL_AUTH;
END PKG_BLOG_UTIL;

Algumas coisas podem ser melhoradas como, separar o corpo da mensagem do cabeçalho e utilizar o UTL_TCP.CRLF como separador de linhas no lugar da variável CRLF, veja como o código fica mais organizado:

/* APENAS UM TRECHO DO CÓDIGO */
UTL_SMTP.MAIL(MAIL_CONN, '<' || P_USUARIO || '>');
UTL_SMTP.RCPT(MAIL_CONN, '<' || P_TO || '>');

UTL_SMTP.open_data(MAIL_CONN);

-- Prepara o cabeçalho
UTL_SMTP.write_data(MAIL_CONN, 'From'    || ': ' || p_USUARIO || UTL_TCP.CRLF);
UTL_SMTP.write_data(MAIL_CONN, 'To'      || ': ' || p_TO      || UTL_TCP.CRLF);
UTL_SMTP.write_data(MAIL_CONN, 'Cc'      || ': ' || p_COPIA   || UTL_TCP.CRLF);
UTL_SMTP.write_data(MAIL_CONN, 'Subject' || ': ' || P_SUBJECT || UTL_TCP.CRLF);

-- Escreve a mensagem
UTL_SMTP.write_data(MAIL_CONN, UTL_TCP.CRLF || p_message);
UTL_SMTP.close_data(MAIL_CONN);

Eu preferi adotar este segundo código como o mais recomendável, mesmo assim, alguns detalhes podem ser adaptados a sua realidade, por exemplo, criar uma constante para o Mail Host, e indicando que o envio de e-mails sempre será a partir daquele servidor ou fazer a sobrecarga da procedure – a reutilização é uma benção.

Veja que a assinatura da procedure abaixo é um overload do que foi mostrado acima, isto é um conceito de Orientação-a-Objetos suportado pelo PLSQL, permite que um método seja escrito com diversas assinaturas diferentes, e reaproveitando o código de maneira eficaz.

PROCEDURE ENVIAR_EMAIL_AUTH(P_USUARIO IN VARCHAR2,
P_SENHA   IN VARCHAR2,
P_TO      IN VARCHAR2,
P_COPIA   IN VARCHAR2,
P_SUBJECT IN VARCHAR2,
P_MESSAGE IN VARCHAR2)
IS
V_MAILHOST CONSTANT VARCHAR2(100) := 'pop.xxxx.com.br';
BEGIN

enviar_email_auth(P_HOST    => v_mailhost,
P_USUARIO => P_USUARIO,
P_SENHA   => P_SENHA,
P_TO      => P_TO,
P_COPIA   => P_COPIA,
P_SUBJECT => P_SUBJECT,
P_MESSAGE => P_MESSAGE);
END ENVIAR_EMAIL_AUTH;

A package completa, está disponível aqui para download.

Não envie spam!

Bookmark and Share

Written by Luciano

julho 5th, 2009 at 1:01 pm

4 Responses to 'Enviando e-mail com PL/SQL'

Subscribe to comments with RSS or TrackBack to 'Enviando e-mail com PL/SQL'.

  1. [...] é o envio de e-mail para diversos destinatários, portanto, complementando o código já postado aqui sobre o envio de e-mails utilizando [...]

  2. Olá amigo..e como ficaria esse mesmo exemplo com o oracle exe

    Emerson

    3 mar 10 at 13:40

  3. amigo poderia publicar um exemplo com o oracle xe!pq fiz uns testes aqui mas nao funfou

    Emerson

    3 mar 10 at 14:23

  4. Emerson, me desculpe pela demora e, me desculpe também por não poder ajudá-lo no momento, não tenho a instalação do Oracle XE feita. É sabido que ele limitado em alguns recursos, verifique no site da Oracle, talvez encontre alguma solução.

    Se encontrar ou já encontrou a solução, coloque aqui.

    Abraço.

    Luciano

    4 mai 10 at 17:35

Leave a Reply