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 ...
随机推荐
- 一、Android NDK编程预备之Java jni简介
转自: http://www.eoeandroid.com/thread-264384-1-1.html 游戏开发 视频教程 博客 淘帖 论坛›eoe·Android应用开发区›Androi ...
- YARN集群维护部分问题汇总
云梯开发人员在云梯Yarn集群的搭建和维护过程中做了许多工作,本文选择这期间部分较为典型的问题,通过对这些问题的分析和解决方案,为大家分享分布式系统问题调查的经验. 调查的问题 1. 2013年初引入 ...
- lintcode:最小差
最小差 给定两个整数数组(第一个是数组 A,第二个是数组 B),在数组 A 中取 A[i],数组 B 中取 B[j],A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|).返回最小差. ...
- Project Euler 103:Special subset sums: optimum 特殊的子集和:最优解
Special subset sums: optimum Let S(A) represent the sum of elements in set A of size n. We shall cal ...
- 540A: Combination Lock
题目链接:http://codeforces.com/problemset/problem/540/A 题意: 输入的两个长度一样的数,求对应位置的某位数到下一个数需要最小的步长,每次只能先前或先后走 ...
- iOS开发--控件
iOS知识点整理-提示器 http://www.jianshu.com/p/ac7e13d36e32 iOS知识点整理-RunLoop http://www.jianshu.com/p/e4fc6ac ...
- iOS开发--基于AFNetWorking3.0的图片缓存分析
图片在APP中占有重要的角色,对图片做好缓存是重要的一项工作.[TOC] 理论 不喜欢理论的可以直接跳到下面的Demo实践部分 缓存介绍 缓存按照保存位置可以分为两类:内存缓存.硬盘缓存(FMDB.C ...
- push与concat
push push()方法将一个或多个元素添加到数组的末尾,并且返回新的数组长度. 语法: arr.push(element1, ..., elementN) concat concat() 方法用于 ...
- Linux远程文件传输
linux系统中,难免会遇到一些要将某文件通过网络传送给其他主机的情况,而恰好两台主机 都是linux系统的时候,我们就可以直接使用scp命令来传输文件到另一台主机了. scp命令用于在网络中安全的传 ...
- python中写shell(转)
python中写shell,亲测可用,转自stackoverflow To run a bash script, copy from stackoverflow def run_script(scri ...