SQL Server表:@、#和##之间有什么区别?

107
在SQL Server中,@表、#表和##表之间有什么区别?
6个回答

134

#table 指的是本地(仅创建它的用户可见)临时表。

##table 指的是全局(所有用户可见)临时表。

@variableName 指的是一个变量,它可以根据其类型来保存值。


40
你对 #table 的定义并不完全正确。它并不仅限于用户,而是连接。如果一个用户有多个连接,那么只有创建 #table 的连接才能看到它。 - Davin Studer
1
@DavinStuder提供了一个至关重要的澄清。用户可见表和仅在当前连接上可见表之间的区别非常重要。 - mirzmaster
1
@DavinStuder 如何查看一个用户的多个数据库连接?是否使用相同的连接字符串? - Kiquenet

27

5
我知道这是很久以前的事情了,但由于这是一个仅包含链接的答案(而且第一个链接已经失效),能否更新一下每个链接的主要要点呢? - Mike Guthrie

7
CREATE TABLE #t

创建一个只在当前连接上可见的表 同一个用户在另一个连接上创建连接时将无法从其他连接中看到表#t。
CREATE TABLE ##t

创建一个对其他连接可见的临时表。但是当创建连接结束时,该表将被删除。


SqlConnection.Open() 使用相同的连接字符串是否是同一个连接 - Kiquenet
2
不,这是与同一数据库的连接,但几乎肯定不是相同的连接。 - Markus

7

###表是在临时数据库中实际存在的表。这些表可以拥有索引和统计数据,并且可以在会话中跨过程访问(在全局临时表的情况下,它可以在会话之间使用)。

@table是一个表变量。

了解更多信息:http://www.sqlteam.com/article/temporary-tables


4
如果表变量的大小超出内存容量,它也将存在于tempDB数据库中。 - marc_s

5
我将专注于#table和@table之间的区别。##table是全局临时表,而在使用SQL Server的10多年中,我还没有遇到过有效的用例。我相信有些存在,但是对象的性质使其高度不可用,以我个人的看法。
@marc_s对@whiner的回应绝对是正确的:表变量总是驻留在内存中是一种普遍的错误观念。实际上,表变量经常会进入磁盘并像临时表一样运行。
无论如何,我建议通过按照@Astander指出的链接阅读差异集来了解差异的集合。大多数差异涉及您无法使用@table变量的限制。

我有5个单独的存储过程,执行不同部分的计算并输出单个结果。为了审计,我想查看中间值,审计员也是如此。我调整了我的过程,将一些内容转储到## Temp表中,以便我们都可以查看它们,但它们不会被保留(只在审计期间需要)。在我看来,这是一个有效的用例! - RyanfaeScotland
@Ryan,为什么你使用##Table而不是dbo.Table?我认为这并不是一个有效的用例,因为你只是省去了输入DROP语句的步骤。 - Aaron Bertrand
4
我不想在我的数据库上授予审计员DROP权限。此外,我也不想在他完成后回来整理。通过使用临时表,他可以随意运行查询,而我知道当他完成后并没有在数据库中留下任何痕迹。 - RyanfaeScotland

0
如果您需要一个唯一的全局临时表,请使用Uniqueidentifier前缀/后缀创建自己的表,并在执行后显式删除(使用if object_id(...))。唯一的缺点是需要使用动态SQL并需要显式删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接