太多的在線電子郵件存儲過程。我不轉發,弄個作為一個簡單的例子演示。
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('username@email.com')));
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:username@email.com'||utl_tcp.CRLF||
'To:sanoul@email.com'||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,'<username@email.com>'); --發件人郵箱
utl_smtp.rcpt(smtp_conn,'<sanoul@email.com>'); --收件人郵箱
utl_smtp.open_data(smtp_conn);
utl_smtp.write_raw_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_raw.cast_to_raw最大長度是16383,假設你的郵件正文超大,請循環插入正文write_raw_data
--否則肯定會得到 ORA-06502: PL/SQL: 數字或值錯誤
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', --smtpserver地址
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'
三大錯誤,為了解決根據上述方法,這些問題可以)
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

