我有一个概念可以这样描述的查询:
CREATE TABLE ##MyTable (
-- rows
)
INSERT INTO ##MyTable (...)
/*inserted SELECT */
WHILE ....
BEGIN
-- do some actions using data from temp table
END
EXEC msdb.dbo.sp_send_dbmail
-- other data needed for email sending ...
@query = N'select ... FROM ##MyTable;',
-- drop the temporary table
DROP TABLE ##MyTable
所以,我选择一些数据到全局临时表,他们使用它,他们发送电子邮件,最后删除这个临时表。
此查询用作任务,该任务会定期启动以自动执行数据库中的某些进程。
我怀疑的那一刻 - 是全球临时表。如果我打算只在这个自动化脚本中使用这个表(带有这样的名字),我能确定不会发生冲突或其他类似的错误吗?它看起来不应该,因为没有用户或程序连接将使用此表,因此逻辑很简单:我的任务每周启动一次,创建此表然后删除它。但它真的如此,或者我想念一些时刻,在这里使用全球临时表不是一个好主意吗?
PS:我试过使用当地的临时工。表,但是sp_send_dbmail返回错误(据我所知,当sp_send_dbmail启动时,表已被删除):Msg 22050, Level 16, State 1, Line 0
Error formatting query, probably invalid parameters
Msg 14661, Level 16, State 1, Procedure sp_send_dbmail, Line 504
Query execution failed: Msg 208, Level 16, State 1, Server SERVER\SERVER, Line 1
Invalid object name '#MyTable'.
答案 0 :(得分:4)
您认为会话临时表不能与sp_send_dbmail一起使用是正确的。引用文档,强调我的:
[@ query =]'query'是要执行的查询。查询结果 可以作为文件附加,也可以包含在电子邮件正文中 信息。查询的类型为nvarchar(max),可以包含任何有效的查询 Transact-SQL语句。 请注意,查询是在a中执行的 单独的会话,所以脚本调用中的局部变量 查询无法使用sp_send_dbmail 。
任何用户都可以创建全局临时表,因此可能会发生冲突。如果任务的执行时间过长并且与下一次运行重叠,则会发生这种情况。我可以考虑三种方法来解决这个问题。
答案 1 :(得分:1)
全局临时表意味着任何其他用户也可以尝试创建相同的全局临时表。这会导致碰撞。
在大多数情况下,创建和使用永久表对我们很有帮助。使用永久表可以获得很多优势。你可以掌握事情的历史。如果您认为数据会增长,您可以设置管家,以删除超过几天或几周的数据。
在我们的项目中,我们的指导是:创建一个“真正的”临时表或“真正的”永久表。
答案 2 :(得分:1)
不使用全局临时表。将您的查询输出转换为HTML正文,这里可以帮助您https://dba.stackexchange.com/questions/83776/need-to-send-a-formatted-html-email-via-database-mail-in-sql-server-2008-r2
使用全局临时表但考虑减少冲突的可能性
一个。试试@Martin Brown的建议。
湾如果你的while循环需要一些时间才能完成,你可以先为它创建一个本地临时表。仅在数据库邮件之前将输出转储到全局临时表。邮件发送后立即删除。