使用触发器在 SQL 服务器中具有复杂条件的 table 上创建唯一过滤索引
Create unique filtered index on a table with complex conditions in SQL Server using Triggers
请考虑此代码:
CREATE UNIQUE NONCLUSTERED INDEX [idx1]
ON dbo.Table1 ([Year] ASC,
[City] ASC,
[Region] ASC,
[Sequence] ASC)
WHERE [Region] IN (1, 20)
AND [City] NOT LIKE N'C_341%'
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]
问题是,似乎无法创建具有复杂条件的过滤索引。我得到这个错误:
Incorrect syntax near the keyword 'LIKE'
有什么方法可以在 SQL 服务器中的那些列上创建唯一性(例如使用 TRIGGER
?
谢谢
Filtered indexes are defined on one table and only support simple comparison operators. If you need a filter expression that references multiple tables or has complex logic, you should create a view.
基于 documentation 不支持 LIKE 运算符。检查这部分
[comparison] ::=
column_name [comparison_op] constant
[comparison_op] ::=
{ IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< }
其他答案已经指出过滤索引不支持LIKE
。所以我将专注于强制唯一性的替代方法。是的,您可以使用触发器执行此操作。您需要定义插入后和更新后触发器。您必须在其中检查 table 的内容,请记住使用此语句插入的行(它们可以不止一个)已经存在。如果检测到重复值,则回滚事务并引发错误。触发器的代码可能如下所示(假设 ID 是您的主键字段,这将使我们能够识别新插入的记录):
CREATE TRIGGER [FORCE_UNIQUENESS] on [dbo].[Table1]
INSTEAD OF INSERT, UPDATE
AS
BEGIN
if exists(select *
from dbo.Table1 t
inner join inserted i on
i.[Year] = t.[Year] and
i.[City] = t.[City] and
i.[Region] = t.[Region] and
i.[Sequance] = t.[Sequance] and
t.ID <> i.ID
where i.Region in (1, 20) and i.[City] NOT LIKE N'C_341%')
begin
ROLLBACK TRANSACTION
RAISERROR('Duplicated values detected', 16, 1);
end
END
您可以创建 INSTEAD OF 触发器而不是引发错误。在这种情况下,触发器将负责实际将数据保存在 table 中。您可以决定插入所有行、部分行或其中的 none,以引发错误,或静默跳过重复值等。
请考虑此代码:
CREATE UNIQUE NONCLUSTERED INDEX [idx1]
ON dbo.Table1 ([Year] ASC,
[City] ASC,
[Region] ASC,
[Sequence] ASC)
WHERE [Region] IN (1, 20)
AND [City] NOT LIKE N'C_341%'
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]
问题是,似乎无法创建具有复杂条件的过滤索引。我得到这个错误:
Incorrect syntax near the keyword 'LIKE'
有什么方法可以在 SQL 服务器中的那些列上创建唯一性(例如使用 TRIGGER
?
谢谢
Filtered indexes are defined on one table and only support simple comparison operators. If you need a filter expression that references multiple tables or has complex logic, you should create a view.
基于 documentation 不支持 LIKE 运算符。检查这部分
[comparison] ::=
column_name [comparison_op] constant
[comparison_op] ::=
{ IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< }
其他答案已经指出过滤索引不支持LIKE
。所以我将专注于强制唯一性的替代方法。是的,您可以使用触发器执行此操作。您需要定义插入后和更新后触发器。您必须在其中检查 table 的内容,请记住使用此语句插入的行(它们可以不止一个)已经存在。如果检测到重复值,则回滚事务并引发错误。触发器的代码可能如下所示(假设 ID 是您的主键字段,这将使我们能够识别新插入的记录):
CREATE TRIGGER [FORCE_UNIQUENESS] on [dbo].[Table1]
INSTEAD OF INSERT, UPDATE
AS
BEGIN
if exists(select *
from dbo.Table1 t
inner join inserted i on
i.[Year] = t.[Year] and
i.[City] = t.[City] and
i.[Region] = t.[Region] and
i.[Sequance] = t.[Sequance] and
t.ID <> i.ID
where i.Region in (1, 20) and i.[City] NOT LIKE N'C_341%')
begin
ROLLBACK TRANSACTION
RAISERROR('Duplicated values detected', 16, 1);
end
END
您可以创建 INSTEAD OF 触发器而不是引发错误。在这种情况下,触发器将负责实际将数据保存在 table 中。您可以决定插入所有行、部分行或其中的 none,以引发错误,或静默跳过重复值等。