问题描述
我正在尝试在2列上添加唯一约束,该约束允许多个(null,null)
,但不允许多个("a",null)
。我编写了以下sql语句,但出现错误
关键字“ with”附近的语法不正确
sql语句:
CREATE UNIQUE NONCLUSTERED INDEX [UQ]
ON [dbo].[MyTable] ([Column_A],[Column_B])
WHERE [Column_A] IS NOT NULL OR [Column_B] IS NOT NULL
WITH (PAD_INDEX = OFF,STATISTICS_norECOmpuTE = OFF,SORT_IN_TEMPDB = OFF,IGnorE_DUP_KEY = OFF,DROP_EXISTING = OFF,ONLINE = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY];
但是在
WHERE [Column_A] IS NOT NULL OR [Column_B] IS NOT NULL
当我将OR
替换为AND
时,就不再有语法错误。但是我想要的是OR
逻辑,而不是AND
,因为使用AND
允许多个("a",null)
条目。
那么为什么使用OR
会出现不正确的语法错误?谢谢。
解决方法
这有点笨拙,但是如果要强制执行唯一性(NULL / NULL除外)并且您很高兴拥有两个索引,则可以通过将NOT NULL过滤器放在单独的索引上来实现,例如,
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_A] ON [dbo].[MyTable]
(
[Column_A],[Column_B]
)
WHERE [Column_A] IS NOT NULL
GO
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_B] ON [dbo].[MyTable]
(
[Column_A],[Column_B]
)
WHERE [Column_B] IS NOT NULL
GO
虽然不必进行唯一性检查,但您可能希望更改第二个索引中字段的顺序,以潜在地获得索引的其他优点(取决于在应用程序中如何使用这些字段-可能会更好在第一个索引中交换它们),例如
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_B] ON [dbo].[MyTable]
(
[Column_B],[Column_A]
)
WHERE [Column_B] IS NOT NULL
GO
,
根据马丁·史密斯(Martin Smith)的评论,我认为我可以通过以下方式实现它:
CREATE VIEW [dbo].[TableAView]
WITH SCHEMABINDING AS
SELECT
[ColumnA] = [ColumnA],[ColumnB] = [ColumnB]
FROM [dbo].[TableA]
WHERE [ColumnA] IS NOT NULL OR [ColumnB] IS NOT NULL;
GO
CREATE UNIQUE CLUSTERED INDEX
[UQ] ON [dbo].[TableAView]
(
[ColumnA],[ColumnB]
)
WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,SORT_IN_TEMPDB = OFF,IGNORE_DUP_KEY = OFF,DROP_EXISTING = OFF,ONLINE = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];
GO