-概述
----這里所指的SQLMail,是微軟公司的關系數據庫管理系統 SQLServer所提供的郵件功能。在SQLServer中包含一些擴展存儲過程,使得SQLServer可以通過基于WindowsNT內部的消息應用編程界面(MAPI)的客戶機郵件程序接收和發送郵件消息。SQLMail可發送的消息包括文本串,附加文件或SQL語句的執行結果集。應用SQLMail的擴展存儲過程,郵件消息可以從一個觸發
器或一個存儲過程中發送,并且通過SQLServer提供的任務和警告等功能,可以根據需要在不同的時間和情況下發送。
----SQLMail工作流程
----SQLMail工作流程主要分為郵件收、發兩個過程。
----在SQLServer內可以通過一定方法,調用擴展存儲過程xp_s
endmail,將收信人電子郵件地址,標題,信的內容等以參數的形式傳送給xp_sendmail,由它通過客戶端MAPI接口將發送郵件任
務交給如MicrosoftExchangeClient或Outlook97等郵件客戶端程序,最終通過郵件服務將郵件發送出去。
----收郵件的過程與此相似。在SQLServer端定期或手工調用xp_readmail擴展存儲過程,通過客戶端MAPI接口將存放在郵件服務器或客戶端的郵件及其他信息讀入SQL變量中,用來滿足特定的處理需要。
配置SQLMail
----配置SQLMail的首要條件是要有一個電子郵件帳戶,不管是局域網內的MSExchangeServer或MSMail3.x的郵件帳戶,還是Internet上的SMTP,POP3等郵件帳戶均可。具體配置可分為以下幾步:
----1.為SQLServer創建一個NT域用戶帳號,要求具有本地管理員組的權限。仔細設置帳號口令,保證口令足夠復雜,且設成口令永不過期和用戶不得更改口令。
----2.雙擊控制面板的服務圖標,找到MSSQLServer的啟動設置,將UseSystemAccount改為UseThisAccount,將剛才建立的NT帳號和口令輸入。重新啟動SQLServer。
----3.在安裝SQLServer的服務器上以與啟動SQLServer相同的NT帳號登錄,然后安裝支持MAPI接口的郵件客戶端程序,如MS
ExchangeClient和Outlook97。
----4.打開控制面板的電子郵件選項,建立一個配置文件(Profile)。用這個配置文件啟動郵件客戶端程序,反復檢驗直至能正常收發郵件。
----5.從SqlEnterpriserManager中,點中相應的服務器圖標,從
Server菜單中選SQLMail/Configure,將在第4步中建立的配置文件名輸入。
----6.從SqlEnterpriserManager中,點中相應的服務器圖標,從
Server菜單中選SQLMail/Start,如果SqlMail的圖標變為綠色,則SQ
LMail成功啟動。
----常用的SQLMail擴展存儲過程
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]
----此存儲過程通過客戶端MAPI接口發送郵件,內容可以是文本串,附加文件或SQL語句的執行結果集。
xp_findnextmsg[@msg_id=msg_id[OUTPUT]]
[,@type=type]
[,@unread_only={'true'|'false'}])
----此存儲過程在郵箱中查找特定的郵件,并返回一封郵件的消息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])
----此存儲過程從指定的郵件收件箱中讀取指定消息ID的郵件的各項信息。
----xp_deletemail[@msg_id=]msg_id
----從郵件收件箱中刪除一封指定消息ID的郵件。
----注釋:
----1.存儲過程的多個參數間用逗號間隔開,[]內的為可選參數,每個參數均以@符號加字符串開頭,用以區別不同的參數項。等號后可以是常量,也可以是預先定義好的變量。
----2.如果需要將某個結果值賦予參數中預先定義好的變量,就必須在該項參數的最后加OUTPUT。
----3.常用參數解釋:
----?@recipient=recipient;指定收件人的電子郵件地址。如果有多個收件人,可以用分號分隔開。
----?@subject=subject;郵件的標題。發送郵件時的默認值為
"SQLServerMessage"。
----?@message=message;郵件的具體內容。
----?@attachments=attachments;郵件掛接的附加文件名。
----?@type=type;基于MAPI定義的消息類型,詳細信息參見"
MicrosoftWindowsNTResourceKit"或"MicrosoftMailTechnicalReference"。
----?@query=query;一條SQL可執行語句,其執行結果以正文或附件的方式隨郵件發送。
----?@msg_id=msg_id;對于信箱中的每一封郵件均被分配了
----?@attachments=attachments;郵件掛接的附加文件名。
----?@type=type;基于MAPI定義的消息類型,詳細信息參見"
MicrosoftWindowsNTResourceKit"或"MicrosoftMailTechnicalReference"。
----?@query=query;一條SQL可執行語句,其執行結果以正文或附件的方式隨郵件發送。
----?@msg_id=msg_id;對于信箱中的每一封郵件均被分配了一個特殊的消息ID,用以相互區分。
----?@originator=@sender;讀取特定郵件的發送者的郵件地址。
--基于SQLMail的電子報刊自動處理系統
----這里利用SQLMail簡單的實現了一個電子報刊自動處理系統。每當新的一期電子報刊編輯完成,只需簡單追加到發行數據庫publication中,SQLServer會自動定期執行my_publish存儲過程。在my_publish存儲過程中,它檢查發行數據庫,當發現有新的記錄(即新的一期電子報刊)時,就通過逐個從訂閱數據庫sub_info中取出訂閱人的郵件地址,完成給每個訂閱者發送電子報刊(以郵件形式)的任務。
----電子報刊的訂閱與取消也是通過郵件來實現。SQLServer同樣定期執行my_subscibe存儲過程。my_subscibe存儲過程檢查特定
郵箱中的所有郵件,如果存在標題為"subscribe"的郵件,就取出它的發件人等信息,在訂閱數據庫中添加一條記錄;同樣,如果存在標題為"stopsubscribe"的郵件,就將它的相關記錄從訂閱數據庫中刪除。系統中用到的數據庫和存儲過程如下所
示。sub_info(訂閱者信息數據庫) 字段名稱類型允許空值含義
emailvarchar(20)NOTNULL訂閱者電子郵件地址
sub_datedatetimeNOTNULL訂閱時間
othertextNULL訂閱者的其他信息
publication(電子報刊出版數據庫)
字段名稱類型允許空值含義
pub_classchar(10)NOTNULL電子報刊期號
pub_datedatetimeNULL出版日期
titletextNOTNULL本期電子報刊標題
contenttextNOTNULL電子報刊正文
endnotetextNULL附加于報刊的其他信息
flagsmallintNULL1,標志為未出版的新報刊
my_subscribe,用于處理訂閱者信息的存儲過程。
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
/*根據郵件標題,在訂閱數據庫中添加或刪除記錄*/
execxp_deletemail@msg_id=@msg_id
if@subject='subscribe'
insertintosqlmailsample..
sub_infovalues(@originator,@date,@message)
else
if@subject='stopsubscribe'
deletefromsqlmailsample..sub_infowhereemail=@originator
end/*循環結束*/
if@mapifailure=1
/*錯誤處理代碼*/
else
return(0)
GO
my_publish,用于分發電子報刊的存儲過程。
CREATEPROCEDUREmy_publish
AS
declare@recipientvarchar(255)
declare@subjectvarchar(255)
declare@contentvarchar(255)
declare@endnotevarchar(255)
declare@statusint
select@subject=pub_classfrom
sqlmailsample..publicationwhereflag=1
/*如果有新的電子報刊,則開始分發*/
if(@subjectisnotnull)
begin
/*將數據庫記錄取出,經過適當處理后,存放到變量中*/
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
/*發送電子郵件*/
if@@fetch_status=0
begin
exec@status=master..xp_sendmail
@recipients=@recipient,
@message=@content,
@subject=@subject
if@status<>0
/*錯誤處理代碼*/
end
end/*向所有訂閱人發送電子報刊的循環結束*/
closecur
deallocatecur
end
GO
----總之,SQLMail在數據庫和電子郵件之間架起了一座溝通
end/*向所有訂閱人發送電子報刊的循環結束*/
closecur
deallocatecur
end
GO
----總之,SQLMail在數據庫和電子郵件之間架起了一座溝通的橋梁,為某些特定用途的應用提供了簡單高效的解決方案,值得一試