Share via


xp_sendmail (Transact-SQL)

將可能含有查詢結果集附加檔案的電子郵件訊息傳送給指定的收件者。這個擴充預存程序會利用 SQL Mail 來傳送訊息。

[!附註]

未來的 Microsoft SQL Server 版本將移除這項功能。請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。 若要從 SQL Server 傳送郵件,請使用 Database Mail

主題連結圖示Transact-SQL 語法慣例

語法

xp_sendmail { [ @recipients= ] 'recipients [ ;...n ]' } 
     [ ,[ @message= ] 'message' ] 
     [ ,[ @query= ] 'query' ] 
     [ ,[ @attachments= ] 'attachments [ ;...n ]' ] 
     [ ,[ @copy_recipients= ] 'copy_recipients [ ;...n ]'
     [ ,[ @blind_copy_recipients= ] 'blind_copy_recipients [ ;...n ]'
     [ ,[ @subject= ] 'subject' ]
     [ ,[ @type= ] 'type' ] 
     [ ,[ @attach_results= ] 'attach_value' ]
     [ ,[ @no_output= ] 'output_value' ] 
     [ ,[ @no_header= ] 'header_value' ] 
     [ ,[ @width= ] width ] 
     [ ,[ @separator= ] 'separator' ] 
     [ ,[ @echo_error= ] 'echo_value' ] 
     [ ,[ @set_user= ] 'user' ] 
     [ ,[ @dbuse= ] 'database' ]

引數

  • [@recipients=] **'**recipients [ ;...n] '
    這是郵件的收件者清單 (用分號分隔)。

  • [@message=] 'message'
    這是要傳送的訊息主體。message 最多可有 8,000 位元組。

  • [@query=] 'query'
    這是用郵件來傳送結果的有效 SQL Server 查詢。xp_sendmail 會在 query 參數上使用繫結連接。SQL Mail 所建立的 query 連接不會因為發出 xp_sendmail 要求之用戶端所保留的鎖定而遭到封鎖。這使您更容易從觸發程序內使用 xp_sendmail。不過,query 陳述式不能參考 inserteddeleted 邏輯資料表,因為這些資料表只能在觸發程序內使用。query 最多可有 8,000 位元組。

  • [@attachments=] 'attachments [ ;...n] '
    這是一份附加至郵件訊息的檔案清單 (用分號分隔)。如果您在 @attach_results 是 TRUE 時使用 @query 參數,
    @attachments
    參數只能指定將一個檔案附加至郵件訊息。在這個情況下,若要傳送多個檔案,您必須針對每個附加的檔案來個別執行 xp_sendmail

  • [@copy_recipients=] **'**copy_recipients [ ;...n] '
    這是用來識別郵件副本收件者的清單 (用分號分隔)。

  • [@blind_copy_recipients=] **'**blind_copy_recipients[ ;...n] '
    這是用來識別郵件密件副本收件者的選擇性清單 (用分號分隔)。

  • [@subject=] 'subject'
    這是指定郵件主旨的參數。如果未指定 subject,預設值就是「SQL Server 訊息」。

  • [@type=] 'type'
    這是以 MAPI 郵件定義為基礎的輸入訊息類型:

    IP[ M|C ].Vendorname.subclass

    如果 type 是 NULL,xp_sendmail 會使用 IPM 訊息類型。開頭是 IPM 的訊息類型會出現在郵件用戶端的收件匣中,xp_findnextmsg 會尋找和讀取它們。開頭是 IPC 的訊息類型不會出現在郵件用戶端的收件匣中,您必須設定 type 參數來尋找或讀取它們。預設值是 NULL。SQL Mail 支援訊息類型 IPM 和 IPC。

  • [@attach_results=] 'attach_value'
    這是一個選擇性參數,用來指定查詢的結果集應該當作郵件中附加的檔案來傳送,而不是附加至郵件中。如果 @attachments 不是 NULL,且 @attach_results 是 TRUE,attachments 中的第一個檔案名稱會用來作為結果的檔案名稱。如果 @attachments 是 NULL,就會產生副檔名是 .txt 的檔案名稱。預設值是 FALSE,表示將結果集附加至訊息中。

  • [@no_output=] 'output_value'
    這是一個傳送郵件的選擇性參數,但不會將任何輸出傳回送出郵件的用戶端工作階段。預設值是 FALSE,表示 SQL Server 的用戶端工作階段會接收輸出。

  • [@no_header=] 'header_value'
    這是一個選擇性參數,用來在郵件中傳送查詢結果,但不隨著查詢結果而傳送資料行標頭資訊。預設值是 FALSE,表示會隨著查詢結果而傳送資料行標頭資訊。

  • [@width=] width
    這是一個選擇性參數,用來設定查詢輸出文字的行寬。這個參數與 isql 公用程式中的 /w 參數相同。對於產生較長輸出資料列的查詢,請搭配 attach_results 來使用 width,以傳送輸出行當中不含分行符號的輸出。預設寬度是 80 個字元。

  • [@separator=] 'separator'
    這是結果集中各資料行的資料行分隔字元字串。依預設,資料行分隔字元是空格。使用資料行分隔字元,會使試算表和其他應用程式更容易剖析結果集。例如,搭配 attach_results 來使用 separator,會傳送含逗號分隔值的檔案。

  • [@echo_error=] 'echo_value'
    當這個值是 TRUE 時,SQL Mail 會擷取執行查詢時所發現的任何伺服器訊息或 DB-Library 錯誤,且會將它們附加至郵件訊息,而不會寫入錯誤記錄中。另外,也會將傳回的資料列數/受影響的資料列數附加至郵件訊息中。

    [!附註]

    當 echo_error 是 TRUE 時,如果郵件傳送成功,xp_sendmail 會傳回 0 (成功) 狀態,即使出現 DB-Library 錯誤或訊息,或查詢未傳回任何結果,都是如此。

  • [@set_user=] 'user'
    這是應於其中執行查詢的安全性內容。如果未指定 user,安全性內容便預設為執行 xp_sendmail 之使用者的安全性內容。

  • [@dbuse=] 'database'
    這是查詢應該在其中執行的資料庫內容。預設值是 NULL,表示使用者在預設資料庫中。

傳回碼值

0 (成功) 或 1 (失敗)

結果集

當成功時,xp_sendmail 會傳回訊息。

備註

您必須先啟動 SQL Mail 工作階段,才能執行 xp_sendmail。工作階段可以自動啟動,也可以利用 xp_startmail 來啟動。如需有關如何自動設定 SQL Mail 工作階段的詳細資訊,請參閱<設定擴充 MAPI 郵件設定檔>。單一 SQL Mail 工作階段會支援 SQL Server 執行個體的所有使用者,但每次只能有一位使用者傳送訊息。其他傳送郵件訊息的使用者會自動等待第一位使用者的訊息送出,才輪到他們。

如果指定 query,xp_sendmail 會以用戶端的身分登入 SQL Server,且會執行指定的查詢。SQL Mail 會建立通往 SQL Server 的個別連接;它不會共用發出 xp_sendmail 的原始用戶端連接的相同連接。

[!附註]

query 可能會被發出 xp_sendmail 的用戶端連接所保留的鎖定封鎖。例如,如果您在交易內更新資料表,且您建立了更新用的觸發程序來嘗試選取與 query 參數相同的更新資料列資訊,此時初始用戶端連接所保留的資料列獨佔鎖定便會封鎖 SQL Mail 連接。

xp_sendmail 是在 SQL Server 的安全性內容中執行。xp_sendmail 的有效使用者可以存取檔案來作為管理員安全性內容中之郵件訊息的附加檔案。如果系統管理員以外的使用者必須存取 xp_sendmail,且您想要保護附加檔案,使它們不會遭到不安全的存取,系統管理員可以建立一個預存程序來呼叫 xp_sendmail 及提供必要的功能,但這並不會顯露 attachments 參數。這個預存程序必須定義在 master 資料庫中。之後,系統管理員便可以在不授與基礎 xp_sendmail 程序權限的情況下,將這個預存程序的執行權限授與必要的使用者。

xp_sendmail 會將訊息和查詢結果集或附加檔案傳給指定的收件者,且它會使用 query 參數的繫結連接。SQL Mail 所建立的 query 連接不會因為發出 xp_sendmail 要求之用戶端所保留的鎖定而遭到封鎖。這使您更容易從觸發程序內使用 xp_sendmail。不過,query 陳述式不能參考只能在觸發程序內使用的邏輯插入和刪除的資料表。

[!附註]

當郵局和通訊錄是在 MSSQLServer 服務因權限不足而無法存取的檔案共用中,嘗試執行 xp_sendmail 可能會造成存取違規。

xp_sendmail 並未完整支援 xml 資料類型。使用 xml 資料類型的查詢可能會有不正確的格式。請利用 Database Mail 來傳送包括 xml 資料的電子郵件。

權限

需要系統管理員 (sysadmin) 固定伺服器角色中的成員資格,但是 EXECUTE 權限可以授與其他使用者。不過,基於安全性的考量,建議您將這個預存程序的權限限制在系統管理員 (sysadmin) 固定伺服器角色的成員。

範例

A. 將訊息傳送給單一收件者

下列範例會將 master 資料庫已滿的訊息傳給使用者 Dan Wilson (電子郵件是 danw)。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com',
    @message=N'The master database is full.' ;

B. 將訊息傳送給多位收件者

下列範例會將訊息傳送給使用者 Dan Wilson 和 Ashvini Sharma (電子郵件是 ashvinis),副本傳給 Peter Connelly (電子郵件是 peterc)。此範例也會指定訊息的主旨。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com;ashvinis@Adventure-Works.com',
     @message=N'The master database is full.',
     @copy_recipients=N'peterc@Adventure-Works.com',
     @subject=N'Master database status' ;
GO

C. 傳送結果

下列範例會傳送 sp_configure 的結果給 Dan Wilson。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com',
    @query = N'EXEC sp_configure' ;
GO

D. 將結果當做附加檔案來傳送

下列範例會將 SELECT * FROM INFORMATION_SCHEMA.TABLES 查詢的結果當做文字檔案附件傳給 Dan Wilson。其中包括郵件的主旨以及出現在附加檔案前面的訊息。@width 參數可用來避免在輸出行中出現分行符號。

EXEC master.dbo.xp_sendmail
    @recipients = N'danw@Adventure-Works.com', 
    @query = N'SELECT * FROM INFORMATION_SCHEMA.TABLES',
    @subject = N'SQL Server Report',
    @message = N'The contents of INFORMATION_SCHEMA.TABLES:',
    @attach_results = 'TRUE',
    @width = 250 ;

E. 傳送超出 7,990 位元組字元的訊息

下列範例會顯示如何傳送超出 7,990 位元組字元的訊息。由於 message 只限於 VARCHAR 的長度 (資料列負擔較低,如同所有的預存程序參數),因此這個範例會將長訊息寫入單一文字資料行所組成的全域暫存資料表中。之後會利用 @query 參數,在郵件中傳送這個暫存資料表的內容。

CREATE TABLE ##mail_body(c1 NVARCHAR(4000)) ;

DECLARE @cmd VARCHAR(56) ;

INSERT ##mail_body(c1)
VALUES ('Put your long message here.') ;

SET @cmd = 'SELECT c1 FROM ##mail_body' ;

EXEC master.dbo.xp_sendmail 
    @recipients = 'danw@Adventure-Works.com', 
    @query = @cmd,
    @no_header= 'TRUE' ;

DROP TABLE ##mail_body ;