Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件
太多的在线电子邮件存储过程。我不转发,弄个作为一个简单的例子演示。
create or replace procedure Send_mail(mail_body varchar2) is
smtp_conn utl_smtp.connection;
user_name varchar2(20) := utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('username@email.com')));
user_paswd varchar2(20) := utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('password')));
lv_mail_header varchar2(200):='From:username@email.com'||utl_tcp.CRLF||
'To:sanoul@email.com'||utl_tcp.CRLF||
'Subject:Oracle数据库'||utl_tcp.CRLF;
lv_mail_content varchar2(2000);
begin
lv_mail_content := utl_tcp.CRLF||mail_body; smtp_conn := utl_smtp.open_connection('smtp.email.com',25);
utl_smtp.helo(smtp_conn,'smtp.email.com');
utl_smtp.command(smtp_conn,'AUTH LOGIN');
utl_smtp.command(smtp_conn,user_name); --邮件用户名
utl_smtp.command(smtp_conn,user_paswd); --邮件密码
utl_smtp.mail(smtp_conn,'<username@email.com>'); --发件人邮箱
utl_smtp.rcpt(smtp_conn,'<sanoul@email.com>'); --收件人邮箱 utl_smtp.open_data(smtp_conn); utl_smtp.write_raw_data(smtp_conn,utl_raw.cast_to_raw(lv_mail_header));
utl_smtp.write_raw_data(smtp_conn,utl_raw.cast_to_raw(lv_mail_content));
--顺便说一句utl_raw.cast_to_raw最大长度是16383,假设你的邮件正文超大,请循环插入正文write_raw_data
--否则肯定会得到 ORA-06502: PL/SQL: 数字或值错误 utl_smtp.close_data(smtp_conn);
utl_smtp.quit(smtp_conn);
exception
when others then
utl_smtp.quit(smtp_conn);
end Send_mail;
/ --储存过程已创建
第二步直接測试函数;
begin
send_mail('測试内容');
end;
/ ORA-29278: SMTP 暂时性错误: 421 Service not available
ORA-06512: 在 "SYS.UTL_SMTP", line 21
ORA-06512: 在 "SYS.UTL_SMTP", line 97
ORA-06512: 在 "SYS.UTL_SMTP", line 139
ORA-06512: 在 "SYS.UTL_MAIL", line 405
ORA-06512: 在 "SYS.UTL_MAIL", line 594
ORA-06512: 在 line 2
话说我第一次看到这个错误很震惊,由于整个邮件发送的存储过程是先用PL/SQL直接測试代码后,再封装到存储过程中的。后来经过搜索才知道为了更仔细地控制网络权限,Oracle 11g中针对UTL_TCP。 UTL_SMTP, UTL_MAIL, UTL_HTTP和 UTL_INADDR的訪问设置了单独的权限訪问控制方式(ACL).
OK,第三步。设置ACL;
--ACL第一步。创建
BEGIN
dbms_network_acl_admin.create_acl(acl => 'httprequestpermission.xml', --文件名称,能够随意取名
DESCRIPTION => 'Normal Access',
principal => 'CONNECT', --角色
is_grant => TRUE,
PRIVILEGE => 'connect',
start_date => NULL,
end_date => NULL);
END;
/ commit; --必需要提交;
然后检查是否创建了该 ACL控制文件;
SQL> SELECT any_path FROM resource_view WHERE any_path like '/sys/acls/%.xml';
假设列表里出现刚才创建的文件httprequestpermission.xml,请继续ACL第二步
--ACL第二步,授权用户(演示样例用scott作为測试)
begin
dbms_network_acl_admin.add_privilege(acl => 'httprequestpermission.xml',
principal => 'SCOTT', --用户。请依照实际变更
is_grant => TRUE,
privilege => 'connect',
start_date => null,
end_date => null);
end;
/
--ACL第三步。加入主机或域名
begin
dbms_network_acl_admin.assign_acl(acl => 'httprequestpermission.xml',
host => 'www.baidu.com', --http网页地址
lower_port => 80, --http端口
upper_port => NULL);
end;
/ commit; begin
dbms_network_acl_admin.assign_acl(acl => 'httprequestpermission.xml',
host => 'smtp.sina.com.cn', --smtpserver地址
lower_port => 25, --smtp端口
upper_port => NULL);
end;
/
commit;
最后就是再次測试存储过程
SQL> begin
2 send_mail(mail_body => 'afafagaga');
3 end;
4 / PL/SQL procedure successfully completed
没有不论什么错误,邮件正确收到;(本文測试环境:Oracle 11.2.0.0。OS:Windows 2008 Server)
(作者測试过程中曾遇到过
ORA-24247: 网络訪问被訪问控制列表 (ACL) 拒绝;
ORA-29278: SMTP 暂时性错误: 421 Service not available。
ORA-44416: ACL 无效: 无法解析的主用户 'AGENT'
三大错误,为了解决根据上述方法,这些问题可以)
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件的更多相关文章
- 安装oracle 11g环境变量ORACLE_HOME的一个问题 转
http://blog.itpub.net/26129555/viewspace-1243467/报错内容: OUI-10137:An Oracle Home with name ORACLE_HOM ...
- 使用oracle 的 PL/Sql 定时执行一个存储过程
CSDN日报20170322--<关于软件研发的一些体会总结> 同步博客至 CSDN ,让更多开发者看到你的文章 看微博技术大咖解析互联网应用架构实战 使用oracle 的 PL/Sql ...
- MySql创建一个存储过程
MySQL 存储过程是从 MySQL 5.0 新功能.存储过程的长处有一箩筐.只是最基本的还是运行效率和SQL 代码封装. 特别是 SQL 代码封装功能,假设没有存储过程,在外部程序訪问数据库时(比如 ...
- vue.js开发环境搭建以及创建一个vue实例
Vue.js 是一套构建用户界面的渐进式框架.Vue 只关注视图层, 采用自底向上增量开发的设计.Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. 在使用 vue.js ...
- 1 创建一个存储过程,以及对存储过程的调用 MySQL
1 首先创建一张tb1表 sql语句如下 CREATE TABLE `tb1` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) DE ...
- Ionic-wechat项目边开发边学(一):环境搭建和创建一个项目
之前学AngularJS,教程过了一遍觉得很简单,但真正写几个Demo就错误百出,一个小小的功能要折腾很久.所以这次学Ionic,准备以开发一个项目为切入点去学,那么问题来了,开发什么项目呢? 纠结了 ...
- linux 成功安装oracle后,为其创建一个登录账户
成功安装oracle后,创建一个登录账户 1.切换到oracle用户下 su -l oracle 2.使用sysdba账户登录: sqlplus / as sysdba 3.创建用户 语法:CREAT ...
- 020、MySQL创建一个存储过程,显示存储过程,调用存储过程,删除存储过程
一.我们创建一个MySQL储存过程,在SQL代码区写入以下内容,并执行就可以了 #编写一个存储过程 CREATE PROCEDURE ShowDate ( ) BEGIN #输出当前时间 SELECT ...
- 第一安装oracle数据库后,需要创建一个用户,给用户解锁并赋予权限
1.第一次安装oracle数据库应该做的事情. 注: 1.安装oracle后需要创建用户,连接数据库,(注意数据库名,还有好像后面的 ":"也有影响) 2.解锁用户, 3.授予新登 ...
随机推荐
- sql pivot、unpivot和partition by用法
原文:sql pivot.unpivot和partition by用法 演示脚本 from sys.sysobjects where name = 'Student' AND type = 'U') ...
- C语言习题 链表建立,插入,删除,输出
Problem B: C语言习题 链表建立,插入,删除,输出 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 222 Solved: 92 [Subm ...
- C#托付和事件
C#托付.我看了非常长时间的资料和帖子, 曾经对托付的理解就是托付事实上就是将一个方法作为參数传递给第一个方法. 如今对托付的认识则变了一些的,托付能够实现: 1.在两个不能直接调用的方法之间做为桥梁 ...
- 七牛对用户使用webp图片格式的使用建议
Qiniu 七牛问题解答 Chrome浏览器是可打开WebP格式的.可是并非全部的浏览器都支持webp格式,比如360.ie等浏览器是不支持的. WebP格式,谷歌(google)开发的一种旨在加快图 ...
- asp.net弹出层实例
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...
- Java中finally你知多少
首先来问大家一个问题:finally 语句块一定会执行吗? 很多人都认为 finally 语句块是肯定要执行的,其中也包括一些很有经验的 Java 程序员.可惜并不像大多人所认为的那样,对于这个问题, ...
- 基于最简单的FFmpeg采样读取内存读写:内存玩家
===================================================== 基于最简单的FFmpeg样品系列读写内存列表: 最简单的基于FFmpeg的内存读写的样例:内 ...
- HTML5 transform三维立方体(随着旋转的效果)
为了得到更好的把握transform精华.因此,我们决定完成三维立方体模型,可以实现360无死三维旋转作用. 但旋转更难推断每侧视图的序列.然而,完美的解决方案,我希望有人能回答. 源代码直接贡献的朋 ...
- cocos2d-x使用CCClippingNode实现跑马灯
直接在代码,这是一个很好的包layer,可以直接调用 //原来白白 bool TestLayer::init() { CCSize size = CCDirector::sharedDirector ...
- Rational Rose 2007使用小结
1.Rose怎样隐藏类的属性和操作? 右击类,选Options->Suppress Attributes/Suppress Operations 2.Rose怎样表示类的约束? 在工具箱中选AB ...