Wes*_*all 9 sql-server stored-procedures temporary-tables
我有一个关于我最近在TechNet 上阅读的有关临时表的文档的问题。该页临时表部分的第四段内容如下:
如果使用命名约束创建临时表,并且临时表是在用户定义的事务范围内创建的,则一次只有一个用户可以执行创建临时表的语句。例如,如果一个存储过程创建了一个带有命名主键约束的临时表,则该存储过程不能被多个用户同时执行。
我在这样一个环境中工作,在这种环境中,我们大量使用了一些使用索引临时表的存储过程,而且我们从未遇到过用户必须等待一次执行完成才能开始下一次执行的问题。我希望情况会继续如此,但我担心如果没有正确理解这个警告,它可能会成为一个问题。
具体来说,我不清楚以下几点:
Eri*_*ing 11
这适用于本地临时表。
命名约束和未命名约束的区别在于:
CREATE TABLE #t1 (c1 INT PRIMARY KEY CLUSTERED)
CREATE TABLE #t2 (c1 INT,
CONSTRAINT pk_c1 PRIMARY KEY CLUSTERED(c1) )
Run Code Online (Sandbox Code Playgroud)
让系统名称约束使得发生冲突的可能性极小。在此示例中,如果您在 SSMS 中打开两个窗口,您将能够在两个窗口中创建#t1
,但不能在#t2
.
全局临时表由所有用户共享,因此您必须以不同的方式处理事情。在使用它们的最后一个会话完成之前,它们不会被“破坏”,因此您需要确保当用户访问它们时,他们只能访问他们的数据。这有时由 SPID 完成,有时由散列值完成。这取决于如何使用全局临时表。
通常,对于全局临时表,存储过程将检查如果它们存在,然后只创建它们如果OBJECT_ID()
是NULL
。
多个用户意味着多个会话。登录名与它无关。如果 George 运行sp_something @i = 1
并且 Gina 运行sp_something @i = 2
,则它们是否都以 身份登录并不重要User1
,它们将具有不同的 SPID。
Joe*_*ish 10
我认为这是因为您不能在tempdb.sys.key_constraints
. 这是我的一台服务器上的元数据视图中的内容:
所有以 结尾的奇怪名称_6E...
都是 SQL Server 自动生成的名称。它们不是命名约束,因为我在创建它们时没有明确给它们命名。SQL Server 在幕后生成一个约束名称,理论上可以避免名称冲突。
如果我尝试在两个不同的会话中创建下表:
create table #x1 (
ID INT NOT NULL,
CONSTRAINT NAMED_CONSTRAINT_1 PRIMARY KEY (ID)
);
Run Code Online (Sandbox Code Playgroud)
第二个运行的会抛出一个错误:
Msg 2714, Level 16, State 5, Line 1
数据库中已经有一个名为“NAMED_CONSTRAINT_1”的对象。
消息 1750,级别 16,状态 1,第 1 行
无法创建约束或索引。请参阅以前的错误。
再次检查视图:
如果我尝试在两个会话中创建下表,则没有问题:
create table #y1 (
ID INT NOT NULL,
PRIMARY KEY (ID)
);
Run Code Online (Sandbox Code Playgroud)
这是元数据视图:
只是直接回答您的问题:您引用的部分适用于本地和全局临时表,命名约束是您故意为其命名的约束,多个用户意味着多个会话。