你可以使用标量UDF来实现,但在检查约束中使用这些函数已有充分的文档说明问题(例如,参见包装在CHECK约束中的标量UDF非常慢,可能在多行更新时失败或快照隔离:对完整性的威胁?系列)。
还可以通过创建一个索引视图来让数据库引擎来执行这个约束。
它需要一个帮助表格,其中有两行,因为CTE和UNION
在索引视图中是不被允许的。这个视图定义总是返回零行,如果有违反唯一约束条件的情况,则会将返回的任何行都加倍。从而导致视图上的唯一约束出现违规,并导致发生错误并使语句失败。
CREATE TABLE dbo.TwoNums
(
Num INT PRIMARY KEY
)
INSERT INTO dbo.TwoNums
VALUES (1),
(2)
然后是视图定义。
CREATE VIEW dbo.PreventOverCapacity
WITH SCHEMABINDING
AS
SELECT V.Venueid,
E.EventId,
E.Expected,
V.Capacity
FROM dbo.Venues V
JOIN dbo.Events E
ON E.venueid = V.venueid
AND E.Expected > V.Capacity
CROSS JOIN dbo.TwoNums
在视图上创建唯一索引
CREATE UNIQUE CLUSTERED INDEX [UIX_PreventOverCapacity (Venueid, EventId, Expected, Capacity)]
ON dbo.PreventOverCapacity(Venueid, EventId, Expected, Capacity)
包含所有四列的原因是为了在错误信息中显示所有所需的值。
无法将重复键行插入到对象'dbo.PreventOverCapacity'中,因为它具有唯一索引'UIX_PreventOverCapacity (Venueid, EventId, Expected, Capacity)'。
重复键值为(1, 97, 110, 100)。
events
表上构建一个触发器,检查venues
表并引发错误/回滚无效值。 - Nick.McDermaid