2011-10-13 59 views
2

我們有一個表文件保存爲BLOBPL/SQL發送帶附件的電子郵件?

我寫了一個代碼,將這些文件作爲附件發送給我們!

目前爲止一切正常,但文件(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); 

有什麼建議嗎?

回答

5

這裏是我用它來做到這一點

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原料(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。


* EDIT - >附加信息*


我們與的假設是相同的:

- >假設v_offset 1 開始 - > v_buffer_size承擔57

我注意到,有一個命令,命令你必須遵循的得到它的工作(值得注意的是,把未來的附件到了END身體!!!

  1. 連接LOGIC
  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); 
+0

看着代碼,我看到它和我的代碼之間沒有推論!!!即使我有相同的緩衝區和索引值! –

+0

@ Data-Base;添加了一些評論,主要是確保附件在電子郵件的結尾處,即在電子郵件關閉之前。 – Harrison

+0

現在我想出來了,我錯過了 - 強制重新啓動可能會改變l_buff_size:= 57; l_idx:= 1;謝謝分配 –

5

蒂姆霍爾有一個偉大的網站(oracle-base),有你在找什麼。特別注意編碼是如何完成的。

我已經用類似的代碼通過發送PL/SQL郵件沒有問題

+0

同意。 Tim公開了一個非常乾淨的代碼,涵蓋了幾乎所有的可能性。 – EAmez