使用UTL_SMTP发送存储为Blob的预格式化RFC822邮件问题
问题解决方案
你的方案完全可行,无需重新用UTL_SMTP构建带附件、图片的邮件,只需修正SMTP发送流程即可解决邮件显示原始文本的问题。
问题根源
当前代码的核心错误:
- 错误拆分SMTP DATA阶段(使用
open_data/close_data),并额外插入多余换行符,破坏了原RFC822邮件的格式结构。 - 完整邮件内容(含头部)被错误插入到SMTP流程的不当节点,导致邮件服务器无法正确解析邮件格式。
修正后的完整代码
create or replace PROCEDURE barry_test_proc ( p_errbuf OUT NOCOPY VARCHAR2, p_retcode OUT NOCOPY NUMBER ) AS p_mail_host varchar2(1000) := 'xyz.local'; p_from varchar2(1000) := '1@test.com'; p_to varchar2(1000) := '2@test.com'; l_mail_conn utl_smtp.connection; lblob blob; BEGIN FND_FILE.PUT_LINE(FND_FILE.LOG,'Called '); -- 建立SMTP连接 FND_FILE.PUT_LINE(FND_FILE.LOG,'Opening Connection '); l_mail_conn := utl_smtp.open_connection(p_mail_host, 25); FND_FILE.PUT_LINE(FND_FILE.LOG,'Helo '); utl_smtp.helo(l_mail_conn, p_mail_host); -- 可选:设置SMTP Envelope发件人和收件人(可与邮件头部From/To不一致) utl_smtp.mail(l_mail_conn, p_from); utl_smtp.rcpt(l_mail_conn, p_to); -- 读取数据库中存储的完整RFC822邮件Blob FND_FILE.PUT_LINE(FND_FILE.LOG,'Fetch message '); select content_blob into lblob from FAC_OC_EMAIL_META_DATA where id = 121; -- 直接发送完整邮件内容:UTL_SMTP.DATA自动处理SMTP DATA阶段全流程 FND_FILE.PUT_LINE(FND_FILE.LOG,'Sending mail content '); utl_smtp.data(l_mail_conn, lblob); FND_FILE.PUT_LINE(FND_FILE.LOG,'Quiting '); utl_smtp.quit(l_mail_conn); FND_FILE.PUT_LINE(FND_FILE.LOG,'Finished '); END;
关键说明
- 直接用
UTL_SMTP.DATA发送Blob:该方法支持传入完整的RFC822格式Blob邮件,自动完成DATA命令发送、内容传输、结束符.发送的全流程,无需手动调用open_data/close_data。 - 保留原始格式:无需将Blob转成Clob,也不要插入额外换行符,直接发送原始Blob可确保邮件格式完全符合RFC822标准,避免编码或格式损坏。
- Envelope与Header的区别:SMTP的
MAIL FROM/RCPT TO是信封地址,可与邮件头部的From/To不一致(比如群发场景),按需设置即可。
内容的提问来源于stack exchange,提问作者Barry Brierley
相关产品推荐
相关产品推荐

