Sql 编写检查约束的更好方法是检查一个值是否不为null
假设我有一个包含整数列Col1、Col2、Col3、Col4的表。每列都可以为空,有效行必须正好包含1列中的值(即,所有空值都无效,超过1列也无效) 目前,我有一个这样的检查约束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
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方法的行为会是什么——这让我感到惊讶。