我有一个存储在PL / SQL blob变量attachment_blob_
中的有效文件。假设文件的大小足够小,以下过程可以将文件附加到电子邮件中。
PROCEDURE Write_Mail_Attachment IS BEGIN
Write_Part_Boundary (OUTER_BOUNDARY_);
utl_smtp.write_data (
smtp_conn_,
'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; ' ||
'name="' || attachment_name_ || '"' || utl_tcp.crlf ||
'Content-Transfer-Encoding: base64' || utl_tcp.crlf ||
'Content-Disposition: attachment;filename="'||attachment_name_||'"'||utl_tcp.crlf||utl_tcp.crlf
);
utl_smtp.write_raw_data (smtp_conn_, utl_encode.base64_encode(attachment_blob_));
END Write_Mail_Attachment;
(为了避免含糊不清或“你检查过这种”答案,所有变量都有效。此块中未定义的任何变量都属于父范围。)
当变量attachment_blob_
大于特定大小时,我的问题就开始了。它变得太大而无法由utl_encode.base64_encode()
函数处理,并产生数值或值错误。
好的,我告诉自己,没关系。我需要做的就是将blob
分成多个块。所以我修改程序如下:
PROCEDURE Write_Mail_Attachment IS
chunk_size_ NUMBER := 1900;
offset_ NUMBER := 1;
file_chunk_ RAW(1900);
BEGIN
Write_Part_Boundary (OUTER_BOUNDARY_);
utl_smtp.write_data (
smtp_conn_,
'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; ' ||
'name="' || attachment_name_ || '"' || utl_tcp.crlf ||
'Content-Transfer-Encoding: base64' || utl_tcp.crlf ||
'Content-Disposition: attachment; filename="'||attachment_name_||'"'||utl_tcp.crlf||utl_tcp.crlf
);
WHILE offset_ < Dbms_Lob.GetLength(attachment_blob_) LOOP
Dbms_Lob.Read (attachment_blob_, chunk_size_, offset_, file_chunk_);
utl_smtp.write_raw_data (smtp_conn_, utl_encode.base64_encode(file_chunk_));
offset_ := offset_ + chunk_size_;
END LOOP;
END Write_Mail_Attachment;
现在,此过程执行时没有错误,因为块大小永远不会太大而无法管理utl_encode.base64_encode()
。但现在问题是附加文件到达我的收件箱时已损坏。
当我调查“原始”电子邮件内容时,我可以看到附件内容字符串被裁剪为大约1900个字符。如果我将block_size_
变量定义为50
(而不是1900
),则电子邮件中的原始内容将被截断为大约50个字符。换句话说,好像过程utl_smtp.write_raw_data()
在循环的每次迭代中都覆盖了文件内容的前一部分,所以我只能在电子邮件中找到文件的最后一块何时发送。
我已经验证了utl_smtp.write_raw_data()
上的文档,该文档确认将附加电子邮件,而不是覆盖最后一个块。
我还在Oracle留言板上寻找解决方案,(事实上,我上面的第二个程序来自我在那里发现的一些帖子)。但是,我还没能完全发送附件。
有人能看出我做错了吗?
答案 0 :(得分:1)
你必须记住,Base64将3个字节编码为4个字节,当最后一个组包含少于3个字节时使用'=',检查Wikipedia上的填充部分。字符'='只能放在编码文档的末尾。这就是为什么你的缓冲区长度必须是三的倍数。