我正在使用SQL Server 2000,它的许多存储过程广泛使用临时表。数据库的流量很大,我担心创建和删除临时表的线程安全性。
假设我有一个存储过程,它创建了几个临时表,甚至可以将临时表连接到其他临时表等。并假设两个用户同时执行该存储过程。
是否可能一个用户运行存储过程并创建名为#temp的临时表,而另一个用户运行同样的存储过程但因为数据库中已经存在名称为#temp的表而被停止?
如果同一用户在同一连接上执行同一存储过程两次呢?
是否存在其他奇怪的情况可能会导致两个用户的查询互相干扰?
我正在使用SQL Server 2000,它的许多存储过程广泛使用临时表。数据库的流量很大,我担心创建和删除临时表的线程安全性。
假设我有一个存储过程,它创建了几个临时表,甚至可以将临时表连接到其他临时表等。并假设两个用户同时执行该存储过程。
是否可能一个用户运行存储过程并创建名为#temp的临时表,而另一个用户运行同样的存储过程但因为数据库中已经存在名称为#temp的表而被停止?
如果同一用户在同一连接上执行同一存储过程两次呢?
是否存在其他奇怪的情况可能会导致两个用户的查询互相干扰?
对于第二种情况,是的,您会收到此错误,因为该表已经存在,并且该表的持续时间与连接一样长。如果是这种情况,则建议在尝试创建它之前检查表的存在性。在存储过程中创建的本地临时表在存储过程完成时会自动删除。该表可以由由创建表的存储过程执行的任何嵌套存储过程引用。不能由调用创建表的存储过程的进程引用该表。
本地范围的临时表(只有一个#)在其末尾创建了一个标识符,使它们成为唯一的;多个调用者(即使使用相同的登录)永远不应该重叠。
(试试:从两个连接和相同的登录创建相同的临时表。然后查询tempdb.dbo.sysobjects以查看实际创建的表...)
#TMP
)。CREATE PROCEDURE myProc(@n INT)
AS BEGIN
RAISERROR('running with (%d)', 0, 1, @n);
CREATE TABLE #TMP(n INT);
INSERT #TMP VALUES(@n);
INSERT #TMP VALUES(@n * 10);
INSERT #TMP VALUES(@n * 100);
WAITFOR DELAY '00:00:30';
SELECT * FROM #TMP;
END;
只存在于当前上下文中。请不要将上下文与当前连接混淆。
如果您所描述的工作原理,则应在同一会话内多次调用该过程而不会出现问题,只要相关的本地临时表是在该过程的上下文中创建的,而不是在该过程之外? - BenCREATE TABLE #T (Col1 INT)
SELECT * FROM tempdb.sys.tables WHERE [name] LIKE N'#T%';
临时表与会话绑定,因此如果不同用户同时运行您的过程,则不会发生冲突...
临时表只在创建它们的查询或过程的上下文中创建。每个新查询都会在数据库上获得一个无其他查询临时表的上下文。因此,名称冲突不是问题。
如果你查看temps数据库,你可以看到临时表,它们具有系统生成的名称。因此,除了常规死锁之外,你应该没问题。
除非您使用两个井号##temp,否则临时表将是本地的,并且仅存在于用户与本地连接之间。