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 ...
随机推荐
- [转载] ACE 组播校验和出错问题解决
源地址:http://yuanmuqiuyu2000.blog.sohu.com/140904942.html 使用ACE框架写了个组播简单的测试工具,但是测试过程中,总是发现udp校验和出错的信息. ...
- UVALive 6187 Never Wait for Weights 带权并查集
题意:每次给出每两个数之间的大小差值.在给出关系的过程中插入询问:数a和数b的差值,若不能确定,输出UNKNOWN 解法:相对大小关系的处理:并查集 1.给出两点的相对大小关系后,找到两个点的根节点, ...
- 妙味课堂——HTML+CSS(第四课)(二)
单开一篇来讲一个大点的话题——清浮动 来看下例: <!DOCTYPE html> <html> <head> <meta charset="U ...
- linux下PostgreSQL数据库的源码安装
实验环境>>>>>>>>>>>>>>>>>>操作系统:CentOS release 6.3 ...
- Newtonsoft.Json.dll
代码 using System; DoNet2.0 需要借助于Newtonsoft.Json.dll using System.IO; using System.Text; using Newtons ...
- Java-在线聊天系统-线程
一.概述 1.目标:在上一个版本非线程的聊天系统中,出于要不断监听接收新client和接收client发出的信息,把accept()和DataInputStream.readUTF()分别写在了whi ...
- Python3导入自定义模块的3种方式
前话 最近跟着廖雪峰的教程学到 模块 这一节.关于如何自定义一个模块,如果大家不懂的话还请先看下面这篇博文 ↓ http://www.liaoxuefeng.com/wiki/001431608955 ...
- Control Flow ->> Containers
Sequence Container: 它的作用就是可以把一组任务绑定起来成为一个整体,这样Sequence本身就是具有了任务(task)的特性,比如TransactionOption.如果需要把一组 ...
- Java 数据结构之Stack
Stack类表示后进先出(LIFO)的对象堆栈.栈是一种非常常见的数据结构.Stack继承Vector,并对其进行了扩展. 用法: 1.只有一个构造函数: public Stack() {} 2.创建 ...
- USACO Section 3.1: Score Inflation
完全背包问题 /* ID: yingzho1 LANG: C++ TASK: inflate */ #include <iostream> #include <fstream> ...