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

作者:不剪发的Tony老师 时间:2024-01-17 19:32:18 

如何使用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;
/

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

来源:https://blog.csdn.net/horses/article/details/119537966

标签:Oracle,PL/SQL,UTL,MAIL,发送电子邮件
0
投稿

猜你喜欢

  • python中前缀运算符 *和 **的用法示例详解

    2022-05-19 08:41:31
  • perl产生随机数实现代码

    2023-04-14 05:30:10
  • Go标准容器之Ring的使用说明

    2023-09-21 02:18:14
  • Python 使用 pip 安装 matplotlib 模块的方法

    2021-08-22 02:42:52
  • Linux虚拟机下mysql 5.7安装配置方法图文教程

    2024-01-13 11:55:08
  • Oracle数据库的备份与恢复

    2024-01-21 02:13:58
  • MySQL数据库的23个注意事项

    2024-01-23 11:26:06
  • PHP中最低级别的错误类型总结

    2023-09-04 16:46:17
  • python 使用fileinput读取文件

    2021-09-07 23:48:43
  • 浅析Python是如何实现集合的

    2022-05-16 03:38:58
  • 科讯CMS编辑器会自动更改代码

    2008-12-12 13:00:00
  • Python人工智能构建简单聊天机器人示例详解

    2022-03-10 04:42:29
  • go redis实现滑动窗口限流的方式(redis版)

    2024-02-02 18:04:27
  • Python中for循环可迭代对象迭代器及生成器源码学习

    2023-10-11 07:00:30
  • mysql mycat 中间件安装与使用

    2024-01-21 11:35:48
  • Asp编写不再让人讨厌的自动弹出窗口

    2007-09-29 12:16:00
  • vue中的v-show,v-if,v-bind的使用示例详解

    2024-05-28 15:48:07
  • 站长如何活用"nofollow"标签

    2008-05-13 12:40:00
  • python人工智能自定义求导tf_diffs详解

    2023-06-11 13:31:51
  • 对SQL Server聚集索引的指示综合描述

    2010-08-31 14:25:00
  • asp之家 网络编程 m.aspxhome.com