我有一个存储在 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 留言板的解决方案,(实际上,我上面的第二个过程来自我在那里找到的一些帖子)。但是,我还不能完整地发送附件。
有人可以看到我做错了什么吗?