I am trying to send multiple email addresses through an Oracle package/procedure. I have the procedure working when sending only a single to, cc, bcc. (That means I can send one of each.) But although have a loop that generates a correct, single email address (from a comma-separated-list), the procedure fails. I'm hoping someone can point out my code problem.
Note. The code for the package works; just the function two write multple rcpt lines does not.
When I use a separate code block to send the message (see below), I get the following error: Error report - ORA-29279: SMTP permanent error: 550 Internal error: Invalid argument
First, here is my process_recipients procedure code:
PROCEDURE process_recipients(p_mail_conn IN OUT UTL_SMTP.connection,
p_list IN VARCHAR2) IS
a DBMS_UTILITY.UNCL_ARRAY;
len PLS_INTEGER;
BEGIN
DBMS_UTILITY.COMMA_TO_TABLE(p_list, len, a);
FOR i IN 1..a.COUNT LOOP
--dbms_output.put_line( a(i) );
UTL_SMTP.rcpt(p_mail_conn, a(i) );
END LOOP;
END process_recipients;
Here is the relevant code from the send_email procedure, which will call proccess_recipients...
PROCEDURE send_email (
p_mail_server IN VARCHAR2
, p_mail_port IN VARCHAR2
, p_from IN VARCHAR2
, p_to IN VARCHAR2
, p_cc IN VARCHAR2 DEFAULT NULL
, p_bcc IN VARCHAR2 DEFAULT NULL
, p_subject IN VARCHAR2
, p_html_msg IN VARCHAR2 DEFAULT NULL
, p_text_msg IN VARCHAR2 DEFAULT NULL
) IS
l_mail_conn UTL_SMTP.connection;
l_boundary VARCHAR2(50) := '----=*#abc1234321cba#*=';
BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_mail_server,p_mail_port);
UTL_SMTP.helo(l_mail_conn, p_mail_server);
UTL_SMTP.mail(l_mail_conn, p_from);
--UTL_SMTP.rcpt(l_mail_conn, p_to);
process_recipients(l_mail_conn, p_to);
IF p_cc IS NOT NULL THEN
UTL_SMTP.rcpt(l_mail_conn, p_cc);
END IF;
IF p_bcc IS NOT NULL THEN
UTL_SMTP.rcpt(l_mail_conn, p_bcc);
END IF;
Here is the code which actually executes the package/procedure:
DECLARE
-- l_tab dbms_utility.lname_array;
html_message VARCHAR2(2000);
BEGIN
--GZ_SEND_EMAIL.p_send_v_test_email_address('smtp.isu.edu','25','mackaaro@isu.edu','<em>This</em> is a 3nd test message');
html_message := '<strong>Curabitur a arcu id erat fermentum dapibus et at leo.</strong> <p>Nunc placerat finibus pellentesque. Curabitur id ligula ac dui dictum bibendum. Suspendisse eget neque risus. </p>';
GZ_SEND_EMAIL.send_email(
p_mail_server => 'smtp.isu.edu'
, p_mail_port => '25'
, p_from => 'scholar@isu.edu'
, p_to => 'mackaaro@isu.edu,aaronmackley01@gmail.com'
, p_cc => 'snakeriver1701@gmail.com'
, p_bcc => NULL
, p_subject => 'Come join me for lunch at 11:07.'
, p_html_msg => html_message
, p_text_msg => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vel justo quis felis pellentesque iaculis. Sed sed tristique felis, non condimentum erat. Duis maximus, ligula quis imperdiet euismod, velit sem consectetur erat, a pellentesque ex dui id massa. Suspendisse a dolor elit.'
);
END;
And, here is a final snippit (not in the Procedure) which I used to test that I was actually sending single email addresses. (Note. I've used fake emails here, but not in my tests.)
DECLARE
a DBMS_UTILITY.UNCL_ARRAY;
len PLS_INTEGER;
p_list VARCHAR2(200);
BEGIN
p_list := 'test1@isu.edu,test2@gmail.com,test3@dc1315.com,test4@gmail.com';
DBMS_UTILITY.COMMA_TO_TABLE(p_list, len, a);
FOR i IN 1..a.COUNT LOOP
dbms_output.put_line( a(i) );
END LOOP;
END;
I use it like this:
CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(1000);
PRIORITY_HIGH CONSTANT INTEGER := 1;
PRIORITY_NORMAL CONSTANT INTEGER := 3;
PRIORITY_LOW CONSTANT INTEGER := 5;
PROCEDURE SendMail(
Subject IN VARCHAR2,
Message IN OUT CLOB,
ToMail IN VARCHAR_TABLE_TYPE,
FromMail IN VARCHAR2,
FromName IN VARCHAR2,
PRIORITY IN T_MAIL_PRIORITY DEFAULT PRIORITY_NORMAL) IS
SMTP_PORT CONSTANT INTEGER := 25;
SMTP_SERVER CONSTANT VARCHAR2(50):= 'mailhost';
MIME_BOUNDARY CONSTANT VARCHAR2(50) := '====Multipart.Boundary.689464861147414354====';
con UTL_SMTP.CONNECTION;
ret UTL_SMTP.REPLY;
BEGIN
-- setup mail header
con := UTL_SMTP.OPEN_CONNECTION(SMTP_SERVER, SMTP_PORT);
ret := UTL_SMTP.HELO(con, SYS_CONTEXT('USERENV', 'DB_DOMAIN'));
ret := UTL_SMTP.MAIL(con, FromMail);
FOR i IN ToMail.FIRST..ToMail.LAST LOOP
Recipients := Recipients ||ToMail(i)||',';
ret := UTL_SMTP.RCPT(con, ToMail(i));
END LOOP;
ret := UTL_SMTP.OPEN_DATA(con);
UTL_SMTP.WRITE_DATA(con, 'From: "'||FromName||'" <'||FromMail||'>'||UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(con, 'To: '||REGEXP_REPLACE(Recipients, ',$')||UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(con, 'Subject: '||Subject||UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(con, 'Date: '||TO_CHAR(CURRENT_TIMESTAMP, 'Dy, DD Mon YYYY hh24:mi:ss TZHTZM', 'NLS_DATE_LANGUAGE = American')||UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(con, 'X-Priority: '||PRIORITY||UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(con, 'MIME-Version: 1.0' || UTL_TCP.CRLF);
...
END;
SendMail(
'Come join me for lunch at 11:07.',
Message,
VARCHAR_TABLE_TYPE('test1@isu.edu', 'test2@gmail.com', 'test3@dc1315.com', 'test4@gmail.com'),
'scholar@isu.edu',
'scholar');
I think it works the same if you like to add Bcc and/or Cc addresses.
See also how to export data from log table to email body in oracle