2016-12-29 460 views
2

我們計劃安裝UTL_MAIL軟件包,目前我們正在測試開發環境中的安裝步驟。 後成功地安裝UTL_MAIL包裝腳本和創建充分PUBLIC同義詞和資助, 運行測試時,我們所得到的是錯誤ORA-29278匿名塊如下:ORA-29278:SMTP瞬態錯誤:運行UTL_MAIL時服務不可用

BEGIN 

    UTL_MAIL.SEND(sender  => '[email protected]' 
       , recipients => '[email protected]' 
       , subject => 'Testmail' 
       , message => 'Hello'); 

END; 
錯誤消息的

的詳細介紹:

ORA-29278: SMTP transient error: 421 4.3.2 Service not available 
ORA-06512: at "SYS.UTL_MAIL", line 662 
ORA-06512: at "SYS.UTL_MAIL", line 679 
ORA-06512: at line 3 
29278. 00000 - "SMTP transient error: %s" 
*Cause: A SMTP transient error occurred. 
*Action: Correct the error and retry the SMTP operation.  

根據相關鏈接研究(Send Email Using PLSQL), 我可能需要設置正確的訪問控制列表(ACL)才能使其工作。但是,在執行下面的腳本時,我仍然得到相同的錯誤。

DECLARE 
    -- ACL name to be used for email access reuse the same value for all 
    -- future calls 
    l_acl   VARCHAR2 (30) := 'utl_smtp.xml'; 
    -- Oracle user to be given permission to send email 
    l_principal VARCHAR2 (30) := 'APPS'; 
    -- Name of email server 
    g_mailhost VARCHAR2 (60) := 'smtprelay.xxxxx.com'; 
    l_cnt   INTEGER; 

    PROCEDURE validate_smtp_server 
    AS 
     l_value  v$parameter.VALUE%TYPE; 
     l_parameter v$parameter.name%TYPE := 'smtp_out_server'; 
    BEGIN 

     SELECT VALUE 
     INTO l_value 
     FROM v$parameter 
     WHERE name = l_parameter; 

     IF l_value IS NULL 
     THEN 
     raise_application_error (
      -20001 
      , 'Oracle parameter ' 
      || l_parameter 
      || ' has not been set' 
      || UTL_TCP.crlf 
      || 'it s/b smtprelay.alorica.com' 
     ); 
     END IF; 

     DBMS_OUTPUT.put_line ('parameter ' || l_parameter || ' value is ' ||  l_value); 

    END validate_smtp_server; 

    PROCEDURE create_if_needed (p_acl IN VARCHAR2) 
    AS 
     l_cnt INTEGER; 
    BEGIN 

     SELECT COUNT (*) c 
     INTO l_cnt 
     FROM dba_network_acls a 
     WHERE SUBSTR (acl, INSTR (acl, '/', -1) + 1) = p_acl; 

     IF l_cnt = 0 
     THEN 
     DBMS_OUTPUT.put_line ('creating acl ' || p_acl); 
     DBMS_NETWORK_ACL_ADMIN.create_acl (
      acl   => p_acl 
      , description => 'Allow use of utl_smtp' 
      , principal => l_principal 
      , is_grant => TRUE 
      , privilege => 'connect' 
     ); 

     DBMS_NETWORK_ACL_ADMIN.assign_acl (acl => p_acl, HOST => g_mailhost); 
     COMMIT; 
     ELSE 
     DBMS_OUTPUT.put_line (p_acl || ' acl already exists'); 
     END IF; 

    END create_if_needed; 

    PROCEDURE add_if_needed (
     p_principal IN VARCHAR2 
    , p_acl   IN VARCHAR2 
    ) 
    AS 
     l_cnt INTEGER; 
    BEGIN 

     SELECT COUNT (*) c 
     INTO l_cnt 
     FROM dba_network_acl_privileges 
     WHERE SUBSTR (acl, INSTR (acl, '/', -1) + 1) = p_acl 
     AND principal = p_principal; 

     IF l_cnt = 0 
     THEN 
     DBMS_NETWORK_ACL_ADMIN.add_privilege (
      acl  => 'utl_smtp.xml' 
      , principal => p_principal 
      , is_grant => TRUE 
      , privilege => 'connect' 
     ); 
     COMMIT; 
     DBMS_OUTPUT.put_line ('access to ' || p_acl || ' added for ' ||  p_principal); 
     ELSE 
     DBMS_OUTPUT.put_line (p_principal || ' already has access to ' || p_acl); 
     END IF; 

    END add_if_needed; 
BEGIN 

    EXECUTE IMMEDIATE 'grant execute on utl_mail to ' || l_principal; 

    create_if_needed (p_acl => l_acl); 
    add_if_needed (p_principal => l_principal, p_acl => l_acl); 
    DBMS_OUTPUT.put_line ('Verification SQL:'); 
    DBMS_OUTPUT.put_line (' SELECT * FROM dba_network_acls;'); 
    DBMS_OUTPUT.put_line (' SELECT * FROM dba_network_acl_privileges;'); 
    COMMIT; 
    validate_smtp_server; 
END; 

我可以採取哪些其他步驟或需要向DBA提供哪些其他說明?

Oracle數據庫版本:

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production 
PL/SQL Release 11.2.0.4.0 - Production 
"CORE 11.2.0.4.0 Production" 
TNS for Solaris: Version 11.2.0.4.0 - Production 
NLSRTL Version 11.2.0.4.0 - Production 

非常感謝你。

回答

1

我可以通過聯繫我們的系統管理員並詢問郵件服務器的詳細信息來解決此問題。 原來,如果我們只是在內部發送電子郵件,我們建議使用不同的服務器mail.xxx.xxx.xxxx,因爲它不會被防火牆阻止。另一方面,如果我們要在外部發送電子郵件,則涉及另一臺服務器smtprelay.xxxxx.com ,這涉及到將白名單列爲要發送到的外部服務器的額外步驟。

當我檢查V$PARAMETER,我們使用smtprelay.xxxxx.com服務器,並決定嘗試其他服務器mail.xxx.xxx.xxxx

我發出如下alter命令:

alter system set smtp_out_server = 'mail.xxx.xxx.xxxx'; 

就跑匿名塊,並能夠成功收到的電子郵件。

BEGIN 

    UTL_MAIL.SEND(sender  => '[email protected]' 
       , recipients => '[email protected]' 
       , subject => 'Testmail' 
       , message => 'Hello'); 

END; 
+0

嗨,我面臨與我的應用程序類似的問題。我無法發送電子郵件,而且我在公司網絡內。我想更深入地與你討論。我也得到「SMTP瞬態錯誤:421服務不可用」。 –

+0

@RaviShankar你還在使用PL/SQL嗎? –

+0

是的!我正在使用PL/SQL。 –