2

如何将 Oracle PL/SQL 包中的电子邮件发送给多个收件人?我在 oracle 包中有以下 pl/sql 过程,它仅适用于一个接收器。我需要改进它的功能,让它可以同时向多个接收者发送电子邮件,例如“致:David Festool;Peter Makita;John Dewalt”。任何可以帮助我的机构将不胜感激!请给我修改后的代码。


procedure email(p_recip   in varchar2,
                p_subject in varchar2,
                p_message in varchar2) is

  c   utl_smtp.connection;
  msg varchar2(4000);

  procedure send_header(name in varchar2, header in varchar2) as
  begin
    utl_smtp.write_data(c, name || ': ' || header || utl_tcp.crlf);
  end;
begin
  --Open SMTP connection
  c := utl_smtp.open_connection('ExchangeServerName');

  -- Write SMTP header
  utl_smtp.helo(c, 'ExchangeServerName');
  utl_smtp.mail(c, 'Email@MyCompany.on.ca');
  utl_smtp.rcpt(c, p_recip);
  utl_smtp.open_data(c);
  send_header('From', '"Title" <Email@MyCompany.on.ca');
  send_header('To', p_recip);
  send_header('Subject', p_subject);
  send_header('Mime-Version', '1.0');
  send_header('Content-Type', 'multipart/mixed; boundary="DMW.Boundary.605592468"');

  -- Write MIME boundary line for the message body
  msg := utl_tcp.crlf || '--DMW.Boundary.605592468' || utl_tcp.crlf ||
         'Content-Type: text/plain' || utl_tcp.crlf ||
         'Content-Transfer-Encoding: 7bit' || utl_tcp.crlf ||
         utl_tcp.crlf;
  utl_smtp.write_data(c, msg);

  -- Write message body
  utl_smtp.write_data(c, p_message || utl_tcp.crlf);

  -- Clean up
  utl_smtp.close_data(c);
  utl_smtp.quit(c);
exception
  when utl_smtp.transient_error or utl_smtp.permanent_error then
    begin
      utl_smtp.quit(c);
    exception
      when utl_smtp.transient_error or utl_smtp.permanent_error then
        null;
        -- When the SMTP server is down or unavailable, we don't have
      -- a connection to the server. The QUIT call will raise an
      -- exception that we can ignore.
    end;

    raise_application_error(-20000, 'Failed to send mail due to the following error: ' ||
                             sqlerrm);
end;
--------------------------------------------------------------
4

3 回答 3

8

您需要utl_smtp.rcpt多次调用,每个收件人一次;您不能在一次调用中给出值列表。

从 UTL_SMTP.RCPT 文档

要将消息发送给多个收件人,请多次调用此例程。每次调用都会安排发送到单个电子邮件地址。

这意味着您不能真正传递一串名称,除非您乐于解析出各个地址;可能更容易传递一组值。

标题TO是一个单独的问题;如果我没记错的话,那实际上只是为了显示,并且将地址作为 arcpt不在( TOor CC) 标头中是 BCC 的实现方式。虽然需要引用...

这是一篇旧的 AskTom 文章,展示了这一点。jonearles 使用 UTL_MAIL 的建议应该被调查。

于 2013-07-18T22:53:22.330 回答
1

格式为:

UTL_MAIL.SEND (sender, recipientlist, cc, bcc, subject, Message, mime_type, priority)

recipientlist、cc 和 bcc 参数都是以逗号分隔的收件人、复制到和密送电子邮件地址列表。

sender、subject、message 和 mime_type 参数都是单项字段。

于 2014-07-30T07:40:05.527 回答
1

只需使用更改代码运行以下程序:

v_Mail_Host VARCHAR2(50) := 'uacemail.rxcorp.com'; -- 您的主机 IP 或名称


执行:

开始
prc_email_send( 'sohid10@yahoo.com', -- 来自
'smolla@bd.imshealth.com' 的邮件,---收件人
'sohidatibd@gmail.com;smokarem@bd.imshealth.com',-- 抄送列表
'这是邮件主题',
'这是邮件正文');
结尾;
/

程序代码:

Create or replace procedure prc_email_send(
v_From      VARCHAR2,
v_Recipient VARCHAR2,
v_cc_list varchar2,
v_Subject   VARCHAR2,   
v_Mail_body VARCHAR2
)

is
v_Mail_Host VARCHAR2(50) := 'uacemail.rxcorp.com';
v_Mail_Conn utl_smtp.Connection;

crlf        VARCHAR2(2)  := chr(13)||chr(10);
CC_parties varchar2(2000);

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);

 for i in (SELECT LEVEL AS id, REGEXP_SUBSTR(v_cc_list, '[^;]+', 1, LEVEL) AS cc_email_name
           FROM dual
           CONNECT BY REGEXP_SUBSTR(v_cc_list, '[^;]+', 1, LEVEL) IS NOT NULL) loop
    CC_parties := CC_parties||';'|| i.cc_email_name;
  utl_smtp.Rcpt(v_Mail_Conn,i.cc_email_name);

end loop;


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 ||
                'Cc: '     || CC_parties|| crlf ||
                'Content-Type: text/html;' ||crlf ||
                v_Mail_body);
utl_smtp.Quit(v_mail_conn);

EXCEPTION
   WHEN OTHERS THEN
      BEGIN
     DBMS_OUTPUT.put_line (
        SUBSTR (
              'Unable to send mail to recipients. Error message: '
              || SQLERRM
              || CHR (10)
              || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE (),
                 1,255));
     UTL_SMTP.quit (v_Mail_Conn);
     UTL_TCP.close_all_connections;
  EXCEPTION
     WHEN UTL_SMTP.transient_error OR UTL_SMTP.permanent_error   THEN
        NULL;     
  END;
END;

这对我自己很好

于 2017-07-14T10:40:02.757 回答