2009-05-21 106 views
46

我已经阅读了临时表和范围的主题,并且我所看到的所有答案似乎都没有提及我的一个担忧。SQL Server 2005和临时表范围

我知道本地临时表的作用域只对存储过程或子存储过程的生存期有效。然而,在协调方面情况如何。即如果我有一个存储过程创建一个临时表,这是从两个不同的进程,但从相同的用户/连接字符串调用临时表,该临时表将在这两个调用存储过程之间共享,或将它的情况下每次调用存储过程都会创建一个唯一的临时表实例。

我会假设临时表属于调用存储过程的范围,但我想确保在我走下这条路径之前。

回答

76

本地临时表(以#开头)仅限于您的会话;其他会话(即使来自同一用户/连接字符串)也无法看到它们。生命周期的规则取决于本地临时表是否是在存储过程中创建的:

  • 过程结束时会删除在存储过程中创建的本地临时表;其他存储过程或调用进程无法看到它们。
  • 会话结束时会删除其他本地临时表。

会话之间共享全局临时表(以##开头)。

  • 创建它们的会话结束
  • ,没有其他会话指的是他们

这个命令可以很方便的看到哪个临时表存在:当它们被丢弃

select TABLE_NAME from tempdb.information_schema.tables 

如果您不确定它们是否存在,则可以方便地删除临时表:

if object_id('tempdb..#SoTest') is not null drop table #SoTest 

有关更多信息,请参阅此MSDN article

+0

+1这是一个很棒的答案。你能确认吗?如果一个存储过程从同一个连接字符串中被多次执行,那么后一个语句“if object_id ...”将确定在调用它的会话中是否存在一个临时表。我的理解是否正确?我知道会话不会知道临时表的存在,但我只是想知道`object_id`是否会返回基于会话的值。 – Legend 2013-05-22 19:45:43

+0

@Legend:`object_id`应该只能从你自己的会话中看到临时表。应该很容易测试。 – Andomar 2013-05-22 22:31:03

+0

+1是的,我自己也检查过。真的很感谢你的回应。谢谢。 – Legend 2013-05-22 22:44:25

11

的临时表将可以接触到程序的创建它

下面的脚本实例

Exec ('Select 1 as col Into #Temp Select * From #Temp') 
Exec ('Select 2 as col Into #Temp Select * From #Temp') 

返回

Col 
1 

Col 
2 

Col 
1 
2 

或者因为该表已存在而发生错误。

临时表也可以通过初始过程运行的任何“子”过程访问。

1

你也可以考虑使用表变量。他们有一个非常明确的范围,他们有时比临时表的同行更快。表变量的唯一问题是它们不能被索引,所以尽管它们的性质可能会丢失一些性能。 Check here了解有关该主题的更多信息。