6

我有一个存储过程,它首先检查临时表(#temp_table),如果它存在则删除它,使用该表,然后在完成后最终将其删除。当用户执行某些操作来触发它时,该 SP 会被随机调用,并且有时 SP 可能会同时执行 - 或有一些重叠。

假设我有同一个 SP 的 Exec1 和 Exec2 创建、更改和删除 #temp 表,并且它们彼此运行在几毫秒内。

发生什么了?Exec1 会锁定 #temp_table 并且 Exec2 会在 Exec1 完成时等待吗?在我的情况下,这显然是可取的。我不希望 Exec1 和 2 同时使用该表,也不希望 Exec2 失败,因为 Exec1 已经在使用该表。

[编辑] 我应该将我的临时表转换为表变量吗?

4

3 回答 3

5

在 sql server 中,如果您创建一个本地临时表,它带有一个 # 符号 sql server 在后端使用一些下划线和一些 ID。假设您#Temp在 temp db 中创建了一个名为 sql server 的 Temp 表,创建了一个名为 name 的表#Temp_______10912098,在单独的连接中创建的每个 Temp 表都将在名称的末尾有其 on ID。


临时表

这些是在不同连接中创建的所有临时表都具有名称#Temp,但附加了一些下划线,并且unique idsql 服务器用于区分它们。

于 2013-10-29T23:23:02.557 回答
4

临时表的范围#table仅限于您的会话,因此应该不是问题。

如果您使用 a ##table,那么这是全球性的,您会遇到问题。

请参阅此处:MSDN SQL 表

特别是这一点:

如果数据库会话创建本地临时表#employees,则只有会话可以使用该表,并在会话断开时将其删除。如果创建全局临时表 ##employees,数据库中的任何用户都可以使用该表。如果在您创建该表后没有其他用户使用该表,则该表会在您断开连接时被删除。如果其他用户在您创建该表后使用它,则 SQL Server 会在您断开连接并且所有其他会话不再主动使用它之后将其删除。

于 2013-10-29T23:21:03.423 回答
3

以散列命名的临时表#特定于单个连接。

因此,如果两个连接(也称为“进程”或“SPID”)都引用同一个临时表,#tablename它们实际上将引用不同的表。

如果您查看 tempdb,您可以看到这一点。将有多个表命名为#748B826C. 这些实际上是临时表变量,例如declare @t table (ix int identity primary key)带有哈希的临时表名称。

因此,如果这些是不同的连接而不是递归触发器,则应该没有问题。

但是,如果您担心递归触发器的可能性,您应该改用表变量。这些仅限于批处理或存储过程的范围。

于 2013-10-29T23:24:09.297 回答