我可以为主键设置 ignore_dup_key 吗?

48

我的一个表有一个由两列组成的主键。我尝试使用以下命令将其更改为将ignore_dup_key设置为开启:

ALTER INDEX PK_mypk on MyTable
SET (IGNORE_DUP_KEY = ON);

但我遇到了这个错误:

无法使用索引选项 ignore_dup_key 来更改索引 'PK_mypk',因为它强制执行主键或唯一约束条件。

我应该如何打开IGNORE_DUP_KEY呢?

6个回答

73
ALTER TABLE [TableName] REBUILD WITH (IGNORE_DUP_KEY = ON)

它与Postgresql-9.5不兼容,PSQL无法理解关键字IGNORE_DUP_KEY。是否有办法使其(或类似的东西)在Postgresql> = 9.5中工作? - Bhindi
5
不知道。这个问题被标记为SQL Server,所以尝试搜索类似的问题以寻找PostgreSQL的答案。 - Kvasi

34

《Books Online》没有提供文档,但我发现虽然IGNORE_DUP_KEY适用于主键,但您无法通过ALTER INDEX更改它; 您需要删除并重新创建主键。

请记住,IGNORE_DUP_KEY不能实际上在唯一索引中存储重复的行,它只是更改了在尝试时失败的方式:

开启(ON):当插入重复键值时,将出现警告消息到唯一索引。 仅违反唯一性约束的行将失败

关闭(OFF): 当插入重复键值时,将出现错误消息到唯一索引。 整个INSERT操作将回滚

来自http://msdn.microsoft.com/en-us/library/ms175132.aspx


6

3
您的命令将 'IGNORE_SUP_KEY' 关闭。您需要将其更改为 WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]。 - pedram bashiri

5

它决定了仅插入重复键时会发生什么。

请参见ALTER TABLE..index option

指定插入操作尝试将重复键值插入唯一索引时的错误响应。 IGNORE_DUP_KEY选项仅适用于在创建或重建索引后进行的插入操作。该选项在执行CREATE INDEX、ALTER INDEX或UPDATE时没有影响。

..并且不适用于PK

关于此问题以及“向后兼容性”的ALTER TABLE BOL评论有些令人困惑。我刚刚尝试了一下,BradC是正确的。

CREATE TABLE dbo.foo (bar int PRIMARY KEY WITH (FILLFACTOR=90, IGNORE_DUP_KEY = ON))
GO
INSERT dbo.foo VALUES (1)
GO
INSERT dbo.foo VALUES (1)
GO
--gives    
(1 row(s) affected)

Duplicate key was ignored.

(0 row(s) affected)

1
请注意,此设置仅影响如果您尝试插入重复键时会发生什么,它不允许您插入重复键。
如果您尝试插入重复键,则可以删除主键索引,插入记录,修复数据(删除重复项等),然后重新创建索引。

1
个人而言,我从不希望忽略重复项。如果有一个主键的重复值,它需要被修复。我不希望它被忽略并插入其他记录,因为这样用户可能会认为它们都已经被插入了。这个设置是对糟糕的插入过程的掩盖。一个设计良好的过程不需要这个设置,因为它在输入数据之前清理数据(或使用upsert更新现有数据并插入新数据),并将错误记录发送到一个表中,以便可以修复并重新插入,或者向用户返回错误信息,让他们知道他们的记录没有被插入。

3
我遇到了这个问题:我每天需要插入大量记录,目前是为每条记录执行一个插入命令。如果该记录已经存在,则通过抛出重复键错误来忽略它。从性能的角度来看,尝试插入并允许某些失败比在插入之前检查记录是否存在要好。提高性能的下一步是使用SqlBulkCopy进行插入,而不是为每条记录执行单个命令。但是,如果 ignore_dup_key 关闭,则无法将任何记录插入,因为整个批次都会失败。 - Mr. Flibble
1
如果我的主键中有一个列是用户定义的,该怎么办?如果我需要同时支持插入多个实体,比如1000个,那么在插入之前如何验证所有条目都是唯一的,而不会对服务器造成过大的负担?我认为在这种情况下,“忽略重复项”选项非常合适。你不同意吗? - julealgon
1
是的,如果您忽略重复项并且没有主键,那么您将不拥有主键,最终会遇到糟糕数据的问题。更好的做法是将数据放入暂存表中,然后使用选择语句仅插入新记录。我们就是用这种方式插入数百万条记录。 - HLGEM
2
以防万一其他人也遇到了这个问题:至少在我的情况下,IGNORE_DUP_KEY 的性能远不如使用 WHERE NOT EXISTS,所以请务必自行检查。 - CWagner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接