如何使用Oracle PL/SQL 实现发送电子邮件功能(UTL_MAIL)

大家好,我是只谈技术不剪发的 tony 老师。

我们在开发 oracle 数据库程序时,如果想要通过 pl/sql 存储过程实现发送邮件的功能,大概可以使用以下三种方法:

  • 利用 utl_tcp 程序包基于 tcp 协议发送邮件。这种方法比较原始,需要用户编写基础交换代码。
  • 利用 utl_smtp 程序包基于 smtp 协议发送邮件。这种方法比编码 tcp 操作简单很多,支持发送电子邮件的各种操作,因此使用非常广泛。
  • 利用 utl_mail 程序包发送邮件。这种方法最简单,支持常用的邮件功能,不需要了解 smtp 协议。

今天我们要介绍的是第 3 种方法,也就是通过 utl_mail 程序包在 pl/sql 程序中实现发送邮件的功能。oracle 10g 开始提供 utl_mail 程序包。

安装 utl_mail

默认情况下,系统没有安装 utl_mail 程序包。因为它需要设置 smtp_out_server 配置参数,同时还会涉及到一些安全问题。

首先,执行以下语句安装 utl_mail 程序包:

sqlplus sys/<pwd>
sql> @$oracle_home/rdbms/admin/utlmail.sql
sql> @$oracle_home/rdbms/admin/prvtmail.plb

然后设置 smtp_out_server 参数:

sqlplus sys/<pwd>
sql> alter system set smtp_out_server='smtp.domain.com' scope=spfile;

如果使用 oracle 10g r1,需要重启服务,更高版本不需要。

建议在数据库服务器上设置一个邮件转发,而不是直接连接到外部的邮件服务器。邮件转发配置非常简单,设置一个引用 smtp_out_server 参数的 localhost 的配置。任何连接外部邮件服务器的复杂配置都隐藏在邮件转发配置中。

发送邮件

完成安装和配置之后,我们可以使用存储过程 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 3,
   replyto     in    varchar2 character set any_cs default null);

这些参数的作用如下:

  • sender:发送者的邮件地址
  • recipients:接收者的邮件地址,多个地址使用逗号分隔
  • cc:抄送者的邮件地址,多个地址使用逗号分隔,默认为 null
  • bcc:密送者的邮件地址,多个地址使用逗号分隔,默认为 null
  • subject:邮件主题,默认为 null
  • message:邮件正文
  • mime_type:邮件的 mime 类型,默认为 text/plain; charset=us-ascii
  • priority:邮件优先级,1 级最高,5 级最低,默认为 3
  • replyto:回复邮件发送的目标地址,oracle 11g r2 开始支持该参数

以下是一个发送邮件的简单示例:

begin
  utl_mail.send(sender     => 'myname@domain.com',
                recipients => 'zhangsan@domain.com,lisi@domain.com',
                cc         => 'wangwu@domain.com',
                bcc        => 'myboss@domain.com',
                subject    => 'utl_mail 测试',
                message    => '邮件正文',
                mime_type  => 'text/plain; charset=utf-8'); -- 支持中文
end;
/

发送附件

除了发送文本邮件之外,utl_mail 程序包还提供了两个支持附件的存储过程:send_attach_raw 以及 send_attach_varchar2 。它们分别可以用于发送 raw 以及 varchar2 格式的附件。

utl_mail.send_attach_raw (
   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 default null,
   mime_type        in    varchar2 default character set any_cs
                              default 'text/plain; charset=us-ascii',
   priority         in    pls_integer default 3,
   attachment       in    raw,
   att_inline       in    boolean default true,
   att_mime_type    in    varchar2 character set any_cs 
                                           default 'text/plain; charset=us-ascii',
   att_filename     in    varchar2 character set any_cs default null,
   replyto          in    varchar2 character set any_cs default null);

utl_mail.send_attach_varchar2 (
   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 default null,
   mime_type         in    varchar2 character set any_cs 
                                           default 'text/plain; charset=us-ascii',
   priority          in    pls_integer default 3,
   attachment        in    varchar2 character set any_cs, ,
   att_inline        in    boolean default true,
   att_mime_type     in    varchar2 character set any_cs 
                                           default 'text/plain; charset=us-ascii',
   att_filename      in    varchar2character set any_cs default null,
   replyto           in    varchar2 character set any_cs default null);

这两个存储过程比 utl_mail.send 支持以下额外的参数:

  • attachment:附件内容,数据类型为 raw 或者 varchar2
  • att_inline:指定附件是否在邮件正文中显式,默认为 true
  • att_mime_type:附件的 mime 类型,默认为 ‘application/octet’ 或者 ‘text/plain; charset=us-ascii’
  • att_filename:附件的文件名,默认为 null

以下是一个发送文本附件的示例:

begin
  utl_mail.send(sender     => 'myname@domain.com',
                recipients => 'zhangsan@domain.com,lisi@domain.com',
                cc         => 'wangwu@domain.com',
                bcc        => 'myboss@domain.com',
                subject    => 'utl_mail 测试',
                message    => '邮件正文',
                mime_type  => 'text/plain; charset=utf-8', -- 支持中文
                attachment => '附件内容',
                att_mime_type => 'text/plain; charset=utf-8', -- 支持中文
                att_filename => '附件.txt');
end;
/

注意事项

utl_mail 程序包使用调用者权限,也就是说使用该程序的用户需要拥有访问外部邮件服务器的权限。

如果遇到以下错误,表示缺少相应的权限。

ora-24247: network access denied by access control list (acl)

此时我们可以通过以下语句授予指定用户(例如 scott)访问外部服务器上的 smpt 服务权限:

begin;

dbms_network_acl_admin.append_host_ace(
  host => 'www.domain.comm',
  ace  =>  xs$ace_type(privilege_list => xs$name_list('smtp'),
                       principal_name => 'scott',
                       principal_type => xs_acl.ptype_db)); 
end;
/

详细内容可以参考官方文档。

到此这篇关于如何使用oracle pl/sql 实现发送电子邮件功能(utl_mail)的文章就介绍到这了,更多相关oracle pl/sql 发送电子邮件内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐