让我们假设我有一个表ExchangeSession,字段已处理。
我需要使用Processed = 0的所有ExchangeSession发送电子邮件,然后将这些会话更新为Processed = 1.像这样:
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'SomeProfile',
@recipients='SomeAddress',
@subject = 'SomeSubject',
@body = @bodyparam,
@body_format = 'TEXT',
@query = N'SET NOCOUNT ON; select * from ExchangeSession where Processed = 0',
@execute_query_database = @dbnameparam,
@attach_query_result_as_file = 1,
@query_attachment_filename = 'report.csv',
@query_result_header = 1,
@query_result_width = 32767,
@query_result_separator = @delimiterparam,
@exclude_query_output = 1,
@append_query_error = 0,
@query_no_truncate = 0,
@query_result_no_padding = 1;
update ExchangeSession
set
Processed = 1
where
Processed = 0
sp_send_dbmail会相对于批处理还是异步地同步执行我的查询?换句话说,是否有可能在电子邮件中我没有得到所有未经处理的会话?
答案 0 :(得分:1)
答案是肯定的。查询参数执行是相对于批处理同步的。 做了以下测试:
insert dbo.[CallLog]([Name]) values ('BeforeMail')
set @queryparam = N'SET NOCOUNT ON;
insert dbo.[CallLog]([Name]) values (''Attachment'');
SELECT
0 as [ID],
...'
...
EXEC msdb.dbo.sp_send_dbmail
...
@query = @queryparam,
...
insert dbo.[CallLog]([Name]) values ('AfterMail')
瞧,CallLog中的结果:
LogID Name
801 BeforeMail
802 Attachment
803 AfterMail
我还查看了 sysmail_allitems 和 sysmail_mailattachments 。 sysmail_allitems 中的 send_request_date 值与 sysmail_mailattachments 中的 last_mod_date 值完全相同。 sysmail_allitems 中 sent_date 的值略有不同。
因此,sp_send_dbmail在批处理中同步执行查询,将结果保存到文件中,然后再发送电子邮件。
答案 1 :(得分:0)
我不是100%肯定,但我认为新条目可能会在发送电子邮件和更新记录之间潜入您的ExchangeSession
表。我会这样做安全:
update ExchangeSession
set Processed = 2 -- This procedure should be the only place that sets Processed to 2
where Processed = 0
EXEC msdb.dbo.sp_send_dbmail
....
@query = N'SET NOCOUNT ON; select * from ExchangeSession where Processed = 2',
....
update ExchangeSession
set Processed = 1
where Processed = 2