程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle11g環境下,利用utl_smtp創建發送郵件的存儲過程

Oracle11g環境下,利用utl_smtp創建發送郵件的存儲過程

編輯:Oracle教程

Oracle11g環境下,利用utl_smtp創建發送郵件的存儲過程


網上太多發郵件儲存過程,我就不轉發了,弄個簡單的作為示例;

create or replace procedure Send_mail(mail_body varchar2) is
  smtp_conn  utl_smtp.connection;
  user_name  varchar2(20) := utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('[email protected]'))); 
  user_paswd varchar2(20) := utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('password')));
  lv_mail_header varchar2(200):='From:[email protected]'||utl_tcp.CRLF||
                                'To:[email protected]'||utl_tcp.CRLF||
                                'Subject:Oracle數據庫'||utl_tcp.CRLF;
  lv_mail_content varchar2(2000);
begin
  lv_mail_content := utl_tcp.CRLF||mail_body;  

  smtp_conn := utl_smtp.open_connection('smtp.email.com',25);
  utl_smtp.helo(smtp_conn,'smtp.email.com');
  utl_smtp.command(smtp_conn,'AUTH LOGIN');
  utl_smtp.command(smtp_conn,user_name); --郵件用戶名
  utl_smtp.command(smtp_conn,user_paswd); --郵件密碼
  utl_smtp.mail(smtp_conn,'<[email protected]>'); --發件人郵箱
  utl_smtp.rcpt(smtp_conn,'<[email protected]>'); --收件人郵箱
  utl_smtp.open_data(smtp_conn);
  utl_smtp.write_data(smtp_conn,utl_raw.cast_to_raw(lv_mail_header)); 
  utl_smtp.write_raw_data(smtp_conn,utl_raw.cast_to_raw(lv_mail_content));
  utl_smtp.close_data(smtp_conn);
  utl_smtp.quit(smtp_conn);
exception
  when others then
    utl_smtp.quit(smtp_conn);
end Send_mail;
/

--儲存過程已創建

第二步直接測試函數;

begin
  send_mail('測試內容');
end;
/

ORA-29278: SMTP 臨時性錯誤: 421 Service not available
ORA-06512: 在 "SYS.UTL_SMTP", line 21
ORA-06512: 在 "SYS.UTL_SMTP", line 97
ORA-06512: 在 "SYS.UTL_SMTP", line 139
ORA-06512: 在 "SYS.UTL_MAIL", line 405
ORA-06512: 在 "SYS.UTL_MAIL", line 594
ORA-06512: 在 line 2
話說我第一次看到這個錯誤非常震驚,因為整個郵件發送的存儲過程是先用PL/SQL直接測試代碼後,再封裝到存儲過程中的,後來經過搜索才知道為了更細致地控制網絡權限,Oracle 11g中針對UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP和 UTL_INADDR的訪問設置了單獨的權限訪問控制方式(ACL).

OK,第三步,設置ACL;

--ACL第一步,創建
BEGIN  
        dbms_network_acl_admin.create_acl(acl         => 'httprequestpermission.xml',  --文件名,可以任意取名
                                          DESCRIPTION => 'Normal Access',  
                                          principal   => 'CONNECT',  --角色
                                          is_grant    => TRUE,  
                                          PRIVILEGE   => 'connect',  
                                          start_date  => NULL,  
                                          end_date    => NULL);  
END;  
/

commit; --必須要提交;

然後檢查是否創建了該 ACL控制文件;

SQL> SELECT any_path FROM resource_view WHERE any_path like '/sys/acls/%.xml';
如果列表裡出現剛才創建的文件httprequestpermission.xml,請繼續ACL第二步 
--ACL第二步,授權用戶(示例用scott作為測試)
begin  
        dbms_network_acl_admin.add_privilege(acl        => 'httprequestpermission.xml',  
                                             principal  => 'SCOTT',  --用戶,請按照實際變更
                                             is_grant   => TRUE,  
                                             privilege  => 'connect',  
                                             start_date => null,  
                                             end_date   => null);  
end;  
/
--ACL第三步,添加主機或域名
    begin  
        dbms_network_acl_admin.assign_acl(acl        => 'httprequestpermission.xml',  
                                          host       => 'www.baidu.com',  --http網頁地址
                                          lower_port => 80,  --http端口
                                          upper_port => NULL);  
    end;  
/

commit;

    begin  
        dbms_network_acl_admin.assign_acl(acl        => 'httprequestpermission.xml',  
                                          host       => 'smtp.sina.com.cn',  --smtp服務器地址
                                          lower_port => 25,  --smtp端口
                                          upper_port => NULL);  
    end;  
/
commit;
最後就是再次測試存儲過程 
SQL> begin
  2    send_mail(mail_body => 'afafagaga');
  3  end;
  4  /
 
PL/SQL procedure successfully completed
沒有任何錯誤,郵件正確收到;(本文測試環境:Oracle 11.2.0.0,OS:Windows 2008 Server)

(作者測試過程中曾遇到過

ORA-24247: 網絡訪問被訪問控制列表 (ACL) 拒絕;

ORA-29278: SMTP 臨時性錯誤: 421 Service not available;

ORA-44416: ACL 無效: 無法解析的主用戶 'AGENT'

這三個主要錯誤,按照上述步驟均能解決這些問題)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved