UTL_SMTP包发送电子邮件时出错

时间:2015-03-23 11:31:39

标签: sql oracle plsql oracle11g

我创建了一个程序,如下所示: -

CREATE OR REPLACE PROCEDURE send_mail (p_to        IN VARCHAR2,
                                       p_from      IN VARCHAR2,
                                       p_message   IN VARCHAR2,
                                       p_smtp_host IN VARCHAR2,
                                       p_smtp_port IN NUMBER DEFAULT 26)
AS
  l_mail_conn   UTL_SMTP.connection;
BEGIN
  l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
  UTL_SMTP.helo(l_mail_conn, p_smtp_host);
  UTL_SMTP.mail(l_mail_conn, p_from);
  UTL_SMTP.rcpt(l_mail_conn, p_to);
  UTL_SMTP.data(l_mail_conn, p_message);
  UTL_SMTP.quit(l_mail_conn);
END;

运行程序后,我收到错误: -

ORA-00600: internal error code, arguments: [psdnop-1], [604], [], [], [], [], [], [], [], [], [], []
ORA-00604: error occurred at recursive SQL level 
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYS.UTL_TCP", line 17
ORA-06512: at "SYS.UTL_TCP", line 246
ORA-06512: at "SYS.UTL_SMTP", line 115
ORA-06512: at "SYS.UTL_SMTP", line 138
ORA-06512: at "APPS.SEND_MAIL", line 9
ORA-06512: at line 2

请帮忙。

2 个答案:

答案 0 :(得分:0)

在我的应用程序中,它看起来(并且工作)如下:

CREATE OR REPLACE PROCEDURE send_mail (p_to        IN VARCHAR2,
                                       p_from      IN VARCHAR2,
                                       p_subject   IN VARCHAR2,
                                       p_message   IN VARCHAR2,
                                       p_domain IN VARCHAR2,
                                       p_smtp_host IN VARCHAR2,
                                       p_smtp_port IN NUMBER DEFAULT 25)
AS
    PRIORITY_HIGH           CONSTANT INTEGER := 1;
    PRIORITY_NORMAL         CONSTANT INTEGER := 3;
    PRIORITY_LOW            CONSTANT INTEGER := 5;
  l_mail_conn   UTL_SMTP.connection;
BEGIN
    l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
    UTL_SMTP.helo(l_mail_conn, p_domain);
    UTL_SMTP.mail(l_mail_conn, p_from);
    UTL_SMTP.rcpt(l_mail_conn, p_to);  
    UTL_SMTP.open_data(l_mail_conn);
    UTL_SMTP.write_data(l_mail_conn, 'From: <'||p_from||'>'||UTL_TCP.CRLF);
    UTL_SMTP.write_data(l_mail_conn, 'To: <'||p_to||'>'||UTL_TCP.CRLF);
    UTL_SMTP.write_data(l_mail_conn, 'Subject: '||p_subject||UTL_TCP.CRLF);
    UTL_SMTP.write_data(l_mail_conn, 'X-Priority: '||PRIORITY_NORMAL||UTL_TCP.CRLF);
    UTL_SMTP.write_data(l_mail_conn, 'Content-type: text/plain; charset=UTF-8'||UTL_TCP.CRLF );
    UTL_SMTP.write_data(l_mail_conn, UTL_TCP.CRLF);
    UTL_SMTP.write_raw_data(l_mail_conn, UTL_RAW.cast_to_raw(p_message));
    UTL_SMTP.write_data(l_mail_conn, UTL_TCP.CRLF);
    UTL_SMTP.close_data(l_mail_conn);
    UTL_SMTP.quit(l_mail_conn);
END;

注意,不要错过UTL_SMTP.write_data(l_mail_conn, UTL_TCP.CRLF);行。

BTW,SMTP的默认TCP端口是25而不是26。

答案 1 :(得分:-1)

您是否为网络访问创建了ACL?如果没有,请检查以下内容:

首先使用您的邮件服务器更改您的邮件服务器并在空格指定端口号后运行以下命令。

alter system set smtp_out_server = 'yourmailserver yourport' scope=both;

-- change the yourmailserver with your mail server and after a space specify port number.

Then run below script in Sys user but before running this script modify the youruser and yourmailserver in script.

--RUN IN SYS USER FOR ACL PRIVILEGE FOR ORACLE 11G
-----------------------------------------------------------------------------------------
-- "Set define off" turns off substitution variables. 
Set define off; 

--- RUN IN SYS USER ---

CREATE OR REPLACE PROCEDURE mailserver_acl(
aacl varchar2,
acomment varchar2,
aprincipal varchar2,
aisgrant boolean,
aprivilege varchar2,
aserver varchar2,
aport number)
Is
BEGIN 
BEGIN
Dbms_Network_Acl_Admin.DROP_ACL(aacl);
Dbms_Output.put_Line('ACL dropped.....');
EXCEPTION
When Others Then
Dbms_Output.put_Line('Error dropping ACL: '||aacl);
Dbms_Output.put_Line(SQLERRM);
END;
BEGIN
Dbms_Network_Acl_Admin.CREATE_ACL(aacl,acomment,aprincipal,aisgrant,aprivilege);
Dbms_Output.put_Line('ACL created.....');
EXCEPTION
When Others Then
Dbms_Output.put_Line('Error creating ACL: '||aacl);
Dbms_Output.put_Line(SQLERRM);
END; 
BEGIN
Dbms_Network_Acl_Admin.ASSIGN_ACL(aacl,aserver,aport);
Dbms_Output.put_Line('ACL assigned.....'); 
EXCEPTION
When Others Then
Dbms_Output.put_Line('Error assigning ACL: '||aacl);
Dbms_Output.put_Line(SQLERRM);
END; 
COMMIT;
Dbms_Output.put_Line('ACL commited.....');
END;
/

-- replace youruser with your user name and yourmailserver and yourport with your values:

BEGIN
mailserver_acl(
'mailserver_acl.xml',
'ACL for used Email Server to connect',
'YourUser',
TRUE,
'connect',
'YourMailServer',
YourPort); 
END;
/