通过MS Exchange从Oracle数据库发邮件时BCC处理异常求助
问题原因及解决方法
核心问题出在邮件头部的BCC字段处理错误:你在邮件的Header中显式列出了BCC收件人的真实地址,而不是仅通过SMTP的RCPT TO命令传递这些收件人信息。MS Exchange服务器会保留邮件头中的BCC字段内容,导致所有收件人在邮件源码中能看到密送地址。
正确的UTL_SMTP实现方式
要实现真正的BCC,需遵循两个原则:
- 通过SMTP的
RCPT TO命令添加所有BCC收件人,但不在邮件头中写入这些地址 - 邮件头中要么省略BCC字段,要么用
Bcc: undisclosed-recipients:;表示存在密送但隐藏具体地址
示例代码:
DECLARE l_conn UTL_SMTP.connection; BEGIN -- 连接Exchange服务器 l_conn := UTL_SMTP.open_connection('exchange.yourdomain.com', 25); UTL_SMTP.helo(l_conn, 'oracle.yourdomain.com'); UTL_SMTP.mail(l_conn, 'sender@yourdomain.com'); -- SMTP层面添加所有收件人:TO/CC/BCC都通过RCPT TO传递 UTL_SMTP.rcpt(l_conn, 'to_user@yourdomain.com'); UTL_SMTP.rcpt(l_conn, 'cc_user@yourdomain.com'); UTL_SMTP.rcpt(l_conn, 'bcc_user@yourdomain.com'); -- 开始写入邮件内容 UTL_SMTP.open_data(l_conn); -- 邮件头仅包含TO和CC,不写真实的BCC地址 UTL_SMTP.write_data(l_conn, 'To: to_user@yourdomain.com' || UTL_TCP.crlf); UTL_SMTP.write_data(l_conn, 'Cc: cc_user@yourdomain.com' || UTL_TCP.crlf); -- 可选:添加隐藏的BCC标识 UTL_SMTP.write_data(l_conn, 'Bcc: undisclosed-recipients:;' || UTL_TCP.crlf); UTL_SMTP.write_data(l_conn, 'Subject: 测试密送邮件' || UTL_TCP.crlf); UTL_SMTP.write_data(l_conn, UTL_TCP.crlf); -- 头与正文的分隔线 UTL_SMTP.write_data(l_conn, '这是一封测试密送邮件,BCC收件人地址不会被其他收件人看到。' || UTL_TCP.crlf); UTL_SMTP.close_data(l_conn); UTL_SMTP.quit(l_conn); END; /
BCC使用注意事项
- 严格区分SMTP命令与邮件头:BCC收件人仅通过
RCPT TO命令告知邮件服务器,绝对不要在邮件头中列出真实地址,否则会被所有收件人看到。 - Exchange服务器特性:Exchange不会自动移除邮件头中的BCC字段内容,必须手动避免写入真实地址,否则密送失效。
- 优先使用UTL_MAIL:如果Oracle版本支持,UTL_MAIL是更上层的封装,会自动处理BCC的隐藏逻辑,无需手动管理SMTP命令和邮件头,出错概率更低。
- 测试验证:发送测试邮件后,查看邮件的完整源码(而非客户端显示的收件人列表),确认BCC地址未出现在邮件头中。
- 服务器中继权限:确保Oracle服务器被Exchange允许中继到所有BCC收件人(包括外部域地址,如果涉及的话),否则会出现发送失败。
- 批量密送的性能:如果BCC收件人数量较多,需注意Exchange的收件人数量限制,避免触发反垃圾邮件规则。
内容的提问来源于stack exchange,提问作者Volker Heiselmayer
相关产品推荐
相关产品推荐

