SQL Server检查约束逻辑

时间:2016-07-28 10:42:12

标签: sql-server sql-server-2014

我有一张有这种结构的桌子:

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约束。是否有更优雅的方式来做到这一点?

2 个答案:

答案 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