Send mail from PL/SQL-from cyber
Sample scripts for sending E-mail messages from PL/SQL:
Starting from Oracle 8i release 8.1.6, one can send E-mail messages directly from PL/SQL using either the UTL_TCP or UTL_SMTP packages. However, Oracle introduced an improved package for sending E-mail in Oracle 10g - called UTL_MAIL - that should be used instead of UTL_SMTP.
All examples below require a working SMTP mail server. Customize these scripts to point the IP Address of your SMTP server. The SMTP port is usually 25. Configuring an SMTP server is not an Oracle function and thus out of scope for this site.
Contents
|
Send mail with UTL_MAIL
For security reasons, UTL_MAIL is not enabled by default. You must install it by connecting to SYS, then executing the utlmail.sql and prvtmail.plb scripts in the $ORACLE_HOME/rdbms/admin directory. In addition, you must configure an initialization parameter, SMTP_OUT_SERVER, to point to an outgoing SMTP server (unlike UTL_SMTP, this is not specified in the function arguments and must be pre-defined).
IMPORTANT: The scripts do not seem to grant the needed EXECUTE permission to PUBLIC. Thus, after running the scripts, while still logged in as SYS you should run the following line:
grant execute on UTL_MAIL to public;
Example:
BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = ''127.0.0.1'''; UTL_MAIL.send(sender => 'me@address.com', recipients => 'you@address.com', subject => 'Test Mail', message => 'Hello World', mime_type => 'text; charset=us-ascii'); END; /
Send mail with UTL_SMTP
Send mail without attachments using the UTL_SMTP package:
DECLARE v_From VARCHAR2(80) := 'oracle@mycompany.com'; v_Recipient VARCHAR2(80) := 'test@mycompany.com'; v_Subject VARCHAR2(80) := 'test subject'; v_Mail_Host VARCHAR2(30) := 'mail.mycompany.com'; v_Mail_Conn utl_smtp.Connection; crlf VARCHAR2(2) := chr(13)||chr(10); BEGIN v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, 25); utl_smtp.Helo(v_Mail_Conn, v_Mail_Host); utl_smtp.Mail(v_Mail_Conn, v_From); utl_smtp.Rcpt(v_Mail_Conn, v_Recipient); utl_smtp.Data(v_Mail_Conn, 'Date: ' || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf || 'From: ' || v_From || crlf || 'Subject: '|| v_Subject || crlf || 'To: ' || v_Recipient || crlf || crlf || 'some message text'|| crlf || -- Message body 'more message text'|| crlf ); utl_smtp.Quit(v_mail_conn); EXCEPTION WHEN utl_smtp.Transient_Error OR utl_smtp.Permanent_Error then raise_application_error(-20000, 'Unable to send mail', TRUE); END; /
Send mail with UTL_SMTP - with attachments
Send mail with attachments using the UTL_SMTP package:
DECLARE v_From VARCHAR2(80) := 'oracle@mycompany.com'; v_Recipient VARCHAR2(80) := 'test@mycompany.com'; v_Subject VARCHAR2(80) := 'test subject'; v_Mail_Host VARCHAR2(30) := 'mail.mycompany.com'; v_Mail_Conn utl_smtp.Connection; crlf VARCHAR2(2) := chr(13)||chr(10); BEGIN v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, 25); utl_smtp.Helo(v_Mail_Conn, v_Mail_Host); utl_smtp.Mail(v_Mail_Conn, v_From); utl_smtp.Rcpt(v_Mail_Conn, v_Recipient); utl_smtp.Data(v_Mail_Conn, 'Date: ' || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf || 'From: ' || v_From || crlf || 'Subject: '|| v_Subject || crlf || 'To: ' || v_Recipient || crlf || 'MIME-Version: 1.0'|| crlf || -- Use MIME mail standard 'Content-Type: multipart/mixed;'|| crlf || ' boundary="-----SECBOUND"'|| crlf || crlf || '-------SECBOUND'|| crlf || 'Content-Type: text/plain;'|| crlf || 'Content-Transfer_Encoding: 7bit'|| crlf || crlf || 'some message text'|| crlf || -- Message body 'more message text'|| crlf || crlf || '-------SECBOUND'|| crlf || 'Content-Type: text/plain;'|| crlf || ' name="excel.csv"'|| crlf || 'Content-Transfer_Encoding: 8bit'|| crlf || 'Content-Disposition: attachment;'|| crlf || ' filename="excel.csv"'|| crlf || crlf || 'CSV,file,attachement'|| crlf || -- Content of attachment crlf || '-------SECBOUND--' -- End MIME mail ); utl_smtp.Quit(v_mail_conn); EXCEPTION WHEN utl_smtp.Transient_Error OR utl_smtp.Permanent_Error then raise_application_error(-20000, 'Unable to send mail', TRUE); END; /
Send mail with UTL_TCP
Send mail using the UTL_TCP package:
CREATE OR REPLACE PROCEDURE SEND_MAIL ( msg_from varchar2 := 'oracle', msg_to varchar2, msg_subject varchar2 := 'E-Mail message from your database', msg_text varchar2 := ) IS c utl_tcp.connection; rc integer; BEGIN c := utl_tcp.open_connection('127.0.0.1', 25); -- open the SMTP port 25 on local machine dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'HELO localhost'); dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'MAIL FROM: '||msg_from); dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'RCPT TO: '||msg_to); dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'DATA'); -- Start message body dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'Subject: '||msg_subject); rc := utl_tcp.write_line(c, ); rc := utl_tcp.write_line(c, msg_text); rc := utl_tcp.write_line(c, '.'); -- End of message body dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'QUIT'); dbms_output.put_line(utl_tcp.get_line(c, TRUE)); utl_tcp.close_connection(c); -- Close the connection END; / show errors -- Test it: set serveroutput on exec send_mail(msg_to =>'you@yourdomain.com'); exec send_mail(msg_to =>'you@yourdomain.com', - msg_text=>'Look Ma, I can send mail from plsql' - );
Send mail with UTL_TCP - with attachments
Send e-mail messages with attachments from PL/SQL using UTL_TCP:
CREATE OR REPLACE PROCEDURE SEND_MAIL ( msg_from varchar2 := 'EMAILADDRESS@DOMAIN.COM', ----- MAIL BOX SENDING THE EMAIL msg_to varchar2 := 'EMAILADDRESS@DOMAIN.COM', ----- MAIL BOX RECIEVING THE EMAIL msg_subject varchar2 := 'Output file TEST1', ----- EMAIL SUBJECT msg_text varchar2 := 'THIS IS THE TEXT OF THE EMAIL MESSAGE.', v_output1 varchar2 := 'THIS IS THE TEXT OF THE ATTACHMENT FILE. THIS TEXT WILL BE IN A TEXT FILE ATTACHED TO THE EMAIL.') IS c utl_tcp.connection; rc integer; crlf VARCHAR2(2):= CHR(13)||CHR(10); mesg VARCHAR2(32767); BEGIN c := utl_tcp.open_connection('196.35.140.18', 25); ----- OPEN SMTP PORT CONNECTION rc := utl_tcp.write_line(c, 'HELO 196.35.140.18'); ----- PERFORMS HANDSHAKING WITH SMTP SERVER dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'EHLO 196.35.140.18'); ----- PERFORMS HANDSHAKING, INCLUDING EXTRA INFORMATION dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'MAIL FROM: '||msg_from); ----- MAIL BOX SENDING THE EMAIL dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'RCPT TO: '||msg_to); ----- MAIL BOX RECIEVING THE EMAIL dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'DATA'); ----- EMAIL MESSAGE BODY START dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'Date: '||TO_CHAR( SYSDATE, 'dd Mon yy hh24:mi:ss' )); rc := utl_tcp.write_line(c, 'From: '||msg_from||' <'||msg_from||'>'); rc := utl_tcp.write_line(c, 'MIME-Version: 1.0'); rc := utl_tcp.write_line(c, 'To: '||msg_to||' <'||msg_to||'>'); rc := utl_tcp.write_line(c, 'Subject: '||msg_subject); rc := utl_tcp.write_line(c, 'Content-Type: multipart/mixed;'); ----- INDICATES THAT THE BODY CONSISTS OF MORE THAN ONE PART rc := utl_tcp.write_line(c, ' boundary="-----SECBOUND"'); ----- SEPERATOR USED TO SEPERATE THE BODY PARTS rc := utl_tcp.write_line(c, ); ----- DO NOT REMOVE THIS BLANK LINE - PART OF MIME STANDARD rc := utl_tcp.write_line(c, '-------SECBOUND'); rc := utl_tcp.write_line(c, 'Content-Type: text/plain'); ----- 1ST BODY PART. EMAIL TEXT MESSAGE rc := utl_tcp.write_line(c, 'Content-Transfer-Encoding: 7bit'); rc := utl_tcp.write_line(c, ); rc := utl_tcp.write_line(c, msg_text); ----- TEXT OF EMAIL MESSAGE rc := utl_tcp.write_line(c, ); rc := utl_tcp.write_line(c, '-------SECBOUND'); rc := utl_tcp.write_line(c, 'Content-Type: text/plain;'); ----- 2ND BODY PART. rc := utl_tcp.write_line(c, ' name="Test.txt"'); rc := utl_tcp.write_line(c, 'Content-Transfer_Encoding: 8bit'); rc := utl_tcp.write_line(c, 'Content-Disposition: attachment;'); ----- INDICATES THAT THIS IS AN ATTACHMENT rc := utl_tcp.write_line(c, ' filename="Test.txt"'); ----- SUGGESTED FILE NAME FOR ATTACHMENT rc := utl_tcp.write_line(c, ); rc := utl_tcp.write_line(c, v_output1); rc := utl_tcp.write_line(c, '-------SECBOUND--'); rc := utl_tcp.write_line(c, ); rc := utl_tcp.write_line(c, '.'); ----- EMAIL MESSAGE BODY END dbms_output.put_line(utl_tcp.get_line(c, TRUE)); rc := utl_tcp.write_line(c, 'QUIT'); ----- ENDS EMAIL TRANSACTION dbms_output.put_line(utl_tcp.get_line(c, TRUE)); utl_tcp.close_connection(c); ----- CLOSE SMTP PORT CONNECTION END; /