5

想象一下,我有一个包含整数列 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;

它有效,但令我震惊的是,可能有一种更优雅的方式来实现相同的结果(例如,这个提问者想要检查至少 1 个字段不为空,并且COALESCE关键字在这种情况下运行良好)。

4

2 回答 2

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”的错误。

于 2011-08-24T13:00:41.147 回答
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)) ;
于 2011-08-24T10:54:24.257 回答