编写CHECK CONSTRAINT的一种更好的方法,它检查确切的一个值不为null

时间:2011-08-24 10:45:35

标签: sql sql-server check-constraints

想象一下,我有一个包含整数列Col1,Col2,Col3,Col4的表。每列都可以为空,有效行必须包含恰好1列的值(即所有空值无效且多于1列也无效)。

目前我有像这样的支票限制

ALTER TABLE [dbo].[MyTable]  WITH CHECK 
    ADD CONSTRAINT [CK_ReportTemplateAttributes] CHECK  
    ((
        [Col1] IS NOT NULL AND [Col2] IS NULL AND [Col3] IS NULL AND [Col4] IS NULL
        OR 
        [Col1] IS NULL AND [Col2] IS NOT NULL AND [Col3] IS NULL AND [Col4] IS NULL
        OR 
        [Col1] IS NULL AND [Col2] IS NULL AND [Col3] IS NOT NULL AND [Col4] IS NULL
        OR 
        [Col1] IS NULL AND [Col2] IS NULL AND [Col3] IS NULL AND [Col4] IS NOT NULL
    ));
GO;

它有效,但令我印象深刻的是,可能有一种更优雅的方式来实现相同的结果(例如this questioner想要检查至少1个字段不为空且COALESCE关键字有效在那种情况下)。

2 个答案:

答案 0 :(得分:9)

对于这里的另一个答案,我认为这是一个更自我记录:

ALTER TABLE [dbo].[MyTable]  WITH CHECK 
ADD CONSTRAINT [CK_ReportTemplateAttributes] CHECK  
(1 = CASE when [Col1] IS NULL THEN 0 ELSE 1 END + 
     CASE when [Col2] IS NULL THEN 0 ELSE 1 END + 
     CASE when [Col3] IS NULL THEN 0 ELSE 1 END + 
     CASE when [Col4] IS NULL THEN 0 ELSE 1 END ) ;

它还有一个好处,即可以避免更改约束以考虑其他列的错误,但忘记将“3”更新为“[约束中的列数] - 1”。

答案 1 :(得分:7)

目前我能想到的最简洁的方式是。

ALTER TABLE [dbo].[MyTable]  WITH CHECK 
ADD CONSTRAINT [CK_ReportTemplateAttributes] CHECK  
(3 = ISNULL([Col1] - [Col1],1) + 
     ISNULL([Col2] - [Col2],1) + 
     ISNULL([Col3] - [Col3],1) + 
     ISNULL([Col4] - [Col4],1)) ;