UTL_SMTP服务不可用错误

时间:2017-05-24 05:01:41

标签: oracle email plsql smtp email-attachments

当我发送大尺寸附件的邮件时,我收到服务不可用的消息。

要求是编写一个程序,该程序将提取整个表的数据,并将提取作为excel附件发送到邮件中。 table_name和email id将作为参数传递。

我尝试了CLOB。从表中获取数据并将其作为XML结构放入CLOB中。然后我发送附件为xls的邮件,其中包含CLOB中的数据。

对于较少数量的记录(最大约2k)工作正常。但是当我检查更多数量的记录时,程序会抛出UTL_SMTP瞬态错误 - 服务不可用。

以下是我正在使用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.

1 个答案:

答案 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;