首页 > 解决方案 > 是否可以通过索引强制执行此业务规则?

问题描述

考虑下表:

ID, Name
==============
1, 'Name1'
1, 'Name1'
1, 'Name1'
2, 'Name2'
2, 'Name2'

尝试插入 (3, 'Name2') 应该会失败,因为具有相同 Name 值的行应该始终具有相同的 ID 值。

这可以通过索引强制执行吗?我知道它可以通过触发器或约束来强制执行,但这两个似乎都是相当不雅的解决方案。

请注意,这个问题源于真实(更复杂)的业务逻辑,我简化为这个示例以保持简单。

标签: sql-servertsql

解决方案


是的,它可以通过索引强制执行。

虽然不是基表上的索引。您可以在 上创建视图选择和分组ID, Name

然后使用键列在该视图上创建唯一索引Name


CREATE TABLE dbo.YourTable
  (
     ID   INT,
     Name VARCHAR(10)
  );

GO

CREATE VIEW dbo.SomeView
WITH SCHEMABINDING
AS
  SELECT count_big(*) AS c,
         ID,
         Name
  FROM   dbo.YourTable
  GROUP  BY ID,
            Name

GO

CREATE UNIQUE CLUSTERED INDEX SomeIndex
  ON dbo.SomeView(Name)

GO
---SUCCEEDS
INSERT INTO dbo.YourTable
VALUES      (1,'Name1'),
            (1, 'Name1'),
            (1, 'Name1'),
            (2, 'Name2'),
            (2, 'Name2');

GO

---FAILS
INSERT INTO dbo.YourTable
VALUES      (3,
             'Name2'); 

推荐阅读