2016-07-28 77 views
0

我已经得到了具有此类结构的表:SQL Server的检查约束逻辑

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。在我的例子第二和第三行不会通过这个。

我可以创建一个自定义函数来验证它,并使其约束CHECK。有没有更好的方法来做到这一点?

+0

我已经回答了,但现在我不那么肯定它是有效的。你是说你只想要一行存在'ApplicationID'为-1的地方吗? – DavidG

+0

@DavidG正确的,可以有多行“ProductID”/“CountryID”组合与除-1之外的其他ApplicationID组合。 –

+0

我认为我的编辑现在可以做到这一点。 – DavidG

回答

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的任何记录,马克计算的东西= 0此!是你的违规规则。

+0

这似乎是正确的,不像我希望的那样优雅,但却完成了这项工作。 –

0

你可以只使用一个唯一的Filtered Index

CREATE UNIQUE INDEX IX_UniqueNegativeApp ON Mine(ProductID, CountryID) WHERE ApplicationID = -1