PL/SQL 下邮件发送程序

对DBA而言,尽管在os级别下发送邮件是轻而易举的事情,然而很多时候我们也需要在PL/SQL中来发送邮件,比如监控job的执行状况等。本文根据网友(源作者未考证)的代码将其改装并封装到了package,感谢这位网友的无私奉献。文章首先给出演示调用该包发送邮件的情形后面给出了完整的代码。经测试Oracle 10g,Oracle 11g下均可用。关于os下发送邮件可参考:不可或缺的 sendEmail

1、调用SENDMAIL_PKG来发送邮件

[sql] view plain copy

print?

  1. [email protected]> set serveroutput on;
  2. [email protected]> DECLARE
  3. 2    P_RECEIVER VARCHAR2(32767);
  4. 3    P_SUB VARCHAR2(32767);
  5. 4    P_TXT VARCHAR2(32767);
  6. 5    ERR_NUM NUMBER;
  7. 6    ERR_MSG VARCHAR2(32767);
  8. 7
  9. 8  BEGIN
  10. 9    P_RECEIVER := ‘[email protected]com‘;
  11. 10    P_SUB := ‘Test mail‘;
  12. 11    P_TXT := ‘This is a test mail.‘;
  13. 12    ERR_NUM := NULL;
  14. 13    ERR_MSG := NULL;
  15. 14
  16. 15    SENDMAIL_PKG.SENDMAIL ( P_RECEIVER, P_SUB, P_TXT, ERR_NUM, ERR_MSG );
  17. 16
  18. 17    DBMS_OUTPUT.Put_Line(‘ERR_NUM = ‘ || TO_CHAR(ERR_NUM));
  19. 18    DBMS_OUTPUT.Put_Line(‘ERR_MSG = ‘ || ERR_MSG);
  20. 19
  21. 20    DBMS_OUTPUT.Put_Line(‘‘);
  22. 21
  23. 22    COMMIT;
  24. 23  END;
  25. 24  /
  26. ERR_NUM = 0
  27. ERR_MSG =
  28. PL/SQL procedure successfully completed.

2、邮件发送结果

3、原代码

[sql] view plain copy

print?

    1. --specification section
    2. CREATE OR REPLACE PACKAGE "SENDMAIL_PKG"
    3. IS
    4. PROCEDURE sendmail (p_receiver       VARCHAR2,
    5. p_sub            VARCHAR2,
    6. p_txt            VARCHAR2,
    7. err_num      OUT NUMBER,
    8. err_msg      OUT VARCHAR2);
    9. END;
    10. /
    11. --body section
    12. CREATE OR REPLACE PACKAGE BODY "SENDMAIL_PKG"
    13. IS
    14. PROCEDURE sendmail (p_receiver       VARCHAR2,
    15. p_sub            VARCHAR2,
    16. p_txt            VARCHAR2,
    17. err_num      OUT NUMBER,
    18. err_msg      OUT VARCHAR2)
    19. IS
    20. /*   p_receiver   =>  receiver
    21. p_sub              =>  mail subject
    22. p_txt                => mail content
    23. */
    24. p_user                         VARCHAR2 (30) := NULL;
    25. p_pass                         VARCHAR2 (30) := NULL;
    26. p_sendor                       VARCHAR2 (40) := ‘[email protected]‘;
    27. p_server                       VARCHAR2 (20)
    28. --             := system_pkg.get_sys_para_value (‘TC_SMTP_IP‘); --‘192.168.7.65‘;
    29. :=‘192.168.7.65‘;
    30. p_port                         NUMBER := 25;
    31. p_need_smtp                    NUMBER := 0;
    32. p_subject                      VARCHAR2 (4000);
    33. l_crlf                         VARCHAR2 (2) := UTL_TCP.crlf;
    34. l_sendoraddress                VARCHAR2 (4000);
    35. l_splite                       VARCHAR2 (10) := ‘++‘;
    36. boundary              CONSTANT VARCHAR2 (256) := ‘-----BYSUK‘;
    37. first_boundary        CONSTANT VARCHAR2 (256) := ‘--‘ || boundary || l_crlf;
    38. last_boundary         CONSTANT VARCHAR2 (256)
    39. := ‘--‘ || boundary || ‘--‘ || l_crlf ;
    40. multipart_mime_type   CONSTANT VARCHAR2 (256)
    41. := ‘multipart/mixed; boundary="‘ || boundary || ‘"‘ ;
    42. TYPE address_list IS TABLE OF VARCHAR2 (100)
    43. INDEX BY BINARY_INTEGER;
    44. my_address_list                address_list;
    45. ---------------------------------------split mail address----------------------------------------------
    46. PROCEDURE p_splite_str (p_str VARCHAR2, p_splite_flag INT DEFAULT 1)
    47. IS
    48. l_addr   VARCHAR2 (254) := ‘‘;
    49. l_len    INT;
    50. l_str    VARCHAR2 (4000);
    51. j        INT := 0;
    52. BEGIN
    53. /*Handle recieve mail address, such like blank, semicolon*/
    54. l_str :=
    55. TRIM (RTRIM (REPLACE (REPLACE (p_str, ‘;‘, ‘,‘), ‘ ‘, ‘‘), ‘,‘));
    56. l_len := LENGTH (l_str);
    57. FOR i IN 1 .. l_len
    58. LOOP
    59. IF SUBSTR (l_str, i, 1) <> ‘,‘
    60. THEN
    61. l_addr := l_addr || SUBSTR (l_str, i, 1);
    62. ELSE
    63. j := j + 1;
    64. IF p_splite_flag = 1
    65. THEN
    66. --Add  symbol  ‘<>‘  for each mail address. else could not send to many reciever
    67. l_addr := ‘<‘ || l_addr || ‘>‘;
    68. my_address_list (j) := l_addr;
    69. END IF;
    70. l_addr := ‘‘;
    71. END IF;
    72. IF i = l_len
    73. THEN
    74. j := j + 1;
    75. IF p_splite_flag = 1
    76. THEN
    77. l_addr := ‘<‘ || l_addr || ‘>‘;
    78. my_address_list (j) := l_addr;
    79. END IF;
    80. END IF;
    81. END LOOP;
    82. END;
    83. -----------------------------------write mail header and mail content----------------------------------
    84. PROCEDURE write_data (p_conn     IN OUT NOCOPY UTL_SMTP.connection,
    85. p_name     IN            VARCHAR2,
    86. p_value    IN            VARCHAR2,
    87. p_splite                 VARCHAR2 DEFAULT ‘:‘,
    88. p_crlf                   VARCHAR2 DEFAULT l_crlf)
    89. IS
    90. BEGIN
    91. /* utl_raw.cast_to_raw  to handle chinese code*/
    92. UTL_SMTP.write_raw_data (
    93. p_conn,
    94. UTL_RAW.cast_to_raw (
    95. CONVERT (p_name || p_splite || p_value || p_crlf,
    96. ‘ZHS16CGB231280‘)));
    97. END;
    98. ----------------------------------------write mime mail tail-----------------------------------------------------
    99. PROCEDURE end_boundary (conn   IN OUT NOCOPY UTL_SMTP.connection,
    100. LAST   IN            BOOLEAN DEFAULT FALSE)
    101. IS
    102. BEGIN
    103. UTL_SMTP.write_data (conn, UTL_TCP.crlf);
    104. IF (LAST)
    105. THEN
    106. UTL_SMTP.write_data (conn, last_boundary);
    107. END IF;
    108. END;
    109. ---------------------------------------------send mail procedure--------------------------------------------
    110. PROCEDURE p_email (p_sendoraddress2      VARCHAR2,      --sender address
    111. p_receiveraddress2    VARCHAR2)    --reciever address
    112. IS
    113. l_conn   UTL_SMTP.connection;                   --create a connection
    114. BEGIN
    115. /*Initial mail server*/
    116. l_conn := UTL_SMTP.open_connection (p_server, p_port);
    117. UTL_SMTP.helo (l_conn, p_server);
    118. /* smtp authentication*/
    119. IF p_need_smtp = 1
    120. THEN
    121. UTL_SMTP.command (l_conn, ‘AUTH LOGIN‘, ‘‘);
    122. UTL_SMTP.command (
    123. l_conn,
    124. UTL_RAW.cast_to_varchar2 (
    125. UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw (p_user))));
    126. UTL_SMTP.command (
    127. l_conn,
    128. UTL_RAW.cast_to_varchar2 (
    129. UTL_ENCODE.base64_encode (UTL_RAW.cast_to_raw (p_pass))));
    130. END IF;
    131. /*configure sender and reciever mail address*/
    132. UTL_SMTP.mail (l_conn, p_sendoraddress2);
    133. UTL_SMTP.rcpt (l_conn, p_receiveraddress2);
    134. /*configure mail header*/
    135. UTL_SMTP.open_data (l_conn);
    136. /*configure date*/
    137. --write_data(l_conn, ‘Date‘, to_char(sysdate-1/3, ‘dd Mon yy hh24:mi:ss‘));
    138. /*configure sender*/
    139. write_data (l_conn, ‘From‘, p_sendor);
    140. /*configure reciever*/
    141. write_data (l_conn, ‘To‘, p_receiver);
    142. /*add mail subject*/
    143. SELECT REPLACE (
    144. ‘=?GB2312?B?‘
    145. || UTL_RAW.cast_to_varchar2 (
    146. UTL_ENCODE.base64_encode (RAWTOHEX (p_sub)))
    147. || ‘?=‘,
    148. UTL_TCP.crlf,
    149. ‘‘)
    150. INTO p_subject
    151. FROM DUAL;
    152. write_data (l_conn, ‘Subject‘, p_subject);
    153. write_data (l_conn, ‘Content-Type‘, multipart_mime_type);
    154. UTL_SMTP.write_data (l_conn, UTL_TCP.crlf);
    155. UTL_SMTP.write_data (l_conn, first_boundary);
    156. write_data (l_conn, ‘Content-Type‘, ‘text/html‘);
    157. UTL_SMTP.write_data (l_conn, UTL_TCP.crlf);
    158. write_data (
    159. l_conn,
    160. ‘‘,
    161. REPLACE (REPLACE (p_txt, l_splite, CHR (10)), CHR (10), l_crlf),
    162. ‘‘,
    163. ‘‘);
    164. end_boundary (l_conn);
    165. /*close write data*/
    166. UTL_SMTP.close_data (l_conn);
    167. /*close connection*/
    168. UTL_SMTP.quit (l_conn);
    169. END;
    170. ---------------------------------------------main procedure -----------------------------------------------------
    171. BEGIN
    172. err_num := 0;
    173. l_sendoraddress := ‘<‘ || p_sendor || ‘>‘;
    174. p_splite_str (p_receiver);                         --handle mail address
    175. FOR k IN 1 .. my_address_list.COUNT
    176. LOOP
    177. p_email (l_sendoraddress, my_address_list (k));
    178. END LOOP;
    179. END;
    180. END;
    181. /
    182. 转:http://blog.csdn.net/leshami/article/details/18616901
时间: 2024-10-09 05:38:50

PL/SQL 下邮件发送程序的相关文章

PL/SQL中如何让程序每隔几秒插入一条数据

在编写ORACLE PL/SQL中,如果需要程序执行中暂停几秒钟再继续执行,可以通过oracle内置的dbms_lock.sleep来实现,不过dbms_lock包需要用户自己安装. [[email protected] ~]# su - oracle [[email protected] ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Mon May 25 16:36:12 2015 Copyright (c

python3实现邮件发送程序

刚开始的想法很简单,由于有上千封的邮件需要发出去,并且需要一条一条发送,不能转发或群发,每条邮件要署对方的姓名,并加上几个相同的符件,考虑到手工操作繁琐无趣,所以想到用程序实现,python好像非常胜任.邮件人在excel表中,因此,首先考虑的就是读取excel表,最好的办法就是直接修改excel表每条记录,表示此条记录已经发送成功,可惜我用的是xlrd,只能读,不能写,只好再调用ini的方法,这样就完成了读取数据,根据ini数据决定是否发送邮件,修改ini中数据状态.嗯,大致情形就是这样. 然

简单的邮件发送程序

using System;using System.Net;using System.Net.Mail;using System.Text; namespace SendMailDemo{ class Program { static void Main(string[] args) { SmtpClient client = new SmtpClient("smtp.goodix.com"); MailAddress from = new MailAddress("[ema

ASA下邮件发送经常失败

更换ASA5525后最近发现,经常有个别人发个别邮件失败,outlook上出现代码0x800CCC0F,查看网络并没有问题,通过抓包发现此邮件通过ASA5525时被丢包,在ASA上查看日志发现日志上的丢包代码为:Aug 03 2018 09:36:16: %ASA-6-305011: Built dynamic TCP translation from inside:10.10.200.148/52065 to outside:118.242.17.18/52065Aug 03 2018 09:

Oracle中PL/SQL简介、基本语法以及数据类型

Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控制为一体的强大语言,PL/SQL不但支持更多的数据类型,拥有自身的变量申明,赋值语句,而且还有条件,循环等流程控制语句.过程控制结构与SQL数据处理能力无缝的结合形成了强大的编程语言,可以创建过程和函数以及程序包. PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性的发送给服务器,由服

PL/SQL数据库开发那点事

PL/SQL数据库开发那点事-->编程,存储程序 在SQL*plus 中编写PL/SQL程序,并在SQL*plus 中执行它, PL/SQL块的代码就存放在SQL*plus的缓冲区中.如果在SQL*plus 中执行了其他的SQL语句或PL/SQL块,缓冲区中就会存放新的代码,原来的PL/SQL块就会被从缓冲区中清除出去.这种没有名称只是临时存放在缓冲区中的PL/SQL块叫做匿名块.匿名块就是没有名字的PL/SQL块,它仅存放在缓冲区中,只能在当前SQL*plus环境中执行.如果希望PL/SQL块

PL/SQL数据开发那点事

PL/SQL开发那点事----->PL/SQL开发过程中异常处理 用户编写的PL/SQL块在执行过程中不可避免地要发生一些错误. 这里涉及的错误并不是由于程序的语法错误引起的,而是因为处理的数据超出了处理的范围而引发的错误.如果给这样的错误起一个名字,这就是异常.当PL/SQL块在执行过程中检测到一个错误时,就会抛出相应的异常.在块中应当处理这样的异常,否则会引起应用程序运行停止. 异常处理程序 异常一般是在PL/SQL程序执行错误时由数据库服务器抛出,也可以在PL/SQL块中由程序员在一定的条

C#邮件发送(最坑爹的邮箱-QQ邮箱)---转发(SmallFlyElephant)

C#邮件发送(最坑爹的邮箱-QQ邮箱) 最近工作挺清闲的,有空的时候陪妹子出去玩玩,自己看看小说,看看电影,日子过的挺欢乐的,这个星期幡然悔悟,代码才是我的最爱,做点小东西,就写个邮件发送程序.说的邮件发送相信工作过基本上都会用到过,用户注册完之后发个验证邮件过去验证一下,改密码的时候邮箱验证一下,用户对网站体验如何发个邮件调查一下,网站最近最热的内容发个邮件推送一下,好吧,有点啰嗦.正文开始吧: SMTP定义 简单邮件传输协议 (Simple Mail Transfer Protocol, S

十九、oracle pl/sql简介

一.pl/sql 是什么pl/sql(procedural language/sql)是oracle在标准的sql语言上的扩展.pl/sql不仅允许嵌入sql语言,还可以定义变量和常量,允许使用条件语句和循环语句,允许使用例外处理各种错误,这样使得它的功能变得更加强大. 二.为什么要学pl/sql1.提高应用程序的运行性能2.模块化的设计思想(分页的过程,订单的过程,转账的过程..)3.减少网络传输量4.提高安全性(sql会包括表名,有时还可能有密码,传输的时候会泄露.PL/SQL就不会) 三.