使用UTL_MAIL包实现存储过程邮件发送

邮件通知预警和提示在当前系统中已经是一个比较常见的功能。各类型语言分别针对邮件提供了功能包和API接口方法,本篇介绍如何在PL/SQL代码中使用UTL_MAIL工具包发送邮件,同时还介绍配置中注意的细节要点。

 

 

1、安装UTL_MAIL

 

UTL_MAIL是在Oracle10g推出的新邮件发送开发包。之前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

 

NAME                                TYPE       VALUE

------------------------------------ ----------- ------------------------------

smtp_out_server                     string

 

 

设置上指定的邮件服务器。

 

 

--需要设置该参数

SQL> alter system set smtp_out_server='10.1.2.55'scope=both;

System altered.

 

//动态修改后立刻生效

SQL> show parameter smtp

NAME                                TYPE       VALUE

------------------------------------ ----------- ------------------------------

smtp_out_server                     string     10.1.2.55

 

 

注意:在一些Oracle早期版本中,该参数smtp_out_server是不支持动态修改(scope=memory)的。所以只能使用静态修改(scope=spfile),之后重启动数据库服务器。笔者实验的环境是oracle11gR2,是支持动态修改的。

 

 

2、在SYS上直接使用utl_mail

 

首先实验下在sys下使用utl_mail包,发送邮件的方法是utl_mail.send方法。下面是方法签名。

 

 UTL_MAIL.SEND(SENDER  IN  VARCHAR2  CHARACTER  SET ANY_CS,
               RECIPIENTS  IN  VARCHAR2  CHARACTER  SET ANY_CS,
               CC  IN  VARCHAR2  CHARACTER  SET ANY_CS  DEFAULT  NULL,
               BCC  IN  VARCHAR2  CHARACTER  SET ANY_CS  DEFAULT  NULL,
               SUBJECT  IN  VARCHAR2  CHARACTER  SET ANY_CS  DEFAULT  NULL,
               MESSAGE  IN  VARCHAR2  CHARACTER  SET ANY_CS,
               MIME_TYPE  IN  VARCHAR2  DEFAULT  ' text/plain; charset=us-ascii ',
               PRIORITY  IN PLS_INTEGER  DEFAULT  NULL);

 

Send方法参数很多,大部分都有使用默认值的机会。下面分别介绍一下各个参数。

 

ü       Sender:发送者,为必填参数。填写邮件发送者邮箱地址;

ü       Recipients:接收者邮箱列表,如果是多个使用逗号进行分割;

ü       Cc:邮件抄送列表;

ü       Bcc:邮件密文抄送列表;

ü       Subject:邮件主题;

ü       Message:邮件信息内容;

ü       Mine_type:编码格式;

ü       Priority:消息的优先级;

 

下面在sys下使用utl_mail.send方法发送邮件。

 

 

--直接使用在sys

begin

 utl_mail.send(sender => '[email protected]',

               recipients => '[email protected]',

               message => 'sdlfsdfsdfsdfseew**师地方是',

               subject => 'SCCS航空');

 

end;

/

 

SQL>

PL/SQL procedure successfully completed

 

到接受邮箱中,果然看到了发送邮件。SYS下使用成功。

 

3、SYS用户使用邮箱配置

 

如果是在非SYS用户下直接使用utl_mail包,需要进行何种配置呢?首先是进行包执行权限配置。需要将utl_tcputl_mailutl_smtpdbms_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 => '[email protected]',

               recipients => '[email protected]',

               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要求系统对调用用户开启ACLAccess 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

 2   utl_mail.send(sender => '[email protected]',

 3                 recipients => '[email protected]',

 4                 message => 'sdlfsdf电风扇fsdfseew**师地方是',

 5                 subject => '中国中心');

 6 

 7 end;

 8 /

 

PL/SQL procedure successfully completed

 

 

 

发送成功,也在接受邮箱上发现邮件。

 

4、乱码问题解决

 

我们上面邮件打开之后,发现邮件subject显示正常中文,而message内容显示出乱码。为如下:

 

 

sdlfsdf???fsdfseew??????

 

 

看来是中文引起的编码问题。可以通过调用中改写mine_type参数的方法来解决。默认情况下,邮件字符集是us-ascii方式的。支持中文可以使用UTF-8

 

 

SQL> begin

 2   utl_mail.send(sender => '[email protected]',

 3                 recipients => '[email protected]',

 4                 message => 'sdlfsdf电风扇fsdfseew**师地方是',

 5                 subject => '中国中心',

 6                 mime_type => 'text/plain;charset=UTF-8');

 7 

 8 end;

 9 /

 

PL/SQL procedure successfully completed

 

 

接受到的邮件内容为:

 

 

sdlfsdf电风扇fsdfseew**师地方是

 

 

显示正常。

 

 

5Utl_mail使用实践和结论

 

系统功能中,邮件是一个比较特殊的功能。其中发送者邮箱、邮件服务器位置等内容常常是统一,而且不对一般模块可配置的。所以,笔者建议如下使用UTL_MAIL包方法。

 

ü       使用包封装方法,将UTL_MAIL方法不直接暴露给系统用户,而是在SYS下建立一个自定义邮件发送方法,预设值好发送者邮箱等内容。主题和信息都已参数的形式传入;

ü       借用所有者权限机制,将执行自定义方法的执行权限赋给系统用户schema。这样可以控制用户的权限不会滥用,也便于管理

 

 

UTL_MAIL较传统的简单邮件传输方法,调用方式简化了很多,易用性增强。除了本次介绍的send方法,还可以实现附件内容的发送。这些复杂功能就留待日后继续研究。

http://space.itpub.net/17203031/viewspace-700327

你可能感兴趣的:(存储过程)