我使用以下程序发送电子邮件:
procedure write_clob(p_connection in out nocopy connection, p_clob in out nocopy clob)
is
v_len integer;
v_index integer;
begin
v_len := dbms_lob.getlength(p_clob);
v_index := 1;
while v_index <= v_len loop
utl_smtp.write_data(p_connection, dbms_lob.substr(p_clob, 32000, v_index));
v_index := v_index + 32000;
end loop;
end write_clob;
长电子邮件似乎被截断了。我测试了v_len == 28811的消息,小于32000.但是,我注意到如果我将缓冲区大小更改为3200,它不会被截断:
procedure write_clob(p_connection in out nocopy connection, p_clob in out nocopy clob)
is
v_len integer;
v_index integer;
begin
v_len := dbms_lob.getlength(p_clob);
v_index := 1;
while v_index <= v_len loop
utl_smtp.write_data(p_connection, dbms_lob.substr(p_clob, 3200, v_index));
v_index := v_index + 3200;
end loop;
end write_clob;
我试过其他一些尺码,例如30000和28000,但它仍然被截断。请注意,28000小于消息长度 - 28811.此外,utl_smtp_write_data
接受varchar2,最多允许32767:
UTL_SMTP.WRITE_DATA (
c IN OUT NOCOPY connection,
data IN VARCHAR2 CHARACTER SET ANY_CS);
我可以使用3200作为我的缓冲区大小,但我不想在不了解正在发生的事情的情况下应用bandaid修复。
有谁能帮助我理解为什么会出现这种奇怪的行为?谢谢!
我正在使用Oracle 11.2.0.3.0。
答案 0 :(得分:1)
我们遇到了同样的问题,神奇的数字似乎是2000。如果您看到3,200个有效,那么我猜您是否传递了单字节字符数据,实际限制为4,000。
在反对这个问题之后,我有一个&#34; duh?&#34;时刻(带有不确定的问号)。我一直在读,写入数据的限制应该是32k,但调用write_data()
时的变量类型是varchar2。虽然pl / sql中的varchar2应该允许最多32k,但我怀疑数据库 varchar2限制为4,000字节是在utl_smtp.write_data()
函数内强加的 - 无论是由于某些内部限制,或者通过明确截断传入的缓冲区,我不知道。
我建议将块大小保持在2,000或更小,以避免任何双字节字符集问题。实际上,网上的每个例子似乎都使用1,900 ......一个奇数,其存在可以追溯到asktom.oracle.com网站上的13岁代码:
引用:
我希望我记得为什么它是在1900字节块,但那是在9年前。我想我应该有 更具体的评论。
泰勒
我发现这比我可能表达的更有趣。