热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

使用JMail组件代替SqlMail发送Email_MySQL

说两句:在某人最困难的时候,写下此文,寄给某某报想骗点稿费,结果石沉大海,若干年后,翻腾硬盘翻出来了。呵呵,或许可以对希望在SqlServer中发送邮件的网友有所帮助。54powerman^_^SqlMail技术给每一位数据库开发人员和DBA(数据库管理员)带来了极大的方便,利
说两句:在某人最困难的时候,写下此文,寄给某某报想骗点稿费,结果石沉大海,若干年后,翻腾硬盘翻出来了。呵呵,或许可以对希望在SqlServer中发送邮件的网友有所帮助。

54powerman^_^

Sql Mail技术给每一位数据库开发人员和DBA(数据库管理员)带来了极大的方便,利用该技术,Sql Server数据库代理程序可以在系统出现异常的时候自动发送Email通知管理员,开发人可以利用它让数据库自动定期的修改用户密码,然后发送Email通知用户……等等这些应用,都不同程度上把我们从繁杂的工作中解放出来。但是,Sql Mail的配置是比较复杂的,相信90%以上的人在配置Sql Mail的时候都遇到过各种各样的麻烦,至少有70%的人放弃了Sql Mail而选择其他方案来解决这个问题。笔者是一名Web开发人员,亲身经历了这一切,并找到了一个更好的替代方法。不敢独享,写出来以飨读者。
Sql Mail配置有几种方式,按照支持软件可划分为基于Exchange、Outlook2000(以上)和第三方软件的配置方案,三种方式各有利弊,主要表现在以下几个方面:

使用Outlook客户端配合Sql Server实现Sql Mail
此方案软件要求较低,只需要在Sql Server所在服务器上安装Outlook2000以上版本客户端即可。它要求在Sql Mail使用期间,OutLook客户端必须打开,否则,只能到下次打开时,邮件才能发送出去。另外,如果服务器为远程服务器,用微软官方的远程桌面无法完成配置,可替代的方案是DBA亲自去机房直接操作,或者安装PcAnywhere10替代远程桌面进行操作。

使用Exchange要求较高
Microsoft推荐使用Exchange作为Sql Mail的最佳拍档,MSDN的资料提出:“由于 POP3/SMTP 协议存在的局限性和登录问题,Microsoft 建议您使用 Exchange Server 来实现可靠性”。但是Exchange并不是专门做这个来使用的,可以说是屈才了,而且Exchange要求服务器配置域管理器,相信这个东东对大多数数据库服务器来说用处不大,只不过是浪费资源罢了。如果我们要在多台服务器上配置Sql Mail那么就需要在每一台服务器上配置域管理器,或者所有的服务器都配置到一个域内,但是对于服务器比较分散的系统来说这样是不现实的。

使用第三方系统支持
微软MSDN称:“如果您使用的是第三方邮件服务器,则必须将邮件服务器配置为 POP3 服务器。如果这些邮件服务器使用的本地邮件服务可能是由第三方邮件客户端安装的,Microsoft 将不支持连接到这些服务器”。这就意味着你还要使用Windows平台的邮件服务,使用ASP编写网站的朋友一定都知道,Cdonts.dll组件实在是……。
面对这些问题,笔者就变成了我刚才说的那70%了,虽然爬网无数,读文字数万把Sql Mail配置好了,但是我仍然绝对放弃,因为我不想在做第2台、第3台……的时候重蹈覆辙。替代的方案就是Jmail组件+OLE自动化对象,以上的问题迎刃而解。

预备知识
1.OLE自动化函数
OLE自动化使应用程序能够对另一个应用程序中实现的对象进行操作,或者将对象公开以便可以对其进行操作。自动化客户端是可对属于另一个应用程序的公开对象进行操作的应用程序,本文值得是Sql Server。公开对象的应用程序称为自动化服务器,又成为自动化组件,本文中即Jmail组件咯。客户端通过访问应用程序对象的属性和函数对这些对象进行操作。
在Sql Server使用Ole组件的途径是几个系统扩展存储过程sp_OACreate、sp_OADestroy、sp_OAGetErrorInfo、sp_OAMethod、sp_OASetProperty和sp_OAGetProperty,再次简单地介绍一下使用方法,详细资料参考Sql Server联机丛书。
OLE自动化对象的使用方法:
(1)调用 sp_OACreate 创建对象。
格式:sp_OACreate clsid,objecttoken OUTPUT [ , context ]
参数:clsid——是要创建的 OLE 对象的程序标识符 (ProgID)。此字符串描述该 OLE 对象的类,其形式,如 'OLEComponent.Object',OLEComponent 是 OLE 自动化服务器的组件名称,Object 是 OLE 对象名,本文中使用的“JMail.Message”;
Objecttoken——是返回的对象标志,并且必须是数据类型为 int 的局部变量。用于标识所创建的 OLE 对象,并将在调用其它 OLE 自动化存储过程时使用。本文中就是通过它来调用JMail.Message组件的属性和方法的。
Context——指定新创建的 OLE 对象要在其中运行的执行上下文。本文不使用该参数,故不赘述。以下与此一致,所有方法属性的其他用法请参阅Sql Server联机文档。
(2)使用该对象。
(a)调用 sp_OAGetProperty 获取属性值。
格式:_OAGetProperty objecttoken,propertyname [, propertyvalue OUTPUT]
参数:(前面出现过的参数,以下均省略。)
Propertyname——对象的属性名称;
Propertyvalue——返回的对象的属性值,该参数带OUTPUT属性,执行该操作后,你就可以从propertyvalue中得到属性的值了。
(b)调用 sp_OASetProperty 将属性设为新值。
格式:sp_OASetProperty objecttoken, propertyname, propertyvalue
(c)调用 sp_OAMethod 以调用某个方法。
格式:sp_OAMethod objecttoken, methodname [, returnvalue OUTPUT] [ , [ parametername = ] parametervalue [...n]]
参数:Returnvalue——调用方法的返回值,如果没有返回值,此参数设置为NULL;
Parametername——方法定义中的参数名称,也就是形参;
Parametervalue——参数值;
……n——表示,可以带很多参数,个数由方法定义限制;
(d)调用 sp_OAGetErrorInfo 获取最新的错误信息。
格式:sp_OAGetErrorInfo [objecttoken ] [, source OUTPUT] [, description OUTPUT]
参数:Source——错误源;
Description——错误描述;
(3)调用 sp_OADestroy 释放对象。
格式:sp_OADestroy objecttoken

2.xp_cmdshell扩展存储过程
该扩展存储过程在master数据库中,它的全路径是master..xp_cmdshell(注意,中间是2个点),它的功能是:以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。
格式:xp_cmdshell {'command_string'} [, no_output]
参数:'command_string'——是在操作系统命令行解释器上执行的命令字符串。
no_output——是可选参数,表示执行给定的 command_string,但不向客户端返回任何输出。本文应用中不使用该参数。

操作方法
(1)软件准备
请先到http://www.dimac.net/或者国内提供组件下载的网站下载最新版的JMail组件,如果你得到的是安装版,执行weJMailx.exe即可,系统的配置安装程序会自动完成。如果只有一个JMail.dll文件,请按照下面的步骤安装:
(a)新建文本文件,输入如下命令:
regsvr32 JMail.dll
net start w3svc
另存为Install.Bat(注意,千万不要保存成Install.Bat.Txt啊)
(b)此文件连同Jmail.dll一起拷贝到Sql Server数据库服务器的System32目录下,并执行双击Install.Bat即可。
(2)准备好了吗?跟我来吧
(a)运行Sql Server查询分析器,并以sa身份登录到Sql Server数据库;
(b)如果你的存储过程要添加到YourDefaultCatalog数据库,请在空白Sql窗口输入如下指令,否则请相应修改数据库名。
Use YourDefaultCatalog
按F5或者运行按钮运行该指令;
(c)创建基本发送存储过程
复制如下代码到Sql Server命令窗口,并运行。下面的代码中有相应的注释,文中不多做解释,如有疑问请查看前面的“预备知识”或者查询Sql Server帮助文件,当然也可以和作者联系。

Create Procedure dbo.sp_jmail_send
@sender varchar(100),
@sendername varchar(100)='',
@serveraddress varchar(255)='SMTP服务器地址',
@MailServerUserName varchar(255)=null,
@MailServerPassword varchar(255)=null,
@recipient varchar(255),
@recipientBCC varchar(200)=null,
@recipientBCCName varchar(200)=null,
@recipientCC varchar(200)=null,
@recipientCCName varchar(100)=null,
@attachment varchar(100) =null,
@subject varchar(255),
@mailbody text
As
/*
该存储过程使用办公自动化脚本调用Dimac w3 JMail AxtiveX组件来代替Sql Mail发送邮件
该方法支持“服务器端身份验证”
*/
--声明w3 JMail使用的常规变量及错误信息变量
Declare @object int,@hr int,@rc int,@output varchar(400),@description varchar (400),@source varchar(400)

--创建JMail.Message对象

Exec @hr = sp_OACreate 'jmail.message', @object OUTPUT

--设置邮件编码
Exec @hr = sp_OASetProperty @object, 'Charset', 'gb2312'

--身份验证
If Not @MailServerUserName is null
Exec @hr = sp_OASetProperty @object, 'MailServerUserName',@MailServerUserName
If Not @MailServerPassword is null
Exec @hr = sp_OASetProperty @object, 'MailServerPassword',@MailServerPassword

--设置邮件基本参数
Exec @hr = sp_OASetProperty @object, 'From', @sender
Exec @hr = sp_OAMethod @object, 'AddRecipient', NULL , @recipient
Exec @hr = sp_OASetProperty @object, 'Subject', @subject
Exec @hr = sp_OASetProperty @object, 'Body', @mailbody

--设置其它参数
if not @attachment is null
exec @hr = sp_OAMethod @object, 'Addattachment', NULL , @attachment,'false'
print @attachment
If (Not @recipientBCC is null) And (Not @recipientBCCName is null)
Exec @hr = sp_OAMethod @object, 'AddRecipientBCC', NULL , @recipientBCC,@recipientBCCName
Else If Not @recipientBCC is null
Exec @hr = sp_OAMethod @object, 'AddRecipientBCC', NULL , @recipientBCC

If (Not @recipientCC is null) And (Not @recipientCCName is null)
Exec @hr = sp_OAMethod @object, 'AddRecipientCC', NULL , @recipientCC,@recipientCCName
Else If Not @recipientCC is null
Exec @hr = sp_OAMethod @object, 'AddRecipientCC', NULL , @recipientCC

If Not @sendername is null
Exec @hr = sp_OASetProperty @object, 'FromName', @sendername

--调用Send方法发送邮件
Exec @hr = sp_OAMethod @object, 'Send', null,@serveraddress

--捕获JMail.Message异常
Exec @hr = sp_OAGetErrorInfo @object, @source OUTPUT, @description OUTPUT

if (@hr = 0)
Begin
Set @output='错误源: ' @source
Print @output
Select @output = '错误描述: ' @description
Print @output
End
Else
Begin
Print '获取错误信息失败!'
Return
End

--释放JMail.Message对象
Exec @hr = sp_OADestroy @object

(d)简化存储过程操作,以适合我们平时的使用习惯
上面的存储过程基本可以完成邮件发送操作,但是非常冗长,而且不符合我们的习惯,比如它不支持多个发送给接收者、不支持将Sql指令运行结果以附件形式发送(这是Sql Mail的功能,我们也可以做到)等,所以我们要再写一个存储过程来调用它,以简化操作,并扩展功能。

Create Procedure SendMail
@Sender varChar(50)=null,
@strRecipients varChar(200),
@strSubject varChar(200),
@strMessage varChar(2000),
@sql varChar(50)=null)
As

Declare @SplitStr varchar(1) --定义邮件地址分割符变量
Declare @strTemp varchar(200) --定义多个收件人字符串临时变量
Declare @email varchar(50) --用分割符分割后的单个收件人字符串变量

Declare @SenderAddress varChar(50)
Declare @Attach varChar(200)

Declare @DefaultSender varChar(50)
Declare @MailServer varChar(50)
Declare @User varChar(50)
Declare @Pass varChar(50)
Declare @SenderName varChar(50)
Declare @AttachDir varChar(100)

--初始化缺省变量
Set @DefaultSender='缺省发送地址'
Set @MailServer='邮件服务器地址'
Set @User='SMTP服务器验证用户地址'
Set @Pass='SMTP服务器验证地址'
Set @SenderName='缺省发件人名称'
Set @AttachDir='E:\LOG\WebData\Jmail\' Replace(Replace(Replace(Convert(varChar(19),GetDate(),120),'-',''),' ',''),':','') '.txt'

--将Email地址分割符统一为分号
set @SplitStr=';'
Set @strTemp=@strRecipients @SplitStr 'end'
Set @strTemp=Replace(@strTemp,',',';')

--判断是否有sql语句
If (@Sql is Null) Or (len(@Sql)=0)
Set @AttachDir=Null
Else
Begin
Declare @CmdStr varChar(200)
Set @CmdStr='bcp "' @Sql '" queryout ' @AttachDir ' -c'
EXEC master..xp_cmdshell @CmdStr
End

while CharIndex(@SplitStr,@strTemp,1)<>0
Begin
Set @email=left(@strTemp,CharIndex(@SplitStr,@strTemp,1)-1)
Set @strTemp=right(@strTemp,len(@strTemp)-len(@email)-1)
If (@Sender Is Null) Or (Len(@Sender)=0)
Set @SenderAddress=@DefaultSender
Else
Set @SenderAddress=@Sender
Print @email
--调用sp_jmail_send发送邮件
EXEC sp_jmail_send @sender=@SenderAddress,@sendername=@SenderName,
@serveraddress=@MailServer,@MailServerUserName=@User,@MailServerPassword=@Pass,
@recipient=@email,@subject=@strSubject,@mailbody=@strMessage,@attachment=@AttachDir
End
此存储过程只扩展了Sql查询结果附件发送,如果你要发送标准附件,请直接使用sp_jmail_send存储过程或者自行扩展功能。

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文详细介绍了解决全栈跨域问题的方法及步骤,包括添加权限、设置Access-Control-Allow-Origin、白名单等。通过这些操作,可以实现在不同服务器上的数据访问,并解决后台报错问题。同时,还提供了解决second页面访问数据的方法。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
author-avatar
紫青郝_385
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有