如何使用Oracle PL/SQL 实现发送电子邮件功能(UTL_MAIL)
作者:不剪发的Tony老师 发布时间:2024-01-17 19:32:18
大家好,我是只谈技术不剪发的 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


猜你喜欢
- /// <summary> /// 获得目标
- 本文实例讲述了Python PyInstaller库基本使用方法。分享给大家供大家参考,具体如下:概述将.py源码转换成无需源代码的可执行文
- 先贴代码package mainimport ("fmt")// Send the sequence 2, 3, 4,
- 错误图片解决mysql -u root -p 以root身份进入mysqlgrant all on *.* to 'root'
- 一、简介说明:索引是数据库对象之一,用于加快数据的检索,类似于书籍的索引。在数据库中索引可以减少数据库程序查询结果时需要读取的数据量,类似于
- 很多年前,我们就可以轻易的从很多国营商场、火车车厢、饭馆旅馆中看到墙上挂的那个小本本-意见薄,作为经营方与顾客沟通的
- 本文实例讲述了python实现web方式logview的方法。分享给大家供大家参考。具体如下:这里用Python实现web方式查看日志的一个
- 前言for循环是Go语言唯一的循环结构,最近在做一个基于RabbitMQ的应用,由于官方的qos没有golang的版本,所以出了一点问题。问
- 当SQL语句查询报1055错误时的解决方法报错内容如下报错原因1.SQL语句中使用了group by,并且不需要分组的字段没有加上any_v
- 本文介绍了SpringBoot 中使用JSP的方法示例,分享给大家,具体如下:依赖: <parent>
- 一、pip简介Pip 是安装python包的工具,提供了安装包,列出已经安装的包,升级包以及卸载包的功能。Pip 是对easy_instal
- 详解Python文本操作相关模块linecache——通过使用缓存在内部尝试优化以达到高效从任何文件中读出任何行。 主要方法: lineca
- 本文实例为大家分享了微信小程序实现登陆注册滑块验证的具体代码,供大家参考,具体内容如下一、创建自定义组件MoveVerifyMoveVeri
- Clion、IEDA、pycharm的设置及界面是一模一样的,下面我将按照Clion举例,但是在IEDA和pycharm是同样适用,按照方法
- 1、封装的理解封装(Encapsulation):属性和方法的抽象属性的抽象:对类的属性(变量)进行定义、隔离和保护分为私有属性和公开属性:
- 异常处理简介在我们写程序代码的时候,往往会因一个小问题让我们整个程序直接挂掉。异常处理对我们测试有什么好处,相信做过自动化的同学都知道我们的
- 在学习OpenCV或者其他关于Python技术的时候,我们通常需要准备不同的Python环境,我选择了Anaconda作为我的Python环
- asp之家注:作为一个学习asp的爱好者,相信一定接触过session,我们经常使用session来作为会员登录的验证,当然也可以使用COO
- python函数的参数类型和返回类型默认为int。如果需要传递一个float值给dll,那么需要指定参数的类型。如果需要返回一个flaot值
- 解决方法一:使用python的BeautifulSoup来抓取网页然后输出网页标题,但是输出的总是乱码,找了好久找到解决办法,下面分享给大家