当脚本并行运行时,为#temp表创建PK失败

ca9*_*3d9 11 sql-server sql-server-2008

我在存储过程中有以下代码.

....
select ... into #temp from ....
alter table #temp add constraint PK_mytemp13 primary key (....)
....
Run Code Online (Sandbox Code Playgroud)

如果存储过程并行运行,我将不时收到以下错误消息.

数据库中已经有一个名为"PK_perf322dsf"的对象.无法创建约束.查看以前的错误.

我认为可以通过以下方法避免这种情况.还有其他更优雅的解决方案吗?

  1. 首先使用主键创建临时表.然后插入行.
    create table #temp (... primary key (....))

  2. 动态创建具有会话ID的PK.
    declare @s varchar(500) = 'alter table #temp add constraint PK_temp' + @@spid + ' primary key (....)

gbn*_*gbn 12

只有在相同的客户端连接实例化(等于SQL Server中的一个SPID或连接)被重用于2个不同的调用时,才会发生这种情况.两个并行调用应具有不同的连接实例和单独的SPID

SPID与本地(单个#temp表)完全隔离

编辑:

忽略上面

我以前从未在临时表上命名约束.我根据需要使用索引,或者只在列之后添加PRIMARY KEY.约束名称在sys.objects中是数据库唯一的

PK基本上是一个非唯一的聚簇索引.因此,请使用sys.indexes中的每个表的CREATE UNIQUE CLUSTERED INDEX索引名称是唯一的.

在2个SSMS查询窗口中运行时,此操作失败

CREATE TABLE #gbn (foo int NOT NULL);
ALTER TABLE #gbn ADD CONSTRAINT PK_gbn PRIMARY KEY (foo);
Run Code Online (Sandbox Code Playgroud)

消息2714,级别16,状态5,行2
数据库中已存在名为"PK_gbn"的对象.
消息1750,级别16,状态0,行2
无法创建约束.查看以前的错误.

奇怪的是,错误和约束名称匹配不同于您的错误

这有效

CREATE TABLE #gbn (foo int NOT NULL);
CREATE UNIQUE CLUSTERED INDEX PK_gbn ON #gbn (foo);
Run Code Online (Sandbox Code Playgroud)


CDC*_*CDC 10

我试图记住如何执行此操作,但您可以在临时表上创建无名主键并避免此错误.这与放置列级PK不同,因为它支持多于1列.这是一个例子:

CREATE TABLE #test
(
  AccountNumber INT NOT NULL,
  TransactionNumber INT NOT NULL,
  PRIMARY KEY CLUSTERED (tranid, sys_process_dt)
);
Run Code Online (Sandbox Code Playgroud)

这允许最终目标加上防止名称重复.查询将显示SQL Server将在sys.sysobjects中为您的PK名称添加GUID:

SELECT *
FROM tempdb.sys.sysobjects
WHERE name LIKE '%#test%'
Run Code Online (Sandbox Code Playgroud)

名字| 的xtype

--------------------------------

#test ___..._ 000000000407 | ü

PK __#test_____B88A05A770B3A6A6 | PK

你可以吃蛋糕,也可以吃.


Ole*_*Dok 4

  1. 您尝试从不同的连接插入到同一个临时表(这是不可能的,而不是全局临时表),
  2. 或者您尝试插入到不同的表中。

如果是第二个 - 您只需执行以下操作 - ALTER TABLE #temp ADD PRIMARY KEY(...)

如果是第一个 - 您必须先使用键创建表(常规或全局临时),然后才能在并行操作中使用它

  • 此错误与创建本地临时表、在代码块中创建命名主键以及调用该代码块的多个连接有关。SQL Server 不允许 2 个具有相同名称的 PK,即使在本地临时表中也是如此。 (4认同)