Sql server 脚本并行运行时,为临时表创建PK失败
我在存储过程中有以下代码 .... 选择从…变成临时工。。。。 alter table temp add constraint PK_mytemp13主键。。。。 .... 如果存储过程并行运行,我将不时收到以下错误消息 数据库中已存在名为“PK_perf322dsf”的对象。 无法创建约束。请参阅前面的错误 我认为可以通过以下方法避免。还有其他更优雅的解决方案吗 首先使用主键创建临时表。然后插入行。 创建表温度。。。主键 使用会话id动态创建PK。 声明@s varchar500='alter table temp add constraint PK_temp'+@@spid+'主键 您尝试从不同的连接插入同一临时表,而不是从全局临时表插入,这是不可能的, 或者尝试插入到不同的表中。 如果是第二个-您只需执行以下操作-ALTER TABLE temp ADD PRIMARY KEYSql server 脚本并行运行时,为临时表创建PK失败,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我在存储过程中有以下代码 .... 选择从…变成临时工。。。。 alter table temp add constraint PK_mytemp13主键。。。。 .... 如果存储过程并行运行,我将不时收到以下错误消息 数据库中已存在名为“PK_perf322dsf”的对象。 无法创建约束。请参阅前面的错误 我认为可以通过以下方法避免。还有其他更优雅的解决方案吗 首先使用主键创建临时表。然后插入行。 创建表温度。。。主键 使用会话id动态创建PK。 声明@s varchar500='alter
如果是第一个-在并行操作中使用键之前,必须先创建表REQUALE或global TEMPORATION with key,只有在相同的客户端连接实例化(相当于SQL Server中的一个SPID或连接)被重复用于两个不同的调用时,才会发生这种情况。两个并行调用应具有不同的连接实例化和单独的SPID SPID通过本地单温度表彼此完全隔离 编辑: 忽略上面 我以前从未在临时表上命名过约束。我根据需要使用索引,或者只是在列后面添加主键。约束名称在sys.objects中是数据库唯一的 PK基本上是一个非唯一的聚集索引。因此,请改用创建唯一聚集索引,因为sys.indexes中每个表的索引名都是唯一的 在2个SSMS查询窗口中运行时,此操作失败
CREATE TABLE #gbn (foo int NOT NULL);
ALTER TABLE #gbn ADD CONSTRAINT PK_gbn PRIMARY KEY (foo);
Msg 2714,第16级,第5状态,第2行
数据库中已存在名为“PK_gbn”的对象。
Msg 1750,第16级,第0状态,第2行
无法创建约束。请参阅前面的错误
奇怪的是,错误和约束名称的匹配与您的错误不同
这很有效
CREATE TABLE #gbn (foo int NOT NULL);
CREATE UNIQUE CLUSTERED INDEX PK_gbn ON #gbn (foo);
我试图记住如何执行此操作,但您可以在临时表上创建一个无名主键并避免此错误。这与放置列级PK不同,因为它支持多个列。以下是一个例子:
CREATE TABLE #test
(
AccountNumber INT NOT NULL,
TransactionNumber INT NOT NULL,
PRIMARY KEY CLUSTERED (tranid, sys_process_dt)
);
这允许最终目标加上防止名称重复。查询将显示SQL Server将在sys.sysobjects中为您的PK名称中放置GUID:
SELECT *
FROM tempdb.sys.sysobjects
WHERE name LIKE '%#test%'
名称| xtype
----------------
测试…\u000000000 407 | U
PK_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuub88a05a770b3a6a6|PK
你也可以吃蛋糕。我知道这个问题已经得到了回答和接受,但仍然没有看到正确的观点已经被提出
创建命名约束时,约束的名称必须在表级别精确。它们的作用域在数据库级别。所以,要么不要创建命名约束,让sql选择它自己的名称,要么如果您指定名称,请确保它在该数据库中是唯一的。即使对于TEMP DB.更重要的是,TEMP表上的任何命名约束都必须在会话中唯一命名。这也意味着默认约束—如果您将字段设置为默认值-1,并且默认约束已显式命名,则当您尝试在另一个会话窗口中创建临时表时,SQL Server将抛出错误,即使该临时表不是键约束 例如,打开两个查询窗口,在其中一个窗口中运行以下代码,然后在另一个窗口中运行以下代码,而不首先关闭任何一个窗口:
DROP TABLE IF EXISTS #TempTbl1;
CREATE TABLE #TempTbl_1 (
[TestCol1] INT
,[TestCol2] BIGINT CONSTRAINT [DF_Tc2] DEFAULT (-1)
);
第一个窗口将正常执行,但第二个窗口将抛出一个错误
Msg 2714, Level 16, State 5, Line 2
There is already an object named 'DF_Tc2' in the database.
Msg 1750, Level 16, State 1, Line 2
Could not create constraint or index. See previous errors.
尽管该表没有PK或索引,只有一个命名的默认约束,但仍然存在这种情况。@MartinSmith:从错误中可以看出,约束名称被忽略。IIRC,当我在临时表上创建索引而不是PK时,会添加很多下划线和一些十六进制。我从未遇到过并发问题。我建议错误不在于临时表处理命名约束在tempdb中仍然必须唯一命名,因为它们在sys.objects中是唯一的。命名索引不必是。实际上,OP应该只使用唯一索引或未指定的约束。编辑:明白你对错误消息的意思了吧…@MartinSmith:刚刚验证过。请参阅更新。我从未想过在临时表上使用命名约束。始终对持久表执行此操作,尽管此错误与创建本地临时表、在代码块中生成命名主键以及调用该代码块的连接超过1个有关。SQL Server不允许2个具有相同名称的PK,即使在本地临时表中也是如此。