想象一下,我有一个包含整数列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
关键字有效在那种情况下)。
答案 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)) ;