0

PL/SQL blob variable に有効なファイルが格納されています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()を確認したところ、電子メール メッセージが最後のチャンクを上書きするのではなく、追加されることが確認されました。

また、オラクルのメッセージ ボードで解決策を検索しました (実際、上記の 2 番目の手順は、そこで見つけたいくつかの投稿から派生したものです)。ただし、添付ファイルを完全にそのまま送信することはまだできていません。

誰かが私が間違っていることを見ることができますか?

4

1 に答える 1