我有一张有这种结构的桌子:
CREATE TABLE #Mine
(
ProductID INT
, CountryID INT
, ApplicationID INT
);
我们假设它有如下数据:
ProductID CountryID ApplicationID
1 2 -1
1 3 -1
1 3 2
我想强制执行这样的逻辑,即整个表中没有其他ProductID
/ CountryID
组合(如果它与ApplicationID = -1
一起存在)。在我的例子中,第2行和第3行不会通过它。
我可以创建一个自定义函数来验证它并从中做出CHECK
约束。是否有更优雅的方式来做到这一点?
答案 0 :(得分:0)
我会拆分你的任务。首先,分配唯一约束(这可以是表键):
CREATE UNIQUE INDEX IX_UQ ON Mine(ProductId, CountryId, ApplicationId)
这是为了进行简单的验证并改进触发器查询。
其次,您的检查需要涉及许多记录(不能使用CHECK约束)。这是触发器的任务:
CREATE TRIGGER trMine
ON Mine FOR INSERT,UPDATE
IF (EXISTS(
SELECT Mark FROM
(
SELECT MAX(CASE WHEN M.ApplicationId=-1 THEN 1 ELSE 0 END)*(COUNT(*)-1) Mark
FROM Mine M
JOIN inserted I ON M.ProductId=I.ProductId AND M.CountryId=I.CountryId
GROUP BY M.ProductId,M.CountryId
) Q
WHERE Mark != 0
)) THROW 50000, 'Validation error', 1
当有2个或更多记录(COUNT(*) - 1> 0)并且有任何记录包含ApplicationId = -1时,Mark会评估某些内容!= 0.这是您的违规规则。
答案 1 :(得分:0)
您可以使用唯一Filtered Index:
CREATE UNIQUE INDEX IX_UniqueNegativeApp ON Mine(ProductID, CountryID) WHERE ApplicationID = -1