oracle存储过程借助utl,使用UTL_MAIL包实现存储过程邮件发送
郵件通知預警和提示在當前系統中已經是一個比較常見的功能。各類型語言分別針對郵件提供了功能包和API接口方法,本篇介紹如何在PL/SQL代碼中使用UTL_MAIL工具包發送郵件,同時還介紹配置中注意的細節要點。
1、安裝UTL_MAIL包
UTL_MAIL是在Oracle 10g推出的新郵件發送開發包。之前Oracle 8i開始,支持使用utl_smtp包進行RFC所定義的簡單郵件傳輸協議(SMTP)。使用UTL_MAIL要簡單與傳統方式,免除很多額外工作。
默認情況下,UTL_MAIL工具包是沒有安裝到Oracle程序包中的,如果需要使用需要額外進行安裝。安裝的方法是在sys用戶下,調用$ORACLE_HOME/rdbms/admin目錄下的兩個腳本文件。
SQL> conn / as sysdba;
Connected.
SQL> @$ORACLE_HOME/rdbms/admin/utlmail.sql
Package created.
Synonym created.
SQL> @$ORACLE_HOME/rdbms/admin/prvtmail.plb
Package created.
Package body created.
Grant succeeded.
Package body created.
No errors.
兩個腳本的作用就是建立utl_mail工具包。之后要進行一些參數配置,其中最重要的是smtp_out_server參數。該參數指定的是連接郵件服務器的名稱(或者ip地址)。默認情況下,該字符串類型參數的取值為空。
SQL> show parameter smtp
NAMETYPEVALUE
------------------------------------ ----------- ------------------------------
smtp_out_serverstring
設置上指定的郵件服務器。
--需要設置該參數
SQL> alter system set smtp_out_server='10.1.2.55'scope=both;
System altered.
//動態修改后立刻生效
SQL> show parameter smtp
NAMETYPEVALUE
------------------------------------ ----------- ------------------------------
smtp_out_serverstring10.1.2.55
注意:在一些Oracle早期版本中,該參數smtp_out_server是不支持動態修改(scope=memory)的。所以只能使用靜態修改(scope=spfile),之后重啟動數據庫服務器。筆者實驗的環境是oracle 11g R2,是支持動態修改的。
2、在SYS上直接使用utl_mail包
首先實驗下在sys下使用utl_mail包,發送郵件的方法是utl_mail.send方法。下面是方法簽名。
Send方法參數很多,大部分都有使用默認值的機會。下面分別介紹一下各個參數。
üSender:發送者,為必填參數。填寫郵件發送者郵箱地址;
üRecipients:接收者郵箱列表,如果是多個使用逗號進行分割;
üCc:郵件抄送列表;
üBcc:郵件密文抄送列表;
üSubject:郵件主題;
üMessage:郵件信息內容;
üMine_type:編碼格式;
üPriority:消息的優先級;
下面在sys下使用utl_mail.send方法發送郵件。
--直接使用在sys上
begin
utl_mail.send(sender => 'liuziyu@acca.com.cn',
recipients => 'realkid4@126.com',
message => 'sdlfsdfsdfsdfseew**師地方是',
subject => 'SCCS航空');
end;
/
SQL>
PL/SQL procedure successfully completed
到接受郵箱中,果然看到了發送郵件。SYS下使用成功。
3、非SYS用戶使用郵箱配置
如果是在非SYS用戶下直接使用utl_mail包,需要進行何種配置呢?首先是進行包執行權限配置。需要將utl_tcp、utl_mail、utl_smtp和dbms_network_acl_admin四個包的執行權限賦給該用戶。
SQL> grant execute on utl_tcp to scott;
Grant succeeded
SQL> grant execute on utl_smtp to scott;
Grant succeeded
SQL> grant execute on utl_mail to scott;
Grant succeeded
SQL> grant execute on dbms_network_acl_admin to scott;
Grant succeeded
之后,實驗使用。
//在scott用戶下調用
SQL>
begin
utl_mail.send(sender => 'liuziyu@acca.com.cn',
recipients => 'realkid4@126.com',
message => 'sdlfsdfsdfsdfseew**師地方是',
subject => ' SCCS航空');
end;
ORA-24247:網絡訪問被訪問控制列表(ACL)拒絕
ORA-06512:在"SYS.UTL_MAIL", line 654
ORA-06512:在"SYS.UTL_MAIL", line 671
ORA-06512:在line 2
相同的執行語句,并且已經進行賦予執行權限,為什么報錯24247呢?使用utl_mail要求系統對調用用戶開啟ACL(Access Control List)訪問控制列表權限,允許用戶具有連接connect到網絡郵件服務器的權限。可以使用如下方法進行賦予權限操作。
Begin
//設置權限項目
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (acl => 'email_server_permissions.xml',
description => 'Enables network permissions for the e-mail server',
principal => 'SCOTT',
is_grant => TRUE,
privilege => 'connect');
end;
/
BEGIN
//指定訪問主機和相應端口;
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (acl => 'email_server_permissions.xml',
host => '10.1.2.55',
lower_port => 25);
END;
/
之后再使用發送郵件方法:
SQL> begin
2utl_mail.send(sender => 'liuziyu@acca.com.cn',
3recipients => 'realkid4@126.com',
4message => 'sdlfsdf電風扇fsdfseew**師地方是',
5subject => '中國中心');
6
7end;
8/
PL/SQL procedure successfully completed
發送成功,也在接受郵箱上發現郵件。
4、亂碼問題解決
我們上面郵件打開之后,發現郵件subject顯示正常中文,而message內容顯示出亂碼。為如下:
sdlfsdf???fsdfseew??????
看來是中文引起的編碼問題。可以通過調用中改寫mine_type參數的方法來解決。默認情況下,郵件字符集是us-ascii方式的。支持中文可以使用UTF-8。
SQL> begin
2utl_mail.send(sender => 'liuziyu@acca.com.cn',
3recipients => 'realkid4@126.com',
4message => 'sdlfsdf電風扇fsdfseew**師地方是',
5subject => '中國中心',
6mime_type => 'text/plain;charset=UTF-8');
7
8end;
9/
PL/SQL procedure successfully completed
接受到的郵件內容為:
sdlfsdf電風扇fsdfseew**師地方是
顯示正常。
5、Utl_mail使用實踐和結論
系統功能中,郵件是一個比較特殊的功能。其中發送者郵箱、郵件服務器位置等內容常常是統一,而且不對一般模塊可配置的。所以,筆者建議如下使用UTL_MAIL包方法。
ü使用包封裝方法,將UTL_MAIL方法不直接暴露給系統用戶,而是在SYS下建立一個自定義郵件發送方法,預設值好發送者郵箱等內容。主題和信息都已參數的形式傳入;
ü借用所有者權限機制,將執行自定義方法的執行權限賦給系統用戶schema。這樣可以控制用戶的權限不會濫用,也便于管理;
UTL_MAIL較傳統的簡單郵件傳輸方法,調用方式簡化了很多,易用性增強。除了本次介紹的send方法,還可以實現附件內容的發送。這些復雜功能就留待日后繼續研究。
總結
以上是生活随笔為你收集整理的oracle存储过程借助utl,使用UTL_MAIL包实现存储过程邮件发送的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: snkrs抽签协议获取
- 下一篇: NLP入门_自然语言处理_AI分支