2013-10-29 31 views
6

我有一个存储过程首先检查一个临时表(#temp_table),如果它存在,删除它,使用表,然后在完成后最后删除它。当用户做出某些事情来触发它时,这个SP会被随机地调用,并且很可能有时SP会在同一时间执行 - 或者有一些重叠。在MS SQL Server 2005中,当同一个SP的不同执行访问临时表时会发生什么?

假设我有Exec1和Exec2两个同样的SP创建,修改和删除#temp表,并且它们在毫秒内运行。

会发生什么?执行1结束时,Exec1会锁定#temp_table和Exec2等待吗?对我而言,这显然是可取的。我不希望两个Exec1 & 2同时使用该表,也不希望Exec2失败,因为Exec1已经在使用该表。

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

回答

5

在sql server中,如果你创建一个本地临时表,它带有一个#号sql server会在后端使用一些低于分数和一些ID。假设您在临时数据库中创建名称为#Temp sql的临时表创建一个名称为#Temp_______10912098的表,在单独连接中创建的每个临时表的名称末尾都会有它们的ID。


TempTables

这些都是临时表创建于不同的连接都有名字#Temp但也有一些下划线附加和unique id SQL Server使用区分它们。

+1

因此,在我的SP中,我有'IF OBJECT_ID('tempdb ..#temp_table')不为NULL \t DROP TABLE#temp_table' this does nothing nothing then?或者这可能会对其他执行产生不利影响? – jreed121

+2

如果您每次从新会话中调用它(例如从Web应用程序),则不需要这样做,因为临时表的范围仅限于会话。查看我的答案以获取更多信息。 –

+3

你不需要像Dommer说的那样,但是在尝试创建它之前,它总是一个检查OBJECT的存在的好习惯。在你的proc中保留这些代码。 –

4

临时表#table的范围仅限于您的会话,所以它不应该是一个问题。

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

在这里看到:MSDN SQL Tables

具体该位:

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

3

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

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

如果你看看tempdb,你可以看到这个。将会有多个名为#748B826C的表格。这些实际上是临时表变量,如declare @t table (ix int identity primary key)和带有散列的临时表名。

所以提供这些是不同的连接,而不是递归触发器,应该没有问题。

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

相关问题