无法使用 IGNORE_DUP_KEY = ON 创建 UNIQUE 过滤索引

Man*_*man 3 sql-server duplication sql-server-2012 filtered-index unique-constraint

我有一个表,在 SQL Server 2012 企业版中,我想要一个唯一的索引IGNORE_DUP_KEY = ON,但是我只希望这个索引(并忽略重复项)仅应用于表的一个子集 - 仅带有FLAG = 1.

CREATE TABLE [dbo].[FOO]
([ID] NOT NULL,
[Value] [int] NULL,
[FLAG] [bit] NULL)
Run Code Online (Sandbox Code Playgroud)

尝试使用以下查询创建索引时

CREATE UNIQUE NONCLUSTERED INDEX [IDX_UQ_FL_FOO_VALUE] ON [dbo].[FOO]
([Value] ASC)
WHERE [flag] = 1
WITH (IGNORE_DUP_KEY = ON)
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

消息 10618,级别 16,状态 1,第 1 行无法在表 'dbo.FOO' 上创建过滤索引 'IDX_UQ_FL_FOO_VALUE',因为该语句将 IGNORE_DUP_KEY 选项设置为 ON。重写该语句,使其不使用 IGNORE_DUP_KEY 选项。

不能将过滤的唯一索引与IGNORE_DUP_KEY = ON?

将索引设置为非唯一不是一个选项。我需要它是唯一的来过滤重复的插入,但仅当插入带有FLAG = 1. 我需要忽略重复行的插入,而不是失败。

And*_*y M 6

正如另一个答案已经提到的,过滤索引不支持 IGNORE_DUP_KEY,这在手册中明确说明

过滤索引不允许 IGNORE_DUP_KEY 选项。

但是,如果您负担得起对表结构的小幅更改,则有一种解决方法。在 uniquifier 列的帮助下,您可以创建一个唯一索引,该索引将有效地允许您Value仅对带有FLAG = 1.

下面假设 ID 列已经声明为唯一的(要么是主键,要么对其具有 UNIQUE 约束)。首先,添加一个计算列,该列将对FLAG = 1行和ID所有其他行计算为 NULL :

ALTER TABLE dbo.FOO
ADD Uniquifier AS CASE FLAG WHEN 1 THEN NULL ELSE ID END;
Run Code Online (Sandbox Code Playgroud)

现在您可以(Value, Uniquifier)使用以下IGNORE_DUP_KEY选项创建唯一索引:

CREATE UNIQUE NONCLUSTERED INDEX UQ_1
ON dbo.FOO (Value, Uniquifier)
WITH (IGNORE_DUP_KEY = ON);
Run Code Online (Sandbox Code Playgroud)

由于Uniquifier对于带有 的行将是 NULL FLAG = 1,唯一性将根据Value单独确定。所有其他行都将是唯一的,无论Value因为Uniquifier是唯一的(因为它的值取自唯一的列,ID)。

SQL Fiddle提供了该方法的现场演示。