在Sql Server 中调用Jmail组件发送邮件
预备知识
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——错误描述;
()调用sp_OADestroy 释放对象。
格式:sp_OADestroy objecttoken
2.操作方法
(1)软件准备
请先到/或者国内提供组件下载的网站下载最新版的JMail组件,如果你得到的是安装版,执行weJMailx.exe即可,系统的配置安装程序会自动完成。如果只有一个JMail.dll文件,请按照下面的步骤安装:
(a)新建文本文件,输入如下命令:
regsvr32 /S Jmail.dll
net start w3svc
(b)将文本文件保存为bat批处理文件,以供调用。
或做成vbs脚本也行:(注:regsvr 32 /S, 这里的S让程序静默处理,不显示对话框)
Set WshShell=CreateObject("Wscript.Shell")
WshShell.Run "regsvr32 /S JMail.dll",0
WshShell.Run "net start w3svc",0
(c)此文件连同Jmail.dll一起拷贝到Sql Server数据库服务器的System32目录下,运气时双击即可。
3.Sql Store Procedure的处理
Create Procedure sp_jmail_send
@sender varchar(100),
@sendername varchar(100)='',
@serveraddress varchar(255)='SMTP Server Address',
@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 Store Procedure 来发邮件---
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) --Split symbol
Declare @strTemp varchar(200) --Temp Multi-email address for split
Declare @email varchar(50) --email address
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 Initial value
Set @DefaultSender='Default Sender'
Set @MailServer='Mail Server'
Set @User='SMTP User'
Set @Pass='SMTP Password'
Set @SenderName='Sender Name'
Set @AttachDir='E:/Data/Jmail_Attach/'+Replace(Replace(Replace(Convert(varChar(19),GetDate(),120),'-',''),' ',''),':','')+'.txt'
--Set Email Address Split semicolon ;
set @SplitStr=';'
Set @strTemp=@strRecipients+@SplitStr+'end'
Set @strTemp=Replace(@strTemp,',',';')
--Check sql Sentence
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
--Call sp_jmail_send Send Mail
EXEC sp_jmail_send @sender=@SenderAddress,@sendername=@SenderName,
@serveraddress=@MailServer,@MailServerUserName=@User,@MailServerPassword=@Pass,
@recipient=@email,@subject=@strSubject,@mailbody=@strMessage,@attachment=@AttachDir
End
事实上,我们用第一个sp_jmail_send 存储过程就够了,后面的一个SendMail 的存储过程是在前一个的基础上做的扩展。根据需求来改变,你可以做更多的扩展。
注意:如果在执行存储过程的时候发生如下错误:
Msg 15281, Level 16, State 1, Procedure sp_OACreate, Line 1
SQL Server blocked access to procedure 'sys.sp_OACreate' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.
Msg 15281, Level 16, State 1, Procedure sp_OASetProperty, Line 1
SQL Server blocked access to procedure 'sys.sp_OASetProperty' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.
Msg 15281, Level 16, State 1, Procedure sp_OASetProperty, Line 1
SQL Server blocked access to procedure 'sys.sp_OASetProperty' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.
Msg 15281, Level 16, State 1, Procedure sp_OASetProperty, Line 1
SQL Server blocked access to procedure 'sys.sp_OASetProperty' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.
我们需要修改:
Start -> programs ->MS sql -> configuration tools -> surfce area configuration -> Surface area conf for features ->
Ole automation -> select the Enable check box and saved