Oracle存储过程发送带CSV附件邮件表头缺失且无法同时加正文
问题原因
- 第一是MIME部分缺少必要的空行分隔:MIME协议规定,每个部分的头部声明(比如Content-Type、Content-Disposition)和实际内容之间必须有一个空行(也就是
UTL_TCP.crlf)。你最初的代码里,附件部分写完Content-Disposition之后没有加空行,导致CSV的第一行表头被邮件客户端识别为附件的MIME头字段直接丢弃,所以附件只有数据没有表头。 - 第二是正文部分格式不完整:你最初的代码里正文部分写完Content-Type之后,直接写了正文内容,没有加空行分隔头和内容,导致正文要么无法显示,要么打乱了后续附件的结构识别。你修改后的版本直接删掉了正文的独立MIME部分,把唯一的MIME部分直接设为附件,自然就没有正文了。
修复方案
替换原代码中邮件内容写入的相关部分即可同时保留正文和带表头的附件,修复后的代码如下:
utl_smtp.OPEN_DATA(v_Mail_Conn); UTL_SMTP.write_data(v_Mail_Conn, 'From: ' || v_From || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'To: ' || v_Recipient || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Subject: ' || REPLACE(v_Subject, '[DATE]',TO_CHAR(sysdate,'DD.MM.YYYY')) || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'MIME-Version: 1.0' || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: multipart/mixed; boundary="' || c_mime_boundary || '"' || UTL_TCP.crlf); -- 邮件头和多部分内容之间加空行 UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'This is a multi-part message in MIME format.' || UTL_TCP.crlf); -- 第一部分:邮件正文 UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: text/plain; charset=utf-8' || UTL_TCP.crlf); -- 正文头和内容之间加空行 UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Details' || UTL_TCP.crlf); -- 第二部分:CSV附件 UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: text/csv; charset=utf-8' || UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, 'Content-Disposition: attachment; filename="' || 'myfile.csv' || '"' || UTL_TCP.crlf); -- 附件头和内容之间加空行,这是表头不丢失的核心修复点 UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf); -- 写入附件内容 v_len := DBMS_LOB.getlength(l_clob2); v_index := 1; WHILE v_index <= v_len LOOP UTL_SMTP.write_data(v_Mail_Conn, DBMS_LOB.SUBSTR(l_clob2, 32000, v_index)); v_index := v_index + 32000; END LOOP; -- 结束MIME边界 UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf); UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || '--' || UTL_TCP.crlf); utl_smtp.CLOSE_DATA(v_mail_conn); utl_smtp.Quit(v_mail_conn);
额外优化:将附件的Content-Type从
text/plain改为text/csv,可以避免部分客户端识别附件格式错误,指定charset=utf-8也可以防止文件中出现中文时乱码。
内容的提问来源于stack exchange,提问作者Thejus32
相关产品推荐
相关产品推荐

