红色部分为何要用每次截取1900个字符呢,这是有什么协议或文件支持还是什么的如果把1900更改的大于10000则写出的html邮件会丢失格式,8000byte好象没问题。
Create Or Replace Procedure Html_Email(p_To            In Varchar2,
                                       p_From          In Varchar2,
                                       p_Subject       In Varchar2,
                                       p_Text          In Varchar2 Default Null,
                                       p_Html          In Varchar2 Default Null,
                                       p_Smtp_Hostname In Varchar2,
                                       p_Smtp_Portnum  In Varchar2) Is
  l_Boundary   Varchar2(255) Default 'a1b2c3d4e3f2g1';
  l_Connection Utl_Smtp.Connection;
  l_Body_Html  Clob := Empty_Clob; --This LOB will be the email message
  l_Offset     Number;
  l_Ammount    Number;
  l_Temp       Varchar2(32767) Default Null;
Begin
  l_Connection := Utl_Smtp.Open_Connection(p_Smtp_Hostname, p_Smtp_Portnum);
  Utl_Smtp.Helo(l_Connection, p_Smtp_Hostname);
  Utl_Smtp.Mail(l_Connection, p_From);
  Utl_Smtp.Rcpt(l_Connection, p_To);  l_Temp := l_Temp || 'MIME-Version: 1.0' || Chr(13) || Chr(10);
  l_Temp := l_Temp || 'To: ' || p_To || Chr(13) || Chr(10);
  l_Temp := l_Temp || 'From: ' || p_From || Chr(13) || Chr(10);
  l_Temp := l_Temp || 'Subject: ' || p_Subject || Chr(13) || Chr(10);
  l_Temp := l_Temp || 'Reply-To: ' || p_From || Chr(13) || Chr(10);
  l_Temp := l_Temp || 'Content-Type: multipart/alternative; boundary=' ||
            Chr(34) || l_Boundary || Chr(34) || Chr(13) || Chr(10);  ----------------------------------------------------
  -- Write the headers
  Dbms_Lob.Createtemporary(l_Body_Html, False, 10);
  Dbms_Lob.Write(l_Body_Html, Length(l_Temp), 1, l_Temp);  ----------------------------------------------------
  -- Write the text boundary
  l_Offset := Dbms_Lob.Getlength(l_Body_Html) + 1;
  l_Temp   := '--' || l_Boundary || Chr(13) || Chr(10);
  l_Temp   := l_Temp || 'content-type: text/plain; charset=us-ascii' ||
              Chr(13) || Chr(10) || Chr(13) || Chr(10);
  Dbms_Lob.Write(l_Body_Html, Length(l_Temp), l_Offset, l_Temp);  ----------------------------------------------------
  -- Write the plain text portion of the email
  l_Offset := Dbms_Lob.Getlength(l_Body_Html) + 1;
  Dbms_Lob.Write(l_Body_Html, Length(p_Text), l_Offset, p_Text);  ----------------------------------------------------
  -- Write the HTML boundary
  l_Temp   := Chr(13) || Chr(10) || Chr(13) || Chr(10) || '--' ||
              l_Boundary || Chr(13) || Chr(10);
  l_Temp   := l_Temp || 'content-type: text/html;' || Chr(13) || Chr(10) ||
              Chr(13) || Chr(10);
  l_Offset := Dbms_Lob.Getlength(l_Body_Html) + 1;
  Dbms_Lob.Write(l_Body_Html, Length(l_Temp), l_Offset, l_Temp);  ----------------------------------------------------
  -- Write the HTML portion of the message
  l_Offset := Dbms_Lob.Getlength(l_Body_Html) + 1;
  Dbms_Lob.Write(l_Body_Html, Length(p_Html), l_Offset, p_Html);  ----------------------------------------------------
  -- Write the final html boundary
  l_Temp   := Chr(13) || Chr(10) || '--' || l_Boundary || '--' || Chr(13);
  l_Offset := Dbms_Lob.Getlength(l_Body_Html) + 1;
  Dbms_Lob.Write(l_Body_Html, Length(l_Temp), l_Offset, l_Temp);  ----------------------------------------------------
  -- Send the email in 1900 byte chunks to UTL_SMTP
  l_Offset  := 1;
  l_Ammount := 1900;
  Utl_Smtp.Open_Data(l_Connection);
  While l_Offset < Dbms_Lob.Getlength(l_Body_Html) Loop
    Utl_Smtp.Write_Data(l_Connection,
                        Dbms_Lob.Substr(l_Body_Html, l_Ammount, l_Offset));
    l_Offset  := l_Offset + l_Ammount;
    l_Ammount := Least(1900, Dbms_Lob.Getlength(l_Body_Html) - l_Ammount);
  End Loop;
  Utl_Smtp.Close_Data(l_Connection);
  Utl_Smtp.Quit(l_Connection);
  Dbms_Lob.Freetemporary(l_Body_Html);

End;
/
Show Errors

解决方案 »

  1.   

    邮件协议没有怎么研究,但是HTTP的协议前一定要有固定的协议段,数据基本是固定的,内容负载后面
      

  2.   

    这个我看了一下,也没看出啥问题,然后到TOM的网站上去看了你说的这个东东。I've seen this "magic" number - 1900 byte chunks - couple times on this site, and I'm wondering 
    where this number comes from.The RFC 821 SMTP (
    http://www.ietf.org/rfc/rfc0821.txt
     says "The maximum total length of a text line including the <CRLF> is 1000 characters (but not 
    counting the leading  dot duplicated for transparency)." The same phrase is used in UTL_SMTP 
    package description in Supplied PL/SQL Packages guide.Somewhere on the web I found that there is "a restriction of 2000 on the length on a single call to 
    utl_smtp.write_data"However, I was able to send data chunks of more than 2000 characters. So what's the maximum length 
    of "data" parameter in utl_smtp.write_data that we should not exceed?早有人问了这个问题,但TOM没有回答。所以,我认为这是个utl_smtp实现邮件协议的问题
      

  3.   

    coder ;   tom这个页面你往下看看,还有人问了这个问题,tom回答了。但我不太清楚意思你知道如何在那上面提问么?如能可否代问下,谢谢因为我如果把1900修改成10000 html邮件的<tr><td>表格就会出现错行。格式混乱
      

  4.   

    嗯,我也看了TOM后面的回答,他说可以最大到32767,显示TOM也没有测试(或者说,没测试出你的问题)。asktom上,每个帖子的最后,有一个“Write a Review”按钮,点击这个按钮就可以回复了。我也没在上面问过
      

  5.   

    coderI wish I remembered why it was in 1900 byte chunks, but that was 9 years ago.I guess I should have been more specific with the comment.tyler;-------------------------------------------
    today,in the year 2010,any limit it was working around back then is notrelevant anymore.Feel free to increase it.test it and use it.
    or free free to leave it be.since it doesn't harm anything the way it isIn short- it is your code now,all of the stuff on this site is a"demo to get the concept across" - feel free to use and reuse as you see fit这是我在上面问的,tyler的回复,帮解释下,3q