我有一个pl / sql程序,通过电子邮件发送给很多人(20,000+)。我的问题与utl_mail包有关,当连接实际打开到电子邮件服务器时。
示例:
BEGIN
...
OPEN CUR_person;
FETCH CUR_person INTO REC_person;
WHILE CUR_person%FOUND
LOOP
UTL_MAIL.send(sender => 'me@address.com',
recipients => 'you@address.com',
subject => 'Test Mail',
message => 'Hello World',
mime_type => 'text/html');
FETCH CUR_person INTO REC_person;
END LOOP;
...
END;
/
我想知道连接是否每个人打开一次,或者是否为第一个人打开,并且在程序完成之前保持打开状态?
如果每个人打开一次 - 编码错误吗?如果我遇到不良数据,它会炸弹吗?
如果需要更多信息,请询问。谢谢!
答案 0 :(得分:6)
UTL_MAIL
隐藏了SMTP
API UTL_SMTP
。通常优选易于使用。如果您看到UTL_SMTP
,您会注意到您必须为每个电子邮件地址执行utl_smtp.Rcpt
,不幸的是,它一次只接受一个电子邮件ID。因此,对于多个电子邮件地址说了这个,底层逻辑是相同的,即遍历电子邮件地址并为每个电子邮件地址调用utl_smtp.Rcpt
。更好的解决方案是使用电子邮件分发列表,即一个电子邮件ID,其中包含一组其他电子邮件ID。因此,对于UTL_SMTP
,它看起来像下面的那样 -
declare
v_From VARCHAR2(80) := 'yourhelper@fun.com';
v_cc VARCHAR2(80) := 'gethelp@fun.com';
v_Recipient VARCHAR2(80) := 'yourhelper@fun.com';
v_Subject VARCHAR2(80) := 'test Subject';
v_Mail_Host VARCHAR2(50) := 'hub.fun.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.Rcpt(v_Mail_Conn, v_cc); -- To CC recepient
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: ' || v_cc || crlf ||
'Content-Type: text/html;' ||crlf ||
'Hello this is a test email');
utl_smtp.Quit(v_mail_conn);
end;
我没有看到任何错误的编程方式,如果你有多个电子邮件ID,它是唯一的方法.Oracle引擎需要将电子邮件的有效负载提交给SMTP服务器(由you)对于每个电子邮件ID,比如将消息提交到队列。一个相当明显的建议是创建一对Distribution List,其中包含一堆均匀分布的电子邮件ID,并使用DL ID而不是实际的电子邮件ID。
这是我的“Ask Tom”问题之一,可能会清楚这一点。
另一种快速方法是修改代码以构建逗号分隔的电子邮件地址字符串,因为UTL_MAIL
可以接受以逗号分隔的电子邮件地址,例如 -
BEGIN
...
email_list VARCHAR2(10000) := NULL;
email_count NUMBER(10) := 0;
FOR c_rec in CUR_person
LOOP
email_list := c_rec.CUR_person || ' , ' || email_list;
email_count := email_count +1;
if (email_count = 100) --100 email ids at a time
then
UTL_MAIL.send(sender => 'me@address.com',
recipients => email_list,
subject => 'Test Mail',
message => 'Hello World',
mime_type => 'text/html');
email_list := NULL;
email_count := 0;
end if;
END LOOP
...
END;
/