PL/SQL 发送带有附件的电子邮件吗?

发布于 2024-12-09 18:43:18 字数 1064 浏览 2 评论 0原文

我们有一个表,其中文件保存为 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 );

有什么建议吗?

we have a table with files saved as BLOB

I write a code that email these files as an attachment!

everything works fine so far, but the files (EXCEL,PDF, ... what ever) are not readable by the programs, only text files and excel will open but after some error message, where PDFs all not be opened at all!

here is the part of the code in question!

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 );

any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筱武穆 2024-12-16 18:43:18

这是我用来执行的一个过程,

  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. 标题逻辑:“发件人”,主题
  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 );

here is a procedure that I use to do just that

  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;

I use this to add multiple attachments to a single email. works like a champ for me.

one thing, the p_boundary is passed in as

l_boundary raw(32) := sys_guid();

I see that you already have an l_boundary and that is what you should use.

this is based on http://christopherbeck.wordpress.com/category/plsql/ as well as http://www.oracle-base.com/articles/misc/EmailFromOraclePLSQL.php#attachment
.

then in your code, just pass in your smtp connection, the l_boundary (ie RAW sys_guid or whatever you are using, the name of the file (as it will appear on the email attachment), and the BLOB.


*EDIT --> additional information *


Ours are the same with the assumption of:

--> assume v_offset starts with 1
--> v_buffer_size assume 57

But I have noticed that there is an order that you must follow to get it to work (notably, put the attachments next to the END after body!!!

  1. Connect LOGIC
  2. add all of the recipients
  3. Header LOGIC :"FROM", Subject
  4. Body logic (body text etc)
  5. Attachments
  6. then after the attachments close the email (this is specifically what I have after my attachments:

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 );
一江春梦 2024-12-16 18:43:18

Tim Hall 有一个很棒的网站 (oracle-base),其中包含你在寻找什么。特别注意编码是如何完成的。

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

Tim Hall has a great site (oracle-base) that has what you're looking for. Note in particular how the encoding is done.

I've used similar code to send emails via pl/sql without problem

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文