Oracle发送邮件,支持HTML,多收件人,多附件
- 创建 ACL
BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(acl => 'email_server_permissions.xml',
description => 'Enables network permissions for the e-mail server',
principal => 'LJZ',
is_grant => TRUE,
privilege => 'connect');
END;
-- 与邮件服务关联
BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(acl => 'email_server_permissions.xml',
host => 'smtp.163.com',
lower_port => 25,
upper_port => NULL);
END;
-- 这样 email_user 用户帐户创建的存储过程便可以向此邮件服务器发送邮件
--删除
BEGIN
DBMS_NETWORK_ACL_ADMIN.drop_acl(acl => 'email_server_permissions.xml');
COMMIT;
END;
--查询
SELECT host, lower_port, upper_port, acl FROM dba_network_acls;
SELECT acl,
principal,
privilege,
is_grant,
TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,
TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date
FROM dba_network_acl_privileges;
存储过程
- create or replace procedure p_send_mail(p_from in varchar2,
- p_to in varchar2,
- p_subject in varchar2,
- p_text in clob default null,
- p_html in clob default null,
- p_attachment_path varchar2,
- p_smtp_hostname in varchar2,
- p_smtp_portnum in varchar2 default 25,
- p_need_valid varchar2 default 'Y',
- p_user_name varchar2,
- p_user_pwd varchar2) is
- /*
- 作用:用oracle发送邮件
- 主要功能:1、支持多收件人。
- 2、支持中文
- 3、支持抄送人
- 4、支持大于32K的附件
- 5、支持多行正文
- 6、支持多附件
- 7、支持HTML邮件
- 作者:HH
- 参数说明:
- p_from 发件人
- p_to 收件人,多收件人用逗号或分号分隔
- p_subject 主题
- p_text 文本内容
- p_html HTML内容
- p_attachment_path 附件地址(绝对路径),多附件用逗号或分号分隔
- p_smtp_hostname 邮件服务器地址 例:smtp.163.com
- p_smtp_portnum 端口号,默认25
- p_need_valid 是否需要用户名密码验证,默认需要('Y')
- p_user_name 用户名
- p_user_pwd 密码
- */
- l_crlf varchar2(2) := utl_tcp.crlf;
- l_write_encode varchar2(20) := 'zhs16gbk';
- l_attachment_encode varchar2(10) := 'base64';
- l_attachment_mime_type varchar2(50) := 'application/octet-stream';
- l_attachment_disposition varchar2(10) := 'attachment';
- l_boundary_mail varchar2(255) default '#---hh***hh-mail---#';
- l_boundary_content varchar2(255) default '#---hh***hh-content---#';
- l_first_boundary constant varchar2(256) := '--' || l_boundary_mail ||
- l_crlf;
- l_last_boundary constant varchar2(256) := '--' || l_boundary_mail || '--' ||
- l_crlf;
- l_connection utl_smtp.connection;
- l_body_html clob := empty_clob; --HTML邮件内容
- l_offset number;
- l_ammount number;
- l_temp varchar2(32767) default null;
- l_file_handle utl_file.file_type;
- l_line varchar2(1000);
- l_mesg varchar2(32767);
- l_filepos pls_integer := 1;
- l_fil bfile;
- l_file_len number;
- l_modulo number;
- l_pieces number;
- l_amt number := 8580;
- l_chunks number;
- l_buf raw(32767);
- l_data raw(32767);
- l_max_line_width number := 54;
- l_directory_base_name varchar2(100) := 'DIR_FOR_SEND_MAIL';
- l_receivers varchar2(32767);
- l_count number;
- type address_list is table of varchar2(100) index by binary_integer;
- my_address_list address_list;
- type acct_list is table of varchar2(100) index by binary_integer;
- my_acct_list acct_list;
- --分割邮件地址或者附件地址
- procedure sub_splite_str(p_str varchar2, p_splite_flag int default 1) is
- l_addr varchar2(254) := '';
- l_len int;
- l_str varchar2(4000);
- j int := 0; --表示邮件地址或者附件的个数
- begin
- /*处理接收邮件地址列表,包括去空格、将;转换为,等*/
- l_str := trim(rtrim(replace(replace(p_str, ';', ','), ' ', ''), ','));
- l_len := length(l_str);
- for i in 1 .. l_len loop
- if substr(l_str, i, 1) <> ',' then
- l_addr := l_addr || substr(l_str, i, 1);
- else
- j := j + 1;
- if p_splite_flag = 1 then
- --表示处理邮件地址
- --前后需要加上'<>',否则很多邮箱将不能发送邮件
- l_addr := '<' || l_addr || '>';
- --调用邮件发送过程
- my_address_list(j) := l_addr;
- elsif p_splite_flag = 2 then
- --表示处理附件名称
- my_acct_list(j) := l_addr;
- end if;
- l_addr := '';
- end if;
- if i = l_len then
- j := j + 1;
- if p_splite_flag = 1 then
- --调用邮件发送过程
- l_addr := '<' || l_addr || '>';
- my_address_list(j) := l_addr;
- elsif p_splite_flag = 2 then
- my_acct_list(j) := l_addr;
- end if;
- end if;
- end loop;
- end;
- --删除directory
- procedure sub_drop_directory(p_directory_name varchar2) is
- begin
- select count(1)
- into l_count
- from dba_directories
- where directory_name = upper(p_directory_name);
- if l_count > 0 then
- execute immediate 'drop directory ' || p_directory_name;
- end if;
- exception
- when others then
- --null;
- raise;
- end;
- --创建directory
- procedure sub_create_directory(p_directory_name varchar2, p_dir varchar2) is
- begin
- execute immediate 'create directory ' || p_directory_name || ' as ''' ||
- p_dir || '''';
- execute immediate 'grant read,write on directory ' || p_directory_name ||
- ' to public';
- exception
- when others then
- raise;
- end;
- --返回附件源文件所在目录或者名称
- function sub_get_file(p_file varchar2, p_get int) return varchar2 is
- --p_get=1 表示返回目录
- --p_get=2 表示返回文件名
- l_file varchar2(1000);
- begin
- if instr(p_file, '\') > 0 then
- if p_get = 1 then
- l_file := substr(p_file, 1, instr(p_file, '\', -1) - 1) || '\';
- elsif p_get = 2 then
- l_file := substr(p_file,
- - (length(p_file) - instr(p_file, '\', -1)));
- end if;
- elsif instr(p_file, '/') > 0 then
- if p_get = 1 then
- l_file := substr(p_file, 1, instr(p_file, '/', -1) - 1);
- elsif p_get = 2 then
- l_file := substr(p_file,
- - (length(p_file) - instr(p_file, '/', -1)));
- end if;
- end if;
- return l_file;
- end;
- --发送附件
- procedure sub_attachment(conn in out nocopy utl_smtp.connection,
- filename in varchar2,
- dt_name in varchar2) is
- l_filename varchar2(1000);
- l_amount number;
- begin
- sub_drop_directory(dt_name);
- --创建directory
- sub_create_directory(dt_name, sub_get_file(filename, 1));
- --得到附件文件名称
- l_filename := sub_get_file(filename, 2);
- l_temp := l_temp || l_crlf || '--' || l_boundary_mail || l_crlf;
- l_temp := l_temp || 'Content-Type: ' || l_attachment_mime_type || ';
- name="' || l_filename || '"
- Content-Transfer-Encoding: ' || l_attachment_encode || '
- Content-Disposition: ' || l_attachment_disposition || ';
- filename="' || l_filename || '"' || l_crlf || l_crlf;
- utl_smtp.write_raw_data(l_connection,
- utl_raw.cast_to_raw(convert(l_temp,
- l_write_encode)));
- --begin
- --begin
- --把附件分成多份,这样可以发送超过32k的附件
- l_filepos := 1; --重置offset,在发送多个附件时,必须重置
- l_fil := bfilename(dt_name, l_filename);
- l_file_len := dbms_lob.getlength(l_fil);
- l_modulo := mod(l_file_len, l_amt);
- l_pieces := trunc(l_file_len / l_amt);
- if (l_modulo <> 0) then
- l_pieces := l_pieces + 1;
- end if;
- dbms_lob.fileopen(l_fil, dbms_lob.file_readonly);
- l_data := null;
- l_amount := l_amt;
- for i in 1 .. l_pieces loop
- dbms_lob.read(l_fil, l_amount, l_filepos, l_buf);
- l_filepos := i * l_amount + 1;
- l_file_len := l_file_len - l_amount;
- utl_smtp.write_raw_data(conn, utl_encode.base64_encode(l_buf));
- if i = l_pieces then
- l_amount := l_file_len;
- end if;
- end loop;
- dbms_lob.fileclose(l_fil);
- /*exception
- when others then
- dbms_lob.fileclose(l_fil);
- sub_end_boundary(conn);
- raise;
- end; --结束处理二进制附件*/
- sub_drop_directory(dt_name);
- end; --结束过程attachment
- procedure sub_send_mail is
- l_from varchar2(1000) := '<' || p_from || '>';
- begin
- l_connection := utl_smtp.open_connection(p_smtp_hostname,
- p_smtp_portnum);
- utl_smtp.helo(l_connection, p_smtp_hostname);
- /* smtp服务器登录校验 */
- if p_need_valid = 'Y' then
- utl_smtp.command(l_connection, 'AUTH LOGIN', '');
- utl_smtp.command(l_connection,
- utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(p_user_name))));
- utl_smtp.command(l_connection,
- utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(p_user_pwd))));
- end if;
- utl_smtp.mail(l_connection, l_from);
- sub_splite_str(p_to); --处理邮件地址
- for k in 1 .. my_address_list.count loop
- l_receivers := l_receivers || my_address_list(k) || ';';
- utl_smtp.rcpt(l_connection, my_address_list(k));
- end loop;
- l_temp := l_temp || 'From: ' || l_from || l_crlf;
- l_temp := l_temp || 'To: ' || l_receivers || l_crlf;
- --l_temp := l_temp || 'Cc: ' || l_receivers || l_crlf;--抄送
- --l_temp := l_temp || 'Bcc: ' || l_receivers || l_crlf;--密送
- l_temp := l_temp || 'Subject: ' || p_subject || l_crlf;
- --l_temp := l_temp || 'X-Mailer: Foxmail 7, 1, 3, 48[cn]' || l_crlf;--发送客户端
- l_temp := l_temp || 'Content-Type: multipart/mixed; boundary="' ||
- l_boundary_mail || '"' || l_crlf;
- l_temp := l_temp || 'MIME-Version: 1.0' || l_crlf || l_crlf;
- l_temp := l_temp || '--' || l_boundary_mail || l_crlf;
- if nvl(p_attachment_path, ' ') <> ' ' then
- l_temp := l_temp || 'content-type: multipart/alternative; boundary="' ||
- l_boundary_content || '"' || l_crlf || l_crlf || l_crlf;
- l_temp := l_temp || '--' || l_boundary_content || l_crlf;
- end if;
- --开始
- dbms_lob.createtemporary(l_body_html, false, 10);
- dbms_lob.write(l_body_html, length(l_temp), 1, l_temp);
- --文本内容
- l_offset := dbms_lob.getlength(l_body_html) + 1;
- l_temp := 'content-type: text/plain; charset="GB2312"; Content-Transfer-Encoding: base64' ||
- l_crlf || l_crlf;
- dbms_lob.write(l_body_html, length(l_temp), l_offset, l_temp);
- if trim(p_text) is not null then
- dbms_lob.append(l_body_html, p_text);
- end if;
- --html内容
- if nvl(p_attachment_path, ' ') <> ' ' then
- l_temp := l_crlf || l_crlf || '--' || l_boundary_content ||'--' || l_crlf;
- else
- l_temp := l_crlf || l_crlf || '--' || l_boundary_mail ||'--' || l_crlf;
- end if;
- l_temp := l_temp ||
- 'content-type: text/html;charset="GB2312";Content-Transfer-Encoding: quoted-printable' ||
- l_crlf || l_crlf;
- l_offset := dbms_lob.getlength(l_body_html) + 1;
- dbms_lob.write(l_body_html, length(l_temp), l_offset, l_temp);
- dbms_lob.append(l_body_html, nvl(p_html, ' '));
- --content结束
- if nvl(p_attachment_path, ' ') <> ' ' then
- l_temp := l_crlf || l_crlf || '--' || l_boundary_content || '--' ||
- l_crlf || l_crlf;
- else
- l_temp := l_crlf || '--' || l_boundary_mail || '--' || l_crlf ||
- l_crlf;
- end if;
- l_offset := dbms_lob.getlength(l_body_html) + 1;
- dbms_lob.write(l_body_html, length(l_temp), l_offset, l_temp);
- --写入邮件
- l_offset := 1;
- l_ammount := 1900;
- utl_smtp.open_data(l_connection);
- while l_offset < dbms_lob.getlength(l_body_html) loop
- utl_smtp.write_raw_data(l_connection,
- utl_raw.cast_to_raw(convert(dbms_lob.substr(l_body_html,
- l_ammount,
- l_offset),
- l_write_encode)));
- l_offset := l_offset + l_ammount;
- l_ammount := least(1900, dbms_lob.getlength(l_body_html) - l_ammount);
- end loop;
- commit;
- ----------------------------------------------------
- l_temp := null;
- --附件
- --如果文件名称不为空,则发送附件
- if (p_attachment_path is not null) then
- --根据逗号或者分号拆分附件地址
- sub_splite_str(p_attachment_path, 2);
- --循环发送附件(在同一个邮件中)
- for k in 1 .. my_acct_list.count loop
- sub_attachment(conn => l_connection,
- filename => my_acct_list(k),
- dt_name => l_directory_base_name || to_char(k));
- l_temp := l_crlf;
- end loop;
- end if;
- l_temp := l_crlf || l_crlf || '--' || l_boundary_mail || '--' || l_crlf ||
- l_crlf;
- utl_smtp.write_raw_data(l_connection,
- utl_raw.cast_to_raw(convert(l_temp,
- l_write_encode)));
- commit;
- utl_smtp.close_data(l_connection);
- utl_smtp.quit(l_connection);
- --utl_smtp.close_connection(l_connection);
- dbms_lob.freetemporary(l_body_html);
- end;
- begin
- sub_send_mail();
- /*exception
- when others then
- null;*/
- end;
Oracle发送邮件,支持HTML,多收件人,多附件的更多相关文章
- ci框架(codeigniter)Email发送邮件、收件人、附件、Email调试工具
ci框架(codeigniter)Email发送邮件.收件人.附件.Email调试工具 Email 类 CodeIgniter 拥有强大的 Email 类来提供如下的功能: 多 ...
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- 安装oracle10g“程序异常终止。发生内部错误。请将以下文件提供给oracle技术支持部门
发生情景:测试环境搭建的是windows 2008 r2 sp1系统 在安装Oracle 10g数据库时发生了错误,现在把解决问题的方法和原因分享给大家. * 安装出现的现象: 输入完密码后下一步时 ...
- windows2008 安装oracle10g“程序异常终止。发生内部错误。请将以下文件提供给oracle技术支持部门
在安装oracle10g客户端程序的时候发生了错误!错误如下:“程序异常终止.发生内部错误.请将以下文件提供给oracle技术支持部门:“未知”“未知”“未知” 解决办法: 右键点setup.exe ...
- Oracle GoldenGate 支持 从SAP HANA database抽取或者复制数据到SAP HANA database 吗?
Oracle GoldenGate 支持 从SAP HANA database抽取或者复制数据到SAP HANA database 吗? 来源于: Does Oracle GoldenGate Su ...
- 【从翻译mos文章】在oracle db 11gR2版本号被启用 Oracle NUMA 支持
在oracle db 11gR2版本号被启用 Oracle NUMA 支持 参考原始: Enable Oracle NUMA support with Oracle Server Version 11 ...
- python发送邮件的实例代码(支持html、图片、附件)
转自http://www.jb51.net/article/34498.htm 第一段代码 #!/usr/bin/python# -*- coding: utf-8 -*- import emaili ...
- mono中发送邮件并保存本次收件人的地址
在ios端mono开发中,发送邮件可以选择调用ios原生email程序.有两种方式实现这种功能,一是程序跳转到ipad中email程序,另外一种是将发送邮件的界面在自己应用里弹出. 首先第一种方式的代 ...
- Python使用SMTP发送邮件[HTML格式、送带附件]
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. python的smtplib提供了一 ...
随机推荐
- Android线程管理之Thread使用总结
前言 最近在一直准备总结一下Android上的线程管理,今天先来总结一下Thread使用. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Executo ...
- IDDD 实现领域驱动设计-上下文映射图及其相关概念
上一篇:<IDDD 实现领域驱动设计-理解限界上下文> 距离上一篇有几天时间了,<实现领域驱动设计>第三章的内容都是围绕一个词-上下文映射图,我大概断断续续看了几天,总共看了两 ...
- Android官方文档
下面的内容来自Android官方网站,由于访问这个网站需要FQ,不方便,所以我把部分内容copy下来了,不保证内容是最新的. Source Overview Codelines, Branche ...
- spring aop
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
- javaScript笔记
两边符号是tab键上面的那个键,不是单引号 即在sort内置的函数中先将各字符串转化为统一的大写或者小写,再进行比较即可. -------------------------------------- ...
- JSP实现word文档的上传,在线预览,下载
前两天帮同学实现在线预览word文档中的内容,而且需要提供可以下载的链接!在网上找了好久,都没有什么可行的方法,只得用最笨的方法来实现了.希望得到各位大神的指教.下面我就具体谈谈自己的实现过程,总结一 ...
- uploadify使用的一些经验总结
说说自己使用uploadify的一波三折的曲折过程: 之所以要选择uploadify,是源于自己先前使用过jQuery官网的上传文件插件,比较难用(页面写的代码比较多,IE下后台回传需要配置格式[不清 ...
- 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇
http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...
- ASP.NET Core官方计划路线及需要废除的一些Framework技术
概述 下面是 ASP.NET Core的时间表和路线图. 注意日期和特性都可能更改. 作为.NET Core这么大的一个项目,很难准确预测每一个计划的是否有变动. 即便如此,我们还是计划公开和透明的实 ...
- .NET跨平台之旅:将QPS 100左右的ASP.NET Core站点部署到Linux服务器上
今天下午我们将生产环境中一个单台服务器 QPS(每秒请求数)在100左右的 ASP.NET Core 站点部署到了 Linux 服务器上,这是我们解决了在 .NET Core 上使用 EnyimMem ...