PL/SQL 下邮件发送程序
对DBA而言,尽管在os级别下发送邮件是轻而易举的事情,然而很多时候我们也需要在PL/SQL中来发送邮件,比如监控job的执行状况等。本文根据网友(源作者未考证)的代码将其改装并封装到了package,感谢这位网友的无私奉献。文章首先给出演示调用该包发送邮件的情形后面给出了完整的代码。经测试Oracle 10g,Oracle 11g下均可用。关于os下发送邮件可参考:不可或缺的 sendEmail
1、调用SENDMAIL_PKG来发送邮件
- gx_admin@SYBO2SZ> set serveroutput on;
- gx_admin@SYBO2SZ> DECLARE
- 2 P_RECEIVER VARCHAR2(32767);
- 3 P_SUB VARCHAR2(32767);
- 4 P_TXT VARCHAR2(32767);
- 5 ERR_NUM NUMBER;
- 6 ERR_MSG VARCHAR2(32767);
- 7
- 8 BEGIN
- 9 P_RECEIVER := 'robinson.chen@12306.com';
- 10 P_SUB := 'Test mail';
- 11 P_TXT := 'This is a test mail.';
- 12 ERR_NUM := NULL;
- 13 ERR_MSG := NULL;
- 14
- 15 SENDMAIL_PKG.SENDMAIL ( P_RECEIVER, P_SUB, P_TXT, ERR_NUM, ERR_MSG );
- 16
- 17 DBMS_OUTPUT.Put_Line('ERR_NUM = ' || TO_CHAR(ERR_NUM));
- 18 DBMS_OUTPUT.Put_Line('ERR_MSG = ' || ERR_MSG);
- 19
- 20 DBMS_OUTPUT.Put_Line('');
- 21
- 22 COMMIT;
- 23 END;
- 24 /
- ERR_NUM = 0
- ERR_MSG =
- PL/SQL procedure successfully completed.
2、邮件发送结果
3、原代码
- --specification section
- CREATE OR REPLACE PACKAGE "SENDMAIL_PKG"
- IS
- PROCEDURE sendmail (p_receiver VARCHAR2,
- p_sub VARCHAR2,
- p_txt VARCHAR2,
- err_num OUT NUMBER,
- err_msg OUT VARCHAR2);
- END;
- /
- --body section
- CREATE OR REPLACE PACKAGE BODY "SENDMAIL_PKG"
- IS
- PROCEDURE sendmail (p_receiver VARCHAR2,
- p_sub VARCHAR2,
- p_txt VARCHAR2,
- err_num OUT NUMBER,
- err_msg OUT VARCHAR2)
- IS
- /* p_receiver => receiver
- p_sub => mail subject
- p_txt => mail content
- */
- p_user VARCHAR2 (30) := NULL;
- p_pass VARCHAR2 (30) := NULL;
- p_sendor VARCHAR2 (40) := 'DBA@gotrade.com';
- p_server VARCHAR2 (20)
- -- := system_pkg.get_sys_para_value ('TC_SMTP_IP'); --'192.168.7.65';
- :='192.168.7.65';
- p_port NUMBER := 25;
- p_need_smtp NUMBER := 0;
- p_subject VARCHAR2 (4000);
- l_crlf VARCHAR2 (2) := UTL_TCP.crlf;
- l_sendoraddress VARCHAR2 (4000);
- l_splite VARCHAR2 (10) := '++';
- boundary CONSTANT VARCHAR2 (256) := '-----BYSUK';
- first_boundary CONSTANT VARCHAR2 (256) := '--' || boundary || l_crlf;
- last_boundary CONSTANT VARCHAR2 (256)
- := '--' || boundary || '--' || l_crlf ;
- multipart_mime_type CONSTANT VARCHAR2 (256)
- := 'multipart/mixed; boundary="' || boundary || '"' ;
- TYPE address_list IS TABLE OF VARCHAR2 (100)
- INDEX BY BINARY_INTEGER;
- my_address_list address_list;
- ---------------------------------------split mail address----------------------------------------------
- PROCEDURE p_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
- /*Handle recieve mail address, such like blank, semicolon*/
- 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
- --Add symbol '<>' for each mail address. else could not send to many reciever
- l_addr := '<' || l_addr || '>';
- my_address_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;
- END IF;
- END IF;
- END LOOP;
- END;
- -----------------------------------write mail header and mail content----------------------------------
- PROCEDURE write_data (p_conn IN OUT NOCOPY UTL_SMTP.connection,
- p_name IN VARCHAR2,
- p_value IN VARCHAR2,
- p_splite VARCHAR2 DEFAULT ':',
- p_crlf VARCHAR2 DEFAULT l_crlf)
- IS
- BEGIN
- /* utl_raw.cast_to_raw to handle chinese code*/
- UTL_SMTP.write_raw_data (
- p_conn,
- UTL_RAW.cast_to_raw (
- CONVERT (p_name || p_splite || p_value || p_crlf,
- 'ZHS16CGB231280')));
- END;
- ----------------------------------------write mime mail tail-----------------------------------------------------
- PROCEDURE end_boundary (conn IN OUT NOCOPY UTL_SMTP.connection,
- LAST IN BOOLEAN DEFAULT FALSE)
- IS
- BEGIN
- UTL_SMTP.write_data (conn, UTL_TCP.crlf);
- IF (LAST)
- THEN
- UTL_SMTP.write_data (conn, last_boundary);
- END IF;
- END;
- ---------------------------------------------send mail procedure--------------------------------------------
- PROCEDURE p_email (p_sendoraddress2 VARCHAR2, --sender address
- p_receiveraddress2 VARCHAR2) --reciever address
- IS
- l_conn UTL_SMTP.connection; --create a connection
- BEGIN
- /*Initial mail server*/
- l_conn := UTL_SMTP.open_connection (p_server, p_port);
- UTL_SMTP.helo (l_conn, p_server);
- /* smtp authentication*/
- IF p_need_smtp = 1
- THEN
- UTL_SMTP.command (l_conn, 'AUTH LOGIN', '');
- UTL_SMTP.command (
- l_conn,
- UTL_RAW.cast_to_varchar2 (
- UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw (p_user))));
- UTL_SMTP.command (
- l_conn,
- UTL_RAW.cast_to_varchar2 (
- UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw (p_pass))));
- END IF;
- /*configure sender and reciever mail address*/
- UTL_SMTP.mail (l_conn, p_sendoraddress2);
- UTL_SMTP.rcpt (l_conn, p_receiveraddress2);
- /*configure mail header*/
- UTL_SMTP.open_data (l_conn);
- /*configure date*/
- --write_data(l_conn, 'Date', to_char(sysdate-1/3, 'dd Mon yy hh24:mi:ss'));
- /*configure sender*/
- write_data (l_conn, 'From', p_sendor);
- /*configure reciever*/
- write_data (l_conn, 'To', p_receiver);
- /*add mail subject*/
- SELECT REPLACE (
- '=?GB2312?B?'
- || UTL_RAW.cast_to_varchar2 (
- UTL_ENCODE.base64_encode (RAWTOHEX (p_sub)))
- || '?=',
- UTL_TCP.crlf,
- '')
- INTO p_subject
- FROM DUAL;
- write_data (l_conn, 'Subject', p_subject);
- write_data (l_conn, 'Content-Type', multipart_mime_type);
- UTL_SMTP.write_data (l_conn, UTL_TCP.crlf);
- UTL_SMTP.write_data (l_conn, first_boundary);
- write_data (l_conn, 'Content-Type', 'text/html');
- UTL_SMTP.write_data (l_conn, UTL_TCP.crlf);
- write_data (
- l_conn,
- '',
- REPLACE (REPLACE (p_txt, l_splite, CHR (10)), CHR (10), l_crlf),
- '',
- '');
- end_boundary (l_conn);
- /*close write data*/
- UTL_SMTP.close_data (l_conn);
- /*close connection*/
- UTL_SMTP.quit (l_conn);
- END;
- ---------------------------------------------main procedure -----------------------------------------------------
- BEGIN
- err_num := 0;
- l_sendoraddress := '<' || p_sendor || '>';
- p_splite_str (p_receiver); --handle mail address
- FOR k IN 1 .. my_address_list.COUNT
- LOOP
- p_email (l_sendoraddress, my_address_list (k));
- END LOOP;
- END;
- END;
- /
- 转:http://blog.csdn.net/leshami/article/details/18616901
PL/SQL 下邮件发送程序的更多相关文章
- C# SMTP邮件发送程序
邮件发送在网站应用程序中经常会用到,包括您现在看到的博客,在添加评论后,系统会自动发送邮件通知到我邮箱的,把系统发送邮件的功能整理了下,做了一个客户端Demo,希望对有需要的童鞋有所帮助: 核心代码: ...
- mailto - 简单多媒体邮件发送程序
SYNOPSIS mailto [-a] [-c] [-s] [recipient name(s)] DESCRIPTION mailto 程序是一个用于发送MIME格式的多媒体邮件(MIME格式是 ...
- python3实现邮件发送程序
刚开始的想法很简单,由于有上千封的邮件需要发出去,并且需要一条一条发送,不能转发或群发,每条邮件要署对方的姓名,并加上几个相同的符件,考虑到手工操作繁琐无趣,所以想到用程序实现,python好像非常胜 ...
- linux(debian)下邮件发送
关键字: exim4 mutt smtp 主要的事情就是配置exim4,按照网上的流程来.在这里总结一下: 需要修改的文件有三个:/etc/exim4/update-exim4.conf.conf ...
- pl/sql学习(6): 引号/程序调试/列中的字符串合并/正则表达式
有关自治事务的问题: https://www.cnblogs.com/princessd8251/p/4132649.html 我在plsql development学习中遇到的常见问题: (一) 引 ...
- PL/SQL 下 Command window 与 SQL window 的区别
1.Command window实现了SQL*Plus的所有功能,允许运行sql*plus命令,sql命令,sql脚本. 2.SQL window用于执行sql语句,显示sql输出,执行统计信息.(测 ...
- Oracle+PL+SQL从入门到精通.丁士锋.清华大学出版社.2012
\t第1篇 pl/sql开发入门第1章 oracle 11g数据库系统1.1 关系型数据库系统介绍1.1.1 什么是关系型数据模型1.1.2 数据库系统范式1.1.3 关系型数据库管理系统1.1.4 ...
- Chilkat----开源站点之VS2010 CKMailMan一个很好的邮件发送开源开发包
Chilkat 是一个很好的开源站点,有各种开源库. 开发语言主要有Classic ASP •C • C++ • C# • Delphi ActiveX • Delphi DLL • Visual F ...
- Oracle学习笔记之五sp1,PL/SQL之BULK COLLECT
Bulk Collect特性可以让我们在PL/SQL中能使用批查询,批查询在某些情况下能显著提高查询效率. BULK COLLECT 子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从SQ ...
随机推荐
- Fiddler手机抓包工具如何设置过滤域名?
fiddler手机抓包工具如何设置过滤域名?如题.fiddler抓包可以完成我们移动开发者的调试测试需求.所以说抓包尤其重要,但是多余的网页请求和手机的其他链接影响我们手机开发的需求.下面我教大家怎么 ...
- hdu1715
http://acm.hdu.edu.cn/showproblem.php?pid=1715 模板大数: #include <stdio.h> #include <string.h& ...
- VBA高效删除不连续多行
最近在搞VBA,在感叹Excel功能强大的同时,对于新接触的一门编程语言也很烦恼.很多基础的语法都要靠网上搜索.现总结一些学习到的心得. VBA高效删除不连续多行 在一个拥有几万条数据的Excel中, ...
- Log4J入门教程(二) 参数讲解
继续接着Log4J入门教程(一)中的例子进行讲解,其中log4j.properties中的内容为 Log4j的三个重要组件—— Loggers, Appenders, Layouts ,这三个组 ...
- Android ListView无法触发ItemClick事件
Android ListView无法触发ItemClick事件 开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承Base ...
- Java笔记——面向切面编程(AOP模式)
原文:http://www.cnblogs.com/yanbincn/archive/2012/06/01/2530377.html Aspect Oriented Programming 面向切面 ...
- 277. Find the Celebrity
题目: Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exi ...
- js中indexOF和lastIndexOf
indexOFindexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置(从左向右).没有匹配的则返回-1,否则返回首次出现位置的字符串的下标值. var src="images ...
- JNI层问题
1. make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/g ...
- shell进行mysql统计
array=(江苏 浙江 新疆 宁夏 广东 福建 重庆 江西 吉林 湖南 山东 云南 上海 河北 黑龙江 北京 四川 河南 山西 湖北 辽宁 安徽 陕西 广西 贵州 内蒙古 天津 甘肃 海南 青海 ...