当我发送大尺寸附件的邮件时,我收到服务不可用的消息。
要求是编写一个程序,该程序将提取整个表的数据,并将提取作为excel附件发送到邮件中。 table_name和email id将作为参数传递。
我尝试了CLOB。从表中获取数据并将其作为XML结构放入CLOB中。然后我发送附件为xls的邮件,其中包含CLOB中的数据。
对于较少数量的记录(最大约2k)工作正常。但是当我检查更多数量的记录时,程序会抛出UTL_SMTP瞬态错误 - 服务不可用。
BEGIN
vsql := 'SELECT * from test_table';
V_CLOB := get_query_output(vsql);
v_lob := v_clob;
v_connection := UTL_SMTP.open_connection('abcd.efgh.com');
UTL_SMTP.helo(v_connection, 'abcd.efgh.com');
UTL_SMTP.mail(v_connection, p_from);
UTL_SMTP.rcpt(v_connection, p_to);
UTL_SMTP.open_data(v_connection);
UTL_SMTP.write_data(v_connection, 'From: ' || p_from || UTL_TCP.crlf);
UTL_SMTP.WRITE_DATA(V_CONNECTION, 'To: ' || P_TO || UTL_TCP.CRLF);
utl_smtp.write_data(v_connection, 'Cc: ' || p_cc || utl_tcp.crlf);
UTL_SMTP.write_data(v_connection,
'Subject: NPI Error Report' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, 'MIME-Version: 1.0' || UTL_TCP.crlf);
DBMS_OUTPUT.PUT_LINE('at position 4');
UTL_SMTP.write_data(v_connection,
'Content-Type: multipart/mixed; boundary="' ||
c_mime_boundary || '"' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection,
'This is a multi-part message in MIME format.' ||
UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection,
'--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.WRITE_DATA(V_CONNECTION,
'Content-Type: text/plain' || UTL_TCP.CRLF);
-- Set up attachment header
UTL_SMTP.write_data(v_connection,
'Content-Disposition: attachment; filename="' ||
'Error_Report.xls' || '"' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
-- start attachment
V_LEN := DBMS_LOB.GETLENGTH(V_CLOB);
DBMS_OUTPUT.PUT_LINE('V_LEN :=' || V_LEN);
for I in 0 .. TRUNC((V_LEN - 1) / V_INDEX) LOOP
UTL_SMTP.WRITE_DATA(v_connection,
DBMS_LOB.SUBSTR(V_LOB, V_INDEX, I * V_INDEX + 1));
END LOOP;
-- -- End attachment UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
UTL_SMTP.WRITE_DATA(V_CONNECTION,
'--' || C_MIME_BOUNDARY || '--' || UTL_TCP.CRLF);
UTL_SMTP.close_data(v_connection); UTL_SMTP.quit(v_connection);
EXCEPTION WHEN OTHERS THEN
BEGIN
UTL_SMTP.QUIT(v_connection);
raise;
END;
END;
当表中有大量记录(几乎> 2k)时,我得到的错误代码: enter image description here
Error report -
ORA-29277: invalid SMTP operation
ORA-06512: at "SYS.UTL_SMTP", line 82
ORA-06512: at "SYS.UTL_SMTP", line 212
ORA-06512: at "SYS.UTL_SMTP", line 622
ORA-06512: at "SYS.UTL_SMTP", line 633
ORA-06512: at line 328
ORA-29278: SMTP transient error: 421 Service not available
29277. 00000 - "invalid SMTP operation"
*Cause: The SMTP operation was invalid at the current stage of the SMTP
transaction.
*Action: Retry the SMTP operation at the appropriate stage of the SMTP
transaction.
答案 0 :(得分:0)
错误很奇怪,通常这与附加文件的大小无关。 也许您的附件会导致特殊字符出现问题,请尝试发送这样的邮件:
ClobLen PLS_INTEGER;
amount BINARY_INTEGER := 8192;
buffer VARCHAR2(16384);
offset PLS_INTEGER := 1;
BEGIN
....
UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
UTL_SMTP.write_data(con, '--'||C_MIME_BOUNDARY || Utl_Tcp.CRLF);
UTL_SMTP.write_data(con, 'Content-Type: text/plain; name="Error_Report.xls"'|| Utl_Tcp.CRLF);
UTL_SMTP.write_data(con, 'Content-Disposition: attachment; filename="Error_Report.xls"'|| Utl_Tcp.CRLF);
UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
offset := 1;
ClobLen := DBMS_LOB.GETLENGTH(V_LOB);
LOOP
EXIT WHEN offset > ClobLen;
DBMS_LOB.READ(V_LOB, amount, offset, BUFFER);
UTL_SMTP.write_raw_data(con, Utl_Raw.cast_to_raw(BUFFER));
offset := offset + amount;
END LOOP;
UTL_SMTP.write_data(con, Utl_Tcp.CRLF);
UTL_SMTP.write_data(con, '--'||C_MIME_BOUNDARY||'--' || Utl_Tcp.CRLF);
也许错误不是由主块引起的,而是由异常处理程序引起的。从
更改您的异常处理程序EXCEPTION WHEN OTHERS THEN
BEGIN
UTL_SMTP.QUIT(v_connection);
raise;
END;
END;
到
EXCEPTION
WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
UTL_SMTP.quit(v_connection);
RAISE;
END;