4

我们有一个表,其中的文件保存为 BLOB

我编写了一个代码,将这些文件作为附件通过电子邮件发送!

到目前为止一切正常,但是程序无法读取文件(EXCEL,PDF,...等等),只有文本文件和 excel 会打开,但在出现一些错误消息后,PDF 根本无法打开!

这是有问题的代码部分!

utl_smtp.write_data( l_connection, '--'|| l_boundary || utl_tcp.crlf);
utl_smtp.write_data( l_connection, 'Content-Type: application/octet-stream' || utl_tcp.crlf);
utl_smtp.write_data( l_connection, 'Content-Disposition: attachment; filename="' || V_NAME || '"' || utl_tcp.crlf);
utl_smtp.write_data( l_connection, 'Content-Transfer-Encoding: base64' || utl_tcp.crlf );
utl_smtp.write_data( l_connection, utl_tcp.crlf );   

v_length := dbms_lob.getlength(V_BLOB_CONTENT);     

while v_offset < v_length loop
       dbms_lob.read( V(i).BLOB_CONTENT, v_buffer_size, v_offset, v_raw );
       utl_smtp.write_raw_data( l_connection, utl_encode.base64_encode(v_raw) );
       utl_smtp.write_data( l_connection, utl_tcp.crlf );
       v_offset := v_offset + v_buffer_size;
end loop while_loop;     

utl_smtp.write_data( l_connection, utl_tcp.crlf );

有什么建议么?

4

2 回答 2

7

这是我用来执行此操作的程序

  PROCEDURE StreamAttachmentToConn( p_conn       IN OUT utl_smtp.connection
                                   ,p_boundary   IN raw
                                   ,p_FileName   IN VARCHAR2
                                   ,p_FileData   IN BLOB) PARALLEL_ENABLE
  AS
      l_len       integer := 0 ;
      l_idx       integer := 1 ;
      l_buff_size integer := 57 ;
      l_raw       raw(57) ;
  BEGIN

              -- Attachment
            utl_smtp.write_data( p_conn, '--' || p_boundary || utl_tcp.crlf );
            utl_smtp.write_data( p_conn, 'Content-Type: application/octet-stream' || utl_tcp.crlf );
            utl_smtp.write_data( p_conn, 'Content-Disposition: attachment; ' || utl_tcp.crlf );
            utl_smtp.write_data( p_conn, ' filename="' || p_FileName || '"' || utl_tcp.crlf );
            utl_smtp.write_data( p_conn, 'Content-Transfer-Encoding: base64' || utl_tcp.crlf );
            utl_smtp.write_data( p_conn, utl_tcp.crlf );
            -- Loop through the blob
            -- chuck it up into 57-byte pieces
            -- and base64 encode it and write it into the mail buffer
            l_len := dbms_lob.getlength(p_FileData);

            -- force reinit on this may change
            l_buff_size := 57 ;
            l_idx := 1;

            while l_idx < l_len loop
              dbms_lob.read( p_FileData , l_buff_size, l_idx, l_raw );

              utl_smtp.write_raw_data( p_conn, utl_encode.base64_encode(l_raw) );

              utl_smtp.write_data( p_conn, utl_tcp.crlf );

              l_idx := l_idx + l_buff_size;
            end loop;
  END StreamAttachmentToConn;

我用它来为一封电子邮件添加多个附件。对我来说就像一个冠军。

一件事, p_boundary 作为

l_boundary raw(32) := sys_guid();

我看到你已经有一个 l_boundary ,这就是你应该使用的。

这是基于http://christopherbeck.wordpress.com/category/plsql/以及http://www.oracle-base.com/articles/misc/EmailFromOraclePLSQL.php#attachment

然后在您的代码中,只需传入您的 smtp 连接、l_boundary(即 RAW sys_guid 或您正在使用的任何内容、文件名(因为它将出现在电子邮件附件中)和 BLOB。


*编辑 --> 附加信息 *


我们的假设与以下假设相同:

--> 假设 v_offset 以 1 开头 --> v_buffer_size 假设 57

我注意到,您必须遵循一个命令才能使其工作(特别是,将附件放在正文后面的END旁边!!!

  1. 连接逻辑
  2. 添加所有收件人
  3. 标题逻辑:“FROM”,主题
  4. 正文逻辑(正文等)
  5. 附件
  6. 然后在附件关闭电子邮件之后(这就是我在附件之后所拥有的:

utl_smtp.write_data( l_conn, utl_tcp.crlf );

-- Close Email
utl_smtp.write_data( l_conn, '--' || l_boundary || '--' || utl_tcp.crlf );
utl_smtp.write_data( l_conn, utl_tcp.crlf || '.' || utl_tcp.crlf );
utl_smtp.close_data( l_conn );
utl_smtp.quit( l_conn );
于 2011-10-13T12:53:29.463 回答
5

Tim Hall 有一个很棒的网站(oracle-base),里面有你要找的东西。特别注意编码是如何完成的。

我使用类似的代码通过 pl/sql 发送电子邮件没有问题

于 2011-10-13T11:43:38.847 回答