SQLMail的原理及實(shí)際應(yīng)用
-概述----這里所指的SQLMail,是微軟公司的關(guān)系數(shù)據(jù)庫管理系統(tǒng) SQLServer所提供的郵件功能。在SQLServer中包含一些擴(kuò)展存儲(chǔ)過程,使得SQLServer可以通過基于WindowsNT內(nèi)部的消息應(yīng)用編程界面(MAPI)的客戶機(jī)郵件程序接收和發(fā)送郵件消息。SQLMail可發(fā)送的消息包括文本串,附加文件或SQL語句的執(zhí)行結(jié)果集。應(yīng)用SQLMail的擴(kuò)展存儲(chǔ)過程,郵件消息可以從一個(gè)觸發(fā)
器或一個(gè)存儲(chǔ)過程中發(fā)送,并且通過SQLServer提供的任務(wù)和警告等功能,可以根據(jù)需要在不同的時(shí)間和情況下發(fā)送。
----SQLMail工作流程
----SQLMail工作流程主要分為郵件收、發(fā)兩個(gè)過程。
----在SQLServer內(nèi)可以通過一定方法,調(diào)用擴(kuò)展存儲(chǔ)過程xp_s
endmail,將收信人電子郵件地址,標(biāo)題,信的內(nèi)容等以參數(shù)的形式傳送給xp_sendmail,由它通過客戶端MAPI接口將發(fā)送郵件任
務(wù)交給如MicrosoftExchangeClient或Outlook97等郵件客戶端程序,最終通過郵件服務(wù)將郵件發(fā)送出去。
----收郵件的過程與此相似。在SQLServer端定期或手工調(diào)用xp_readmail擴(kuò)展存儲(chǔ)過程,通過客戶端MAPI接口將存放在郵件服務(wù)器或客戶端的郵件及其他信息讀入SQL變量中,用來滿足特定的處理需要。
配置SQLMail
----配置SQLMail的首要條件是要有一個(gè)電子郵件帳戶,不管是局域網(wǎng)內(nèi)的MSExchangeServer或MSMail3.x的郵件帳戶,還是Internet上的SMTP,POP3等郵件帳戶均可。具體配置可分為以下幾步:
----1.為SQLServer創(chuàng)建一個(gè)NT域用戶帳號(hào),要求具有本地管理員組的權(quán)限。仔細(xì)設(shè)置帳號(hào)口令,保證口令足夠復(fù)雜,且設(shè)成口令永不過期和用戶不得更改口令。
----2.雙擊控制面板的服務(wù)圖標(biāo),找到MSSQLServer的啟動(dòng)設(shè)置,將UseSystemAccount改為UseThisAccount,將剛才建立的NT帳號(hào)和口令輸入。重新啟動(dòng)SQLServer。
----3.在安裝SQLServer的服務(wù)器上以與啟動(dòng)SQLServer相同的NT帳號(hào)登錄,然后安裝支持MAPI接口的郵件客戶端程序,如MS
ExchangeClient和Outlook97。
----4.打開控制面板的電子郵件選項(xiàng),建立一個(gè)配置文件(Profile)。用這個(gè)配置文件啟動(dòng)郵件客戶端程序,反復(fù)檢驗(yàn)直至能正常收發(fā)郵件。
----5.從SqlEnterpriserManager中,點(diǎn)中相應(yīng)的服務(wù)器圖標(biāo),從
Server菜單中選SQLMail/Configure,將在第4步中建立的配置文件名輸入。
----6.從SqlEnterpriserManager中,點(diǎn)中相應(yīng)的服務(wù)器圖標(biāo),從
Server菜單中選SQLMail/Start,如果SqlMail的圖標(biāo)變?yōu)榫G色,則SQ
LMail成功啟動(dòng)。
----常用的SQLMail擴(kuò)展存儲(chǔ)過程
xp_sendmail@recipient=recipient
[;recipient2;[...;recipientn]]
[,@message=message]
[,@query=query]
[,@attachments=attachments]
[,@copy_recipients=recipient
[;recipient2;[...;recipientn]]]
[,@blind_copy_recipients=recipient
[;recipient2;[...;recipientn]]]
[,@subject=subject]
[,@type=type]
[,@attach_results={'true'|'false'}]
[,@no_output={'true'|'false'}]
[,@no_header={'true'|'false'}]
[,@width=width]
[,@separator=separator]
[,@echo_error={'true'|'false'}]
[,@set_user=user]
[,@dbuse=dbname]
----此存儲(chǔ)過程通過客戶端MAPI接口發(fā)送郵件,內(nèi)容可以是文本串,附加文件或SQL語句的執(zhí)行結(jié)果集。
xp_findnextmsg[@msg_id=msg_id[OUTPUT]]
[,@type=type]
[,@unread_only={'true'|'false'}])
----此存儲(chǔ)過程在郵箱中查找特定的郵件,并返回一封郵件的消息ID。
xp_readmail([@msg_id=msg_id][,@type=type[OUTPUT]]
[,@peek={'true'|'false'}]
[,@suppress_attach={'true'|'false'}]
[,@originator=@senderOUTPUT]
[,@subject=@subject_lineOUTPUT]
[,@message=@body_of_messageOUTPUT]
[,@recipients=@recipient_listOUTPUT]
[,@cc_list=@cc_listOUTPUT]
[,@bcc_list=@bcc_listOUTPUT]
[,@date_received=@dateOUTPUT]
[,@unread={'true'|'false'}]
[,@attachments=@temp_file_pathsOUTPUT])
[,@skip_bytes=@bytes_toskipOUTPUT]
[,@msg_length=@length_in_bytesOUTPUT])
----此存儲(chǔ)過程從指定的郵件收件箱中讀取指定消息ID的郵件的各項(xiàng)信息。
----xp_deletemail[@msg_id=]msg_id
----從郵件收件箱中刪除一封指定消息ID的郵件。
----注釋:
----1.存儲(chǔ)過程的多個(gè)參數(shù)間用逗號(hào)間隔開,[]內(nèi)的為可選參數(shù),每個(gè)參數(shù)均以@符號(hào)加字符串開頭,用以區(qū)別不同的參數(shù)項(xiàng)。等號(hào)后可以是常量,也可以是預(yù)先定義好的變量。
----2.如果需要將某個(gè)結(jié)果值賦予參數(shù)中預(yù)先定義好的變量,就必須在該項(xiàng)參數(shù)的最后加OUTPUT。
----3.常用參數(shù)解釋:
----?@recipient=recipient;指定收件人的電子郵件地址。如果有多個(gè)收件人,可以用分號(hào)分隔開。
----?@subject=subject;郵件的標(biāo)題。發(fā)送郵件時(shí)的默認(rèn)值為
"SQLServerMessage"。
----?@message=message;郵件的具體內(nèi)容。
----?@attachments=attachments;郵件掛接的附加文件名。
----?@type=type;基于MAPI定義的消息類型,詳細(xì)信息參見"
MicrosoftWindowsNTResourceKit"或"MicrosoftMailTechnicalReference"。
----?@query=query;一條SQL可執(zhí)行語句,其執(zhí)行結(jié)果以正文或附件的方式隨郵件發(fā)送。
----?@msg_id=msg_id;對(duì)于信箱中的每一封郵件均被分配了
----?@attachments=attachments;郵件掛接的附加文件名。
----?@type=type;基于MAPI定義的消息類型,詳細(xì)信息參見"
MicrosoftWindowsNTResourceKit"或"MicrosoftMailTechnicalReference"。
----?@query=query;一條SQL可執(zhí)行語句,其執(zhí)行結(jié)果以正文或附件的方式隨郵件發(fā)送。
----?@msg_id=msg_id;對(duì)于信箱中的每一封郵件均被分配了一個(gè)特殊的消息ID,用以相互區(qū)分。
----?@originator=@sender;讀取特定郵件的發(fā)送者的郵件地址。
--基于SQLMail的電子報(bào)刊自動(dòng)處理系統(tǒng)
----這里利用SQLMail簡單的實(shí)現(xiàn)了一個(gè)電子報(bào)刊自動(dòng)處理系統(tǒng)。每當(dāng)新的一期電子報(bào)刊編輯完成,只需簡單追加到發(fā)行數(shù)據(jù)庫publication中,SQLServer會(huì)自動(dòng)定期執(zhí)行my_publish存儲(chǔ)過程。在my_publish存儲(chǔ)過程中,它檢查發(fā)行數(shù)據(jù)庫,當(dāng)發(fā)現(xiàn)有新的記錄(即新的一期電子報(bào)刊)時(shí),就通過逐個(gè)從訂閱數(shù)據(jù)庫sub_info中取出訂閱人的郵件地址,完成給每個(gè)訂閱者發(fā)送電子報(bào)刊(以郵件形式)的任務(wù)。
----電子報(bào)刊的訂閱與取消也是通過郵件來實(shí)現(xiàn)。SQLServer同樣定期執(zhí)行my_subscibe存儲(chǔ)過程。my_subscibe存儲(chǔ)過程檢查特定
郵箱中的所有郵件,如果存在標(biāo)題為"subscribe"的郵件,就取出它的發(fā)件人等信息,在訂閱數(shù)據(jù)庫中添加一條記錄;同樣,如果存在標(biāo)題為"stopsubscribe"的郵件,就將它的相關(guān)記錄從訂閱數(shù)據(jù)庫中刪除。系統(tǒng)中用到的數(shù)據(jù)庫和存儲(chǔ)過程如下所
示。sub_info(訂閱者信息數(shù)據(jù)庫) 字段名稱類型允許空值含義
emailvarchar(20)NOTNULL訂閱者電子郵件地址
sub_datedatetimeNOTNULL訂閱時(shí)間
othertextNULL訂閱者的其他信息
publication(電子報(bào)刊出版數(shù)據(jù)庫)
字段名稱類型允許空值含義
pub_classchar(10)NOTNULL電子報(bào)刊期號(hào)
pub_datedatetimeNULL出版日期
titletextNOTNULL本期電子報(bào)刊標(biāo)題
contenttextNOTNULL電子報(bào)刊正文
endnotetextNULL附加于報(bào)刊的其他信息
flagsmallintNULL1,標(biāo)志為未出版的新報(bào)刊
my_subscribe,用于處理訂閱者信息的存儲(chǔ)過程。
CREATEPROCEDUREmy_subscribe
AS
declare@msg_idvarchar(64)
declare@subjectvarchar(255)
declare@messagevarchar(255)
declare@originatorvarchar(255)
declare@datevarchar(255)
declare@statusint
declare@mapifailureint
select@mapifailure=0
while(1=1)
begin
/*查找郵件并獲取消息ID*/
exec@status=master..
xp_findnextmsg@msg_id=@msg_idOUTPUT
if@status<>0
begin
select@mapifailure=1
break
end
if@msg_idisnullbreak
/*讀取郵件的信息到變量中*/
exec@status=master..xp_readmail
@msg_id=@msg_id,
@originator=@originatorOUTPUT,
@subject=@subjectOUTPUT,
@message=@messageOUTPUT,
@date_received=@dateOUTPUT
if@status<>0
begin
select@mapifailure=1
break
end
/*根據(jù)郵件標(biāo)題,在訂閱數(shù)據(jù)庫中添加或刪除記錄*/
execxp_deletemail@msg_id=@msg_id
if@subject='subscribe'
insertintosqlmailsample..
sub_infovalues(@originator,@date,@message)
else
if@subject='stopsubscribe'
deletefromsqlmailsample..sub_infowhereemail=@originator
end/*循環(huán)結(jié)束*/
if@mapifailure=1
/*錯(cuò)誤處理代碼*/
else
return(0)
GO
my_publish,用于分發(fā)電子報(bào)刊的存儲(chǔ)過程。
CREATEPROCEDUREmy_publish
AS
declare@recipientvarchar(255)
declare@subjectvarchar(255)
declare@contentvarchar(255)
declare@endnotevarchar(255)
declare@statusint
select@subject=pub_classfrom
sqlmailsample..publicationwhereflag=1
/*如果有新的電子報(bào)刊,則開始分發(fā)*/
if(@subjectisnotnull)
begin
/*將數(shù)據(jù)庫記錄取出,經(jīng)過適當(dāng)處理后,存放到變量中*/
select@subject=convert(varchar
(255),title)+'('+pub_class+')',
@content=convert(varchar(255),content)
+convert(varchar(255),endnote)
fromsqlmailsample..publication
whereflag=1
updatesqlmailsample..publication
setflag=0whereflag=1
declarecurcursorforselect
emailfromsqlmailsample..sub_info
opencur
fetchcur
while(@@fetch_status=0)
begin
/*取收件人的電子郵件地址*/
fetchnextfromcurinto@recipient
/*發(fā)送電子郵件*/
if@@fetch_status=0
begin
exec@status=master..xp_sendmail
@recipients=@recipient,
@message=@content,
@subject=@subject
if@status<>0
/*錯(cuò)誤處理代碼*/
end
end/*向所有訂閱人發(fā)送電子報(bào)刊的循環(huán)結(jié)束*/
closecur
deallocatecur
end
GO
----總之,SQLMail在數(shù)據(jù)庫和電子郵件之間架起了一座溝通
end/*向所有訂閱人發(fā)送電子報(bào)刊的循環(huán)結(jié)束*/
closecur
deallocatecur
end
GO
----總之,SQLMail在數(shù)據(jù)庫和電子郵件之間架起了一座溝通的橋梁,為某些特定用途的應(yīng)用提供了簡單高效的解決方案,值得一試
posted on 2006-06-01 15:45 【Xine】中文站 閱讀(274) 評(píng)論(0) 編輯 收藏 所屬分類: SQL Server