Sql-Server

執行 Sql 語句並將結果發送到電子郵件

  • September 6, 2019

我必須每天執行 SQL 語句並通過電子郵件將結果發送給 dba。我配置了數據庫電子郵件。

下面是查詢:

SELECT
       account.accountID,
       account.name
   FROM
       account
       LEFT OUTER JOIN accountfeaturesetting afs 
           ON afs.accountid = account.accountid 
               and afs.featureid = 'Schedules' 
               and afs.settingid = 'EditReasons'
   WHERE
       ISNULL(afs.Value, '0') = '1'
       AND NOT EXISTS
(SELECT 1 FROM program 
WHERE program.AccountID = account.AccountID
AND program.Active = 1 AND 
(program.ScheduleEditReasonFlags <> 0 OR
program.ScheduleEditReasonFields <> 0))
       AND account.IsMaster = 0

為此,我創建了具有 2 個步驟的 Sql 作業:

  1. 執行選擇語句
  2. 發送結果:
Use MSDB
   EXEC msdb.dbo.sp_send_dbmail
       @profile_name = 'abc',
       @recipients = 'recipients@company.com',
       @subject = 'queryresultset',
       @body='testmail',
       @query_attachment_filename='warning.csv'

它拋出錯誤,結果集未附加查詢。

錯誤:當沒有為參數 @query 指定值時,參數 @attach_query_result_as_file 不能為 1 (true)。

必須指定查詢以附加查詢結果。

$$ SQLSTATE 42000 $$(錯誤 14625)

編輯:

Use MSDB
   EXEC msdb.dbo.sp_send_dbmail
       @profile_name = 'abc',
       @recipients = 'recipients@company.com',
       @subject = 'queryresultset',
       @body='testmail',
       @query_attachment_filename='warning.csv'
   DECLARE @msg VARCHAR(250);
   declare @query varchar(2048);
   SELECT @msg = 'Please refer to the attached spread sheet for the report.';  

   set @query='
       SELECT
       account.accountID,
       account.name
   FROM
       account
       LEFT OUTER JOIN accountfeaturesetting afs 
           ON afs.accountid = account.accountid 
               and afs.featureid = 'Schedules' 
               and afs.settingid = 'EditReasons'
   WHERE
       ISNULL(afs.Value, '0') = '1'
       AND NOT EXISTS
(SELECT 1 FROM program 
WHERE program.AccountID = account.AccountID
AND program.Active = 1 AND 
(program.ScheduleEditReasonFlags <> 0 OR
program.ScheduleEditReasonFields <> 0))
       AND account.IsMaster = 0
       go';
       exec (@query)

上面的查詢沒有使用 schedules 和 editreasons value 列。聲明所有變數後,我仍然收到語法錯誤,例如:

declare @featureid varchar(100);
declare @settingid varchar(100);
declare @value varchar(100);

你的程式碼是倒退的。您正在發送電子郵件,然後生成查詢結果。sp_send_dbmail 儲存過程將為您執行查詢,並將結果附加到電子郵件正文中或作為附件。

如果您不知道,Microsoft 在其網站上為 SQL Server 提供了廣泛、全面且免費的文件。例如,sp_send_dbmail可在以下網址獲得詳細資訊: https ://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-send-dbmail-transact-sql

@query 參數記錄為:

$$ @query= $$‘query’

是要執行的查詢。查詢結果可以作為文件附加,也可以包含在電子郵件正文中。該查詢的類型為 nvarchar(max),並且可以包含任何有效的 Transact-SQL 語句。請注意,查詢是在單獨的會話中執行的,因此呼叫 sp_send_dbmail 的腳本中的局部變數對查詢不可用。

他們也有幾個呼叫的例子sp_send_dbmail,包括這個重點:

EXEC msdb.dbo.sp_send_dbmail  
   @profile_name = 'Adventure Works Administrator',  
   @recipients = 'yourfriend@Adventure-Works.com',  
   @query = 'SELECT COUNT(*) FROM AdventureWorks2012.Production.WorkOrder  
                 WHERE DueDate > ''2004-04-30''  
                 AND  DATEDIFF(dd, ''2004-04-30'', DueDate) < 2' ,  
   @subject = 'Work Order Count',  
   @attach_query_result_as_file = 1 ;  

因此,您需要將查詢定義傳遞給msdb.dbo.sp_send_dbmail這樣的:

DECLARE @msg VARCHAR(250);
DECLARE @query varchar(2048);

SET @msg = 'Please refer to the attached spread sheet for the report.';  

SET @query='
   SELECT
       account.accountID,
       account.name
   FROM
       dbo.account
       LEFT OUTER JOIN dbo.accountfeaturesetting afs 
           ON afs.accountid = account.accountid 
               AND afs.featureid = ''Schedules'' 
               AND afs.settingid = ''EditReasons''
   WHERE
       ISNULL(afs.Value, ''0'') = ''1''
       AND NOT EXISTS 
           (
               SELECT 1 
               FROM dbo.program 
               WHERE program.AccountID = account.AccountID
                   AND program.Active = 1 
                   AND (
                       program.ScheduleEditReasonFlags <> 0 
                       OR program.ScheduleEditReasonFields <> 0
                       )
           )
       AND account.IsMaster = 0;';

EXEC msdb.dbo.sp_send_dbmail
   @profile_name = 'abc'
   , @recipients = 'recipients@company.com'
   , @subject = 'queryresultset'
   , @body= @msg
   , @body_format = 'TEXT'
   , @query = @query
   , @execute_query_database = 'MyDB'  
   , @attach_query_result_as_file = 1
   , @query_attachment_filename='warning.csv'
   , @query_result_header = 1
   , @query_result_width = 80
   , @query_result_separator = ' '
   , @exclude_query_output = 0
   , @append_query_error = 1
   , @query_no_truncate = 0
   , @query_result_no_padding = 0;

還要注意包含的額外參數,這些參數控制各種輸出因素,例如查詢的格式等。

請注意,在上面的@query文本中,我已經“轉義”了單引號以防止 SQL Server 將它們視為文字分隔符。本質上,參數中出現的任何單引號都@query需要轉換為兩個單引號。Erland Sommarskog 有一篇關於動態 SQL 和嵌套字元串的優秀文章。

我相信你應該做類似的事情:

DECLARE @sub VARCHAR(100);
DECLARE @qry VARCHAR(1000);
DECLARE @msg VARCHAR(250);
DECLARE @query NVARCHAR(1000);
DECLARE @query_attachment_filename NVARCHAR(520);
SELECT @sub = 'TEST XML ATTACHMENT';
SELECT @msg = 'Please refer to the attached spread sheet for the report.';
SELECT @query = 'SET NOCOUNT ON;
           Select top 10 * from master..sysobjects WITH(NOLOCK)';
SELECT @query_attachment_filename = 'test.csv';
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = 'SQLMAIL',
    @recipients = 'sqldba@sqldba.com',
    @copy_recipients = 'sqldba@sqldba.com',
    @body = @msg,
    @subject = @sub,
    @query = @query,
    @query_attachment_filename = @query_attachment_filename,
    @attach_query_result_as_file = 1,
    @query_result_header = 1,
    @query_result_width = 256,
    @query_result_separator = '   ',
    @query_result_no_padding = 1;

參考: http ://sqlworkday.blogspot.ru/2010/12/how-to-send-csv-or-xls-file-as.html

引用自:https://dba.stackexchange.com/questions/168395