Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 脚本并行运行时,为临时表创建PK失败_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql server 脚本并行运行时,为临时表创建PK失败

Sql 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

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

.... 选择从…变成临时工。。。。 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 KEY


如果是第一个-在并行操作中使用键之前,必须先创建表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,即使在本地临时表中也是如此。