Envío de Correos con PLSQL desde Base de Datos Oracle

Raúl Antonio Molina Alvarenga

26 de abril de 2023

#OracleTipsSV

#OracleACE

El envío de correos desde la base de Datos Oracle usando PLSQL es algo común, y en cierta medida necesario, mucha tarea o control de actividades puede desenvolverse con el envío de un correo oportuno orquestado desde la base de datos.

Vamos a comenzar indicando que prefiero usar un PLSQL que complicarme la existencia usando Java para esta tarea, siendo así, hay que indicar que los paquetes de BD  necesarios para el mismo antes en algunas versiones viejas era requerido instalarlos.

sqlplus /nolog

connect / as sysdba

@?/rdbms/admin/utlmail.sql

@?/rdbms/admin/prvtmail.plb

grant execute on utl_mail to public; --> puede ser o debería 
ser a un usuario particular

Debemos definir los datos de nuestro SMTP, y si la bd es 11.1 o superior, debemos configurar las reglas de salida o trafico de salida de la BD con las ACLs y si es 19c las ACE.

alter system set smtp_out_server = 'TuSMTP' scope=both;

select * from dba_network_acls;

Si hubieran borra los que hayan, si no ignora, 

BEGIN

DBMS_NETWORK_ACL_ADMIN.DROP_ACL(

acl => 'mail_access.xml');

END;

/

BEGIN

DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (

acl          => 'mail_access.xml',

description  => 'Permissions to access e-mail server.',

principal    => 'PUBLIC',

is_grant     => TRUE,

privilege    => 'connect');

COMMIT;

END;

/

BEGIN

DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (

acl          => 'mail_access.xml',

host         => 'TUSMTP'

);

COMMIT;

END;

/

 

Luego preparamos las unidades PLSQL que permitirán el envío de los correos, totalmente personalizables, permiten hasta envio de adjuntos,  formateo HTML para los visores de correo mas modernos, etc.

 

CREATE OR REPLACE PROCEDURE send_mail (p_to        IN VARCHAR2,

                                       p_from      IN VARCHAR2,

                                       p_subject   IN VARCHAR2,

                                       p_message   IN VARCHAR2,

                                       p_smtp_host IN VARCHAR2,

                                       p_smtp_port IN NUMBER DEFAULT 25)

AS

  l_mail_conn   UTL_SMTP.connection;

BEGIN

  l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);

  UTL_SMTP.helo(l_mail_conn, p_smtp_host);

  UTL_SMTP.mail(l_mail_conn, p_from);

  UTL_SMTP.rcpt(l_mail_conn, p_to);

  UTL_SMTP.open_data(l_mail_conn);

  

  UTL_SMTP.write_data(l_mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || UTL_TCP.crlf);

  UTL_SMTP.write_data(l_mail_conn, 'To: ' || p_to || UTL_TCP.crlf);

  UTL_SMTP.write_data(l_mail_conn, 'From: ' || p_from || UTL_TCP.crlf);

  UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || p_subject || UTL_TCP.crlf);

  UTL_SMTP.write_data(l_mail_conn, 'Reply-To: ' || p_from || UTL_TCP.crlf || UTL_TCP.crlf);

  

  UTL_SMTP.write_data(l_mail_conn, p_message || UTL_TCP.crlf || UTL_TCP.crlf);

  UTL_SMTP.close_data(l_mail_conn);

  UTL_SMTP.quit(l_mail_conn);

END;

/

Ejemplo para probarlo con cualquier usuario,  por ejemplo enviando correos desde tu ID de correo.

 create user ssa identified by admin;

 grant connect,resource,dba to admin;

grant execute on sys.send_mail to admin;

BEGIN

  sys.send_mail(p_to        => 'correo@dominio',

            p_from      => 'correo1@dominio',

            p_subject   => 'Test Message',

            p_message   => 'This is a test message.',

            p_smtp_host => 'mail.ssasis.com');

END;

/

/  2    3    4    5    6    7    8  

PL/SQL procedure successfully completed.

Pudiendo tener resultados como el siguiente:

DR SYNC STATUS REPORT FOR DATABASE: db
INST_NAME LOG_ARCHIVED LOG_APPLIED TIME_APPLIED LOG_GAP
bd1 302281 302279 26-Apr, 05:49:20 2
bd2 300298 300297 26-Apr, 05:53:55 1
bd3 290118 290117 26-Apr, 05:53:53 1

 

Espero les sea de utilidad!!.

Saludos