APPLIES TO:

PL/SQL - Version 10.1.0.2 and later
Information in this document applies to any platform.
"Checked for relevance on 06-Mar-2012"

GOAL

This note shows how to send emails with the UTL_MAIL package provided staring in Oracle 10g.

SOLUTION

How to Send Emails Using UTL_MAIL

1. UTL_MAIL is a wrapper, which internally uses UTL_TCP and UTL_SMTP, the "old" packages to send emails. You can see that, when you receive an error stack. It contains the functions UTL_TCP and UTL_SMTP. The UTL_MAIL package is much easier to use than the UTL_SMTP package. To create the package, you have to run utlmail.sql and prvtmail.plb under sys. You can find the two scripts in the ORACLE_HOME/rdbms/admin directory. Prerequisite for using the procedures in the UTL_MAIL package further is the new init.ora parameter "SMTP_OUT_SERVER", which has to be set to your outgoing mailserver.

UTL_MAIL package consists of three procedures:

PROCEDURE SEND
Argument Name Typ In/Out Defaultwert
------------------------------ ----------------------- ------ --------
SENDER VARCHAR2 IN
RECIPIENTS VARCHAR2 IN
CC VARCHAR2 IN DEFAULT
BCC VARCHAR2 IN DEFAULT
SUBJECT VARCHAR2 IN DEFAULT
MESSAGE VARCHAR2 IN DEFAULT
MIME_TYPE VARCHAR2 IN DEFAULT
PRIORITY BINARY_INTEGER IN DEFAULT

PROCEDURE SEND_ATTACH_RAW
Argument Name Typ In/Out Defaultwert
------------------------------ ----------------------- ------ --------
SENDER VARCHAR2 IN
RECIPIENTS VARCHAR2 IN
CC VARCHAR2 IN DEFAULT
BCC VARCHAR2 IN DEFAULT
SUBJECT VARCHAR2 IN DEFAULT
MESSAGE VARCHAR2 IN DEFAULT
MIME_TYPE VARCHAR2 IN DEFAULT
PRIORITY BINARY_INTEGER IN DEFAULT
ATTACHMENT RAW IN
ATT_INLINE BOOLEAN IN DEFAULT
ATT_MIME_TYPE VARCHAR2 IN DEFAULT
ATT_FILENAME VARCHAR2 IN DEFAULT

PROCEDURE SEND_ATTACH_VARCHAR2
Argument Name Typ In/Out Defaultwert
------------------------------ ----------------------- ------ --------
SENDER VARCHAR2 IN
RECIPIENTS VARCHAR2 IN
CC VARCHAR2 IN DEFAULT
BCC VARCHAR2 IN DEFAULT
SUBJECT VARCHAR2 IN DEFAULT
MESSAGE VARCHAR2 IN DEFAULT
MIME_TYPE VARCHAR2 IN DEFAULT
PRIORITY BINARY_INTEGER IN DEFAULT
ATTACHMENT VARCHAR2 IN
ATT_INLINE BOOLEAN IN DEFAULT
ATT_MIME_TYPE VARCHAR2 IN DEFAULT
ATT_FILENAME VARCHAR2 IN DEFAULT

2. In this section you can find several samples, showing the functionality of UTL_MAIL. Before attempting to run them be sure that you have created the UTL_MAIL package by running the following script under SYS schema.

@$ORACLE_HOME/rdbms/admin/utlmail.sql @$ORACLE_HOME/rdbms/admin/prvtmail.plb

Grants the execute on UTL_MAIL privilege either to PUBLIC or to the user which will use the package, running one of this statement from SYS:

GRANT EXECUTE ON UTL_MAIL TO PUBLIC;
--or--
GRANT EXECUTE ON UTL_MAIL TO <user>;
TIP: With Database releases 11.1 or later, you will need to setup an ACL for any users that need access to the UTL_MAIL package. See Document 1209644.1 for additional information on the creation and setup. 

In sample 2.2 and 2.3, attachment file cannot exceed the 32k size, because the attachment argument type. 2.1. Simple sample to test the SEND procedure:

CREATE OR REPLACE PROCEDURE send_email AS
BEGIN 
UTL_MAIL.SEND(sender => 'xxx@oracle.com', recipients => 'xxx@oracle.com', cc => 'xxx@oracle.com', bcc => 'xxx@oracle.com', subject => 'Testmail', message => 'Hello');

EXCEPTION
WHEN OTHERS THEN
-- dbms_output.put_line('Fehler');
raise_application_error(-20001,'The following error has occured: ' || sqlerrm); 
END;
/
SHOW ERRORS

exec send_email;

2.2. Sample sending emails with attachments. To run this example the directory object 'MYDIR' must be created.Also there must be a file named attach.txt in that directory.

CREATE OR REPLACE DIRECTORY OBJECT MYDIR as '/tmp'
grant read on directory MYDIR to public;

CREATE OR REPLACE PROCEDURE send_email_attach AS

fHandle utl_file.file_type; 
vTextOut varchar2(32000); 
text varchar2(32000) := NULL;

BEGIN

fHandle := UTL_FILE.FOPEN('MYDIR','attach.txt','r');

IF UTL_FILE.IS_OPEN(fHandle) THEN
DBMS_OUTPUT.PUT_LINE('File read open');
ELSE
DBMS_OUTPUT.PUT_LINE('File read not open');
END IF;

loop
begin
UTL_FILE.GET_LINE(fHandle,vTextOut);
IF text IS NULL THEN
text := text || vTextOut;
ELSE
text := text || UTL_TCP.CRLF || vTextOut;
END IF;
-- dbms_output.put_line(length(text));
EXCEPTION
WHEN NO_DATA_FOUND THEN EXIT;
end;
END LOOP;

--dbms_output.put_line(length(text));

UTL_FILE.FCLOSE(fHandle);

UTL_MAIL.SEND_ATTACH_VARCHAR2(sender => 'xxx@oracle.com', recipients => 'xxx@oracle.com', subject => 'Testmail', message => 'Hello', attachment => text, ATT_INLINE => FALSE); 
EXCEPTION
WHEN OTHERS THEN
-- dbms_output.put_line('Fehler');
raise_application_error(-20001,'The following error has occured: ' || sqlerrm); 
END;
/
SHOW ERRORS

exec send_email_attach

With att_inline you can specify, whether the attachment is viewable inline with the message body or not. With the att_filename parameter you can give the attached file name. 2.3. Sample sending emails with RAW attachments.

set serveroutput on;

create or replace directory BFILE_DIR as 'c:\beispiele\utl_mail';
grant read on directory BFILE_DIR to public;

DECLARE
fil BFILE;
file_len PLS_INTEGER;
MAX_LINE_WIDTH PLS_INTEGER := 54;
buf RAW(2100);
amt BINARY_INTEGER := 2000;
pos PLS_INTEGER := 1; /* pointer for each piece */
filepos PLS_INTEGER := 1; /* pointer for the file */
filenm VARCHAR2(50) := 'clouds.jpg'; /* binary file attachment */
data RAW(2100);
chunks PLS_INTEGER;
len PLS_INTEGER;
modulo PLS_INTEGER;
pieces PLS_INTEGER;
err_num NUMBER;
err_msg VARCHAR2(100); 
resultraw RAW(32000);

BEGIN

/* Assign the file a handle */
fil := BFILENAME('BFILE_DIR', filenm);

/* Get the length of the file in bytes */
file_len := dbms_lob.getlength(fil);

/* Get the remainer when we divide by amt */
modulo := mod(file_len, amt);

/* How many pieces? */
pieces := trunc(file_len / amt);
if (modulo <> 0) then
pieces := pieces + 1;
end if;

/* Open the file */
dbms_lob.fileopen(fil, dbms_lob.file_readonly);

/* Read the first amt into the buffer */
dbms_lob.read(fil, amt, filepos, buf);

/* For each piece of the file . . . */
FOR i IN 1..pieces LOOP

/* Position file pointer for next read */
filepos := i * amt + 1;

/* Calculate remaining file length */
file_len := file_len - amt;

/* Stick the buffer contents into data */
data := utl_raw.concat(data, buf);

/* Calculate the number of chunks in this piece */
chunks := trunc(utl_raw.length(data) / MAX_LINE_WIDTH);

/* Don't want too many chunks */
IF (i <> pieces) THEN
chunks := chunks - 1;
END IF;

/* For each chunk in this piece . . . */
FOR j IN 0..chunks LOOP

/* Position ourselves in this piece */
pos := j * MAX_LINE_WIDTH + 1;

/* Is this the last chunk in this piece? */
IF (j <> chunks) THEN
len := MAX_LINE_WIDTH;
ELSE
len := utl_raw.length(data) - pos + 1;
IF (len > MAX_LINE_width) THEN
len := MAX_LINE_WIDTH;
END IF;
END IF;
/* If we got something, let's write it */
IF (len > 0 ) THEN

resultraw := resultraw || utl_raw.substr(data, pos, len);
END IF;
END LOOP;

/* Point at the rest of the data buffer */
IF (pos + len <= utl_raw.length(data)) THEN
data := utl_raw.substr(data, pos + len);
ELSE
data := NULL;
END IF;

/* We're running out of file, only get the rest of it */
if (file_len < amt and file_len > 0) then
amt := file_len;
end if;

/* Read the next amount into the buffer */
dbms_lob.read(fil, amt, filepos, buf);

END LOOP;

/* Don't forget to close the file */
dbms_lob.fileclose(fil);
UTL_MAIL.SEND_ATTACH_RAW(sender => 'xxx@oracle.com', recipients => 'xxx@oracle.com', subject => 'Testmail', message => 'Hello', attachment => resultraw, att_filename => 'clouds.jpg'); 
EXCEPTION
WHEN OTHERS THEN
--dbms_output.put_line('Fehler');
raise_application_error(-20001,'The following error has occured: ' || sqlerrm); 
END;
/

How to Use the UTL_MAIL Package的更多相关文章

  1. NPM (node package manager) 入门 - 基础使用

    什么是npm ? npm 是 nodejs 的包管理和分发工具.它可以让 javascript 开发者能够更加轻松的共享代码和共用代码片段,并且通过 npm 管理你分享的代码也很方便快捷和简单. 截至 ...

  2. npm package.json属性详解

    概述 本文档是自己看官方文档的理解+翻译,内容是package.json配置里边的属性含义.package.json必须是一个严格的json文件,而不仅仅是js里边的一个对象.其中很多属性可以通过np ...

  3. 关于Visual Studio 未能加载各种Package包的解决方案

    问题: 打开Visual Studio 的时候,总提示未能加载相应的Package包,有时候还无法打开项目,各种提示 解决方案: 进入用户目录 C:\Users\用户名\AppData\Local\M ...

  4. SSIS 包部署 Package Store 后,在 IS 中可以执行,AGENT 执行却报错

    可以执行 SSIS Package ,证明用 SSIS Package 的账户是可以执行成功的.SQL Server Agent 默认指定账号是 Network Service. 那么可以尝试一下将 ...

  5. 如何使用yum 下载 一个 package ?如何使用 yum install package 但是保留 rpm 格式的 package ? 或者又 如何通过yum 中已经安装的package 导出它,即yum导出rpm?

    注意 RHEL5 和 RHEL6 的不同 How to use yum to download a package without installing it Solution Verified - ...

  6. [转]安装 SciTE 报错 No package ‘gtk+-2.0′ found

    centos 记事本,有时候感觉不够用,或者 出毛病,打不开文件 然后决定安装个其他的记事本,  找来找去, 感觉 SciTE 还可以,于是下载源码编译安装,结果 No package ‘gtk+-2 ...

  7. ERROR ITMS-90167: "No .app bundles found in the package"错误

    ERROR ITMS-90167: "No .app bundles found in the package" 出现如上错误请查检以下2个方向: 1.macOS Sierra 1 ...

  8. CRL快速开发框架系列教程八(使用CRL.Package)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. Sublime text 2/3 中 Package Control 的安装与使用方法

    Package Control 插件是一个方便 Sublime text 管理插件的插件,但因为 Sublime Text 3 更新了 Python 的函数,API不同了,导致基于 Python 开发 ...

随机推荐

  1. python内置函数(2)-递归与迭代

    这篇文章简单介绍了迭代和递归的概念.两者的区别 什么是迭代: 迭代是重复反馈过程的活动,其目的通常是为了接近并达到所需的目标或结果.每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来 ...

  2. MapReduce TotalOrderPartitioner 全局排序

    我们知道Mapreduce框架在feed数据给reducer之前会对map output key排序,这种排序机制保证了每一个reducer局部有序,hadoop 默认的partitioner是Has ...

  3. HTML5实战与剖析之classList属性

    classList属性究竟是干什么的,我们先撇下classList不管.我们考虑这么一个问题,那就是我们如何将拥有多个类名的元素中的其中一个类名删除呢?梦龙较劲脑汁儿终于想到一个实现的方法.将拥有类名 ...

  4. LinQ学习手册

    LinQ : Language Integrated Query(语言集成查询); 1.以统一方式操作各种数据源,减少数据访问的复杂性. 优点在于封装了SQL语句,只对对象进行操作(增删改查),代码量 ...

  5. JavaScript阻止事件冒泡

    今天在自学敲代码的时候发现了一个问题,当时的例子如下: <!DOCTYPE html> <html lang="en"> <head> < ...

  6. QT-Creator C/C++ 打地鼠小游戏

    废话少说先上图: 这个游戏纯属土鳖思路,没有用到什么游戏引擎. 1.使用按钮或QLabel铺满窗口. 2.通过简单算法随机动态的设置按钮矩阵中某个按钮的背景图像. 3.同步2过程反复设置多个按钮背景实 ...

  7. 在一个RAC集群中最多支持多少节点

    How many nodes can one have in an HP-UX/Solaris/AIX/Windows/Linux cluster? Technically and since Ora ...

  8. xcode新建项目介绍

    xcode新建项目介绍 1.打开xcode选择“create a new xcode project 2.product name 工程名称 campany identifter 公司id 一般都写公 ...

  9. iOS设计模式解析(四)组合模式

    组合模式:将对象组合成树形结构以表示"部分-整体"的层次结构.组合是的用户对单个对象和组合对象的使用具有一致 Cocoa Touch中组合模式使用:Cocoa Touch框架中,U ...

  10. Android Studio 项目目录结构 英文版

    I don't know if this is because of the Gradle Build System (I'd wager it is), but I'll tell you what ...