Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 编写检查约束的更好方法是检查一个值是否不为null_Sql_Sql Server_Check Constraints - Fatal编程技术网

Sql 编写检查约束的更好方法是检查一个值是否不为null

Sql 编写检查约束的更好方法是检查一个值是否不为null,sql,sql-server,check-constraints,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

假设我有一个包含整数列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;

它是有效的,但我觉得可能有一种更优雅的方法来实现相同的结果(例如,我想检查至少一个字段是否为空,并且在这种情况下,
COALESCE
关键字工作正常)。

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

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)) ;

在这里重复另一个答案,我认为这是一个更自我记录的问题:

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”。

对于我来说,您的约束比公认的答案更清晰。不管怎样,我认为有一种设计问题的味道:表可能没有完全规范化?也许真实的列名会提供更多的线索(希望这些不是真实的名字!)我也喜欢你的方式Ben(尽管你需要将“IsNull”改为“IsNotNull”)。就个人而言,我更喜欢Martin的答案,但我团队的其他成员不同意。如果他们不同意,请他们对10列进行案例分析,其中2列可以为非空。这种风格的方法在开发工作中具有良好的伸缩性。另一个没有。此外,我的回答已经针对需求进行了编辑。就我个人而言,我更喜欢这种检查约束,而不是我发布的(冗长的)检查,但刚刚对我小组中的其他开发人员进行了一次草草调查,响亮的回答是没有人确定ISNULL方法的行为会是什么——这让我感到惊讶。