Oracle 19c中UTL_SMTP发送邮件空格被截断的问题求助
UTL_SMTP发送HTML邮件保留连续空格的解决办法
环境与问题
- 数据库:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.20.0.0.0
- 场景:用UTL_SMTP发送HTML格式邮件,能正常收到,但正文里的连续空格(包括前导、尾随)被自动截断,无法保留预期格式。
原代码如下:
declare l_mail_conn UTL_SMTP.connection; l_boundary VARCHAR2(50) := ' =abc1234321cba='; p_smtp_host VARCHAR2 (100) := 'smtp.cac.com'; p_smtp_port NUMBER := 25; p_to VARCHAR2(100) := 'hello@gmail.com'; p_subject VARCHAR2(100) := 'Hello'; p_html_msg VARCHAR2(100) := ' ' ||'ABC <br>' || ' ' || 'DEF'; BEGIN l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port); UTL_SMTP.helo(l_mail_conn, p_smtp_host); UTL_SMTP.mail(l_mail_conn, p_to); UTL_SMTP.rcpt(l_mail_conn, p_to); UTL_SMTP.open_data(l_mail_conn); UTL_SMTP.write_data(l_mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'To: ' || p_to || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'From: ' || p_to || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || p_subject || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'MIME-Version: 1.0' || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Content-Type: multipart/alternative; boundary="' || l_boundary || '"' || UTL_TCP.crlf || UTL_TCP.crlf); IF p_html_msg IS NOT NULL THEN UTL_SMTP.write_data(l_mail_conn, '--' || l_boundary || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Content-Type: text/html; charset="iso-8859-1"' || UTL_TCP.crlf || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, p_html_msg); UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf); END IF; UTL_SMTP.write_data(l_mail_conn, '--' || l_boundary || '--' || UTL_TCP.crlf); UTL_SMTP.close_data(l_mail_conn); UTL_SMTP.quit(l_mail_conn); END; /
问题原因
这不是UTL_SMTP的问题,是HTML的默认渲染规则:浏览器/邮件客户端会把连续的空白字符(空格、换行、制表符)合并成单个空格,所以你写的连续空格会被自动压缩。
解决方法
有两种常用的办法可以保留空格格式:
方法1:使用<pre>标签
<pre>标签会保留文本的原始格式,包括空格、换行和缩进,适合需要保留排版的内容。修改p_html_msg的定义:
p_html_msg VARCHAR2(200) := '<pre>' || ' ABC' || '<br>' || ' DEF' || '</pre>';
方法2:用 替换普通空格
把每个需要保留的空格替换成HTML空格实体 ,连续空格就用多个 。比如前导的14个空格就写成14个 :
p_html_msg VARCHAR2(200) := ' ' ||'ABC <br>' || ' ' || 'DEF';
修改后的完整代码示例(以<pre>为例)
declare l_mail_conn UTL_SMTP.connection; l_boundary VARCHAR2(50) := ' =abc1234321cba='; p_smtp_host VARCHAR2 (100) := 'smtp.cac.com'; p_smtp_port NUMBER := 25; p_to VARCHAR2(100) := 'hello@gmail.com'; p_subject VARCHAR2(100) := 'Hello'; -- 使用<pre>标签保留空格格式 p_html_msg VARCHAR2(200) := '<pre>' || ' ABC' || '<br>' || ' DEF' || '</pre>'; BEGIN l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port); UTL_SMTP.helo(l_mail_conn, p_smtp_host); UTL_SMTP.mail(l_mail_conn, p_to); UTL_SMTP.rcpt(l_mail_conn, p_to); UTL_SMTP.open_data(l_mail_conn); UTL_SMTP.write_data(l_mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'To: ' || p_to || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'From: ' || p_to || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || p_subject || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'MIME-Version: 1.0' || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Content-Type: multipart/alternative; boundary="' || l_boundary || '"' || UTL_TCP.crlf || UTL_TCP.crlf); IF p_html_msg IS NOT NULL THEN UTL_SMTP.write_data(l_mail_conn, '--' || l_boundary || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, 'Content-Type: text/html; charset="iso-8859-1"' || UTL_TCP.crlf || UTL_TCP.crlf); UTL_SMTP.write_data(l_mail_conn, p_html_msg); UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf); END IF; UTL_SMTP.write_data(l_mail_conn, '--' || l_boundary || '--' || UTL_TCP.crlf); UTL_SMTP.close_data(l_mail_conn); UTL_SMTP.quit(l_mail_conn); END; /
内容的提问来源于stack exchange,提问作者VKD
相关产品推荐
相关产品推荐

