专业的信息化与通信融合产品选型平台及垂直门户
注册 登陆 设为首页 加入收藏
首页 企业新闻 招标信息 行业应用 厂商专区 活动 商城 中标信息

资讯
中心

新闻中心 人物观点
厂商专区 市场分析
行业
应用
政府机构 能源产业 金融机构
教育科研 医疗卫生 交通运输
应用
分类
统一协作 呼叫客服 IP语音 视频会议 智能管理 数据库
数字监控 信息安全 IP储存 移动应用 云计算 物联网

TOP

用Oracle数据库实现实时通信
2012-07-12 13:29:43 来源:中国IT实验室 作者:佚名【
关键词:用Oracle 数据库
 
由于Oracle不提供用于实时输出消息的工具, Oracle数据库开发者总是要面临实时监视他们的储备过程执行的挑战。他们必须使用dbms_output.put_line调用,这个调用直到过程完成才返回结果。

  由于Oracle不提供用于实时输出消息的工具, Oracle数据库开发者总是要面临实时监视他们的储备过程执行的挑战。他们必须使用dbms_output.put_line调用,这个调用直到过程完成才返回结果。

  在本文中,我想演示如何从Oracle8i数据库直接发送电子邮件,作为一种实时通信解决方案。这样我们要监视存储过程就不再需要等待它们完成了,这样的方法还为开发者提供了其他的一些好处:

  1、可以在几分钟内调试一些很长的批处理过程,而不需要等几个小时;

  2、计算用于指定代码块所需的执行时间。

  这就需要解决一个问题,我们如何从运行的存储过程中输出消息以便我们可以即时检查它们,即使我们不在办公场所?我们的做法是把所有必需的过程与函数包装在自定义的包中,然后使用Oracle8i UTL_SMTP包直接地从Oracle数据库中发送电子邮件。下面我将详细讲解一些这个过程。

  Oracle的UTL_SMTP包

  在Oracle8i中引入了UTL_SMTP包(SMTP代表Simple Mail Transfer Protocol简单邮件传送协议,使用TCP端口25在客户机和服务器之间建立通信联络),使开发者能够从数据库发送电子邮件。

  只有安装带有Java虚拟机(JVM)的8i或更高的版本才能使用UTL_SMTP. 此外还必须把plsql.jar载入数据库中。否则,当调用UTL_SMTP API来发送电子邮件的时候我们将得到下面的异常:ORA - 29540 : class oracle/plsql/net/TCPConnection does not exist.

  默认的$ORACLE_HOME/javavm/install/initjvm.sql脚本(安装了JVM)不运行把plsql.jar载入数据库的initplsj.sql脚本。系统用户或者内部用户可以手工运行$ORACLE_HOME/RDBMS/ADMIN/initplsj.sql脚本以解决这个问题。 如果你没有可用的脚本,你要么可以从Oracle支持那里得到它,要么可以简单地直接使用loadjava载入实用程序plsql.jar:

  loadjava -user sys/password@database -resolve plsql/jlib/plsql.jar

  UTL_SMTP API:

  本文的代码中使用了下列UTL_SMTP包中的API:

  OPEN_CONNECTION():打开到简单邮件传送协议服务器的连接。

  HELO():执行连接之后建立与简单邮件传送协议服务器初始的收发关系功能,它能识别发送到服务器的"信使".

  MAIL():初始化与服务器的邮件交换,但是事实上不发送消息。

  RCPT():识别消息的接受者。为了把一条消息发送到多个接受者,你必须多次调用这个过程。

  DATA():指定电子邮件的内容。

  QUIT():终止一个SMTP会话并且断开与服务器的连接。

  为了利用应用程序编程接口,把下面的调用按照给定的顺序放入程序中:

  调用 OPEN_CONNECTION;

  调用 HELO;

  调用 MAIL;

  调用 RCPT for each recipient;

  格式化电子邮件的内容然后调用MAIL;

  调用 QUIT.

  EmailUtils包规范

  EmailUtils包包括下列API:

  SetSender/GetSender-设置/取得发送者;

  SetRecipient/GetRecipient -设置/取得接受者;

  SetCcrecipient/GetCcrecipient -设置/取得抄件接受者;

  SetMailHost/GetMailHost -设置/取得邮件主机;

  SetSubject/GetSubject -设置/取得主题;

  Send-发送邮件。

  代码1说明了EmailUtils包的规范:

  create or replace package EmailUtils as

  procedure SetSender(pSender in varchar2);

  function GetSender

  return varchar2;

  procedure SetRecipient(pRecipient in varchar2);

  function GetRecipient

  return varchar2;

  procedure SetCcRecipient(pCcRecipient in varchar2);

  function GetCcRecipient

  return varchar2;

  procedure SetMailHost(pMailHost in varchar2);

  function GetMailHost

  return varchar2;

  procedure SetSubject(pSubject in varchar2);

  function GetSubject

  return varchar2;

  procedure Send(pMessage in varchar2);

  procedure Send(pSender in varchar2,

  pRecipient in varchar2,

  pMailHost in varchar2,

  pCcRecipient in varchar2 := null,

  pSubject in varchar2 := null,

  pMessage in varchar2 := null);

  end EmailUtils;

  /

  可以看出,Send过程是重载过程:包规范中包括这个过程的两个版本。 一个版本当至少三个强制性参数要规定的时候引用,pSender,pRecipient和pMailHost:

  procedure Send(pSender in varchar2,

  pRecipient in varchar2,

  pMailHost in varchar2,

  pCcRecipient in varchar2 := null,

  pSubject in varchar2 := null,

  pMessage in varchar2 := null);

  另一个版本只有当提供pMessage参数值时执行:

  procedure Send(pMessage in varchar2);

  第二个版本是用作调试的版本。 所有的电子邮件消息共用同样的发送者、接受者、邮件主机、抄送接受者和主题信息,这些都是我在会话的开始的时候设置好的。 下面是一个PL/SQL程序块的例子:

  begin

  EmailUtils.SetSender;

  EmailUtils.SetRecipient;

  EmailUtils.SetCcRecipient;

  EmailUtils.SetMailHost('MyServer.MyCompany.com');

  EmailUtils.SetSubject('DeleteClassifications procedure: Run 1');

  end;

  /

  一个实际的电子邮件消息将在每个Send过程调用中被指定。 我们可以把所用的EmailUtils.Send()调用插入到我们调试的代码中,我们以前为了得到同样的调试结果使用的是DBMS_OUTPUT.PUT_LINE()调用。:

  vMessage := 'Point 1.' || utl_tcp.crlf ||

  'Rows processed: ' || to_char(vRows) || utl_tcp.crlf ||

  'Elapsed time: ' || vTime;

  EmailUtils.Send(vMessage);

  vMessage := 'Point 3.' || utl_tcp.crlf ||

  'Rows processed: ' || to_char(vRows) || utl_tcp.crlf ||

  'Elapsed time: ' || vTime;

  EmailUtils.Send(vMessage);

  代码2显示带有重载Send过程的EmailUtils规格。 我们可以看到,Send过程的代码相当简单。UTL_SMTP包不提供用于格式化消息内容的应用编程接口。 而是由用户负责格式化消息。 这就是为什么下列程序块要被包含到每个Send过程中以便格式化电子邮件的头部。

  vMessage := 'Date: ' ||

  to_char(sysdate, 'fmDy, DD Mon YYYY fxHH24:MI:SS') ||

  utl_tcp.crlf ||

  'From: ' || pSender || utl_tcp.crlf ||

  'Subject: ' || pSubject || utl_tcp.crlf ||

  'To: ' || pRecipient || utl_tcp.crlf;

  同时,如果消息长度超过2000字符的话,你可能得到一个错误( ORA - 06502 : PL/SQL : numeric or value error)。 所以为了避免出现这个错误,我们使用下面的程序块,不允许消息超过2000个字符:

  if length(vMessage) > 2000

  then

  vMessage := substr(vMessage, 1, 2000);

  end if;

  如果需要发送带有超过2000字的电子邮件,那么可以使用另三个UTL_SMTP应用程序编程接口,提供比DATA()过程更加精细的控制。 首先, OPEN_DATA()发送数据命令。 然后WRITE_DATA()添加数据到你要发送的字符串中。 你可以调用WRITE_DATA()任意多次,这样你就可以一次写2000个字符以克服字数的限制。 最后, CLOSE_DATA()通过发送一个封装在CRLF中的终止周期结束电子邮件消息。

  实时消息使你的生活更加舒适

  从数据库发送电子邮件就是那么容易。 一旦你试用这个简单的操作,我相信你会发现它很有用,便于你的数据库操作,例如调试、远程的数据库监控和输出数据库数据。

  每个数据库开发者都有在代码中使用大量的DBMS_OUTPUT调用的调试经历。 在开始一个SQL * Plus会话之后,输入SET SERVEROUTPUT ON然后运行这个过程。 放进DBMS_OUTPUT.PUT_LINE调用的消息显示在屏幕上--但是只有在过程完成以后才能显示出来。 这个过程极端地麻烦,尤其在调试长的批处理时通常是要运行整晚。 你可以等待10到12小时仅仅是为了查出错误的代码,然后修改,再去等待下一个10到12个小时? 然而,如果你有访问消息的实时的办法,那么你可以在头5到10分钟内捕捉到问题。

  DBMS_OUTPUT包也有其他的缺点。 例如,它不接受可变的布尔类型以及它有255字符每行的限制(如果你想输出一个长的消息的话,那么你会得到这个异常:ORA - 20000 : ORU - 10028 : line length overflow, limit of 255 bytes per line)。 把它的缺点全部列出这已经超出本文的范围了,但是重要结论就是DBMS_OUTPUT包不许数据库开发者实时的看到消息。

  谈到服务器上的OS文件,你会不会喜欢把选定的数据从服务器中输出到一个Excel电子表格呢? 一个办法就是使用Oracle的UTL_FILE包,它提供了一个标准OS流文档输入/输出的限制级版本。 然而, PL/SQL程序只能访问在初始化文件INIT.ORA的UTL_FILE_DIR参数规定的目录。 这有些麻烦。使用EmailUtils包,你可以简简单单的把数据写入一个电子邮件中,发送给自己,然后收到它的副本粘贴

  这个参数大多数情况下是空的。为了使这个目录可用来进行文件访问,必须请数据库管理者修改初始化文件。 到自己喜欢的文档编辑器中。

      

责任编辑:admin
免责声明:以上内容转载互联网平台或企业单位自行提供,对内容的真实性、准确性和合法性不负责,Voipchina网对此不承担任何法律责任。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部

上一篇数据中心五大趋势 亚洲情况异常火..
下一篇惠普推AMD平台Gen8服务器 针对数..

热门文章

图片主题

最新文章

相关文章

广告位

Copyright@2003-2009 网络通信中国(原VoIP中国) 版权所有
联系方式:503927495@qq.com
  京ICP备05067673号-1 京公网安1101111101259