Reputation: 9630
I have a table with two columns (amongst others):
NotApplicable bit
TargetLevel numeric(5,2)
I need to create a constraint whereby the following rules apply:
I guess this is an exclusive OR scenario? I had a go a while back, but I realised now that this doesn't account for the last scenario above:
ALTER TABLE [dbo].[my_Table] ADD CONSTRAINT [DF_tbl_my_Table_notApplicable] DEFAULT ((0)) FOR [notApplicable]
GO
ALTER TABLE [dbo].[my_Table] WITH CHECK ADD CONSTRAINT [CK_tbl_my_Table] CHECK ((COALESCE([targetLevel],[notapplicable]) IS NOT NULL))
GO
ALTER TABLE [dbo].[my_Table] CHECK CONSTRAINT [CK_tbl_my_Table]
GO
Any help perfecting this would be appreciated. Also, is the last ALTER statement actually needed in the example above please?
Upvotes: 3
Views: 1502
Reputation: 1155
An alternative syntax for the two column scenario is:
ALTER TABLE T ADD CONSTRAINT CK_One_Or_Tother CHECK (
(NotApplicable IS NULL OR TargetLevel IS NULL)
AND (NotApplicable IS NOT NULL OR TargetLevel IS NOT NULL)
)
Upvotes: 0
Reputation: 239664
It's a bit verbose, but the standard way I do it is just:
ALTER TABLE T ADD CONSTRAINT CK_One_Or_Tother CHECK (
(NotApplicable IS NULL and TargetLevel IS NOT NULL) OR
(NotApplicable IS NOT NULL and TargetLevel IS NULL)
)
Also, is the last ALTER statement actually needed in the example above please?
ALTER TABLE [dbo].[my_Table] CHECK CONSTRAINT [CK_tbl_my_Table]
This is only necessary if you have ever created or altered the constraint and specified NOCHECK
, or have in some other way disabled the constraint previously and now enabled it. The default for creation of constraints is for them to be enabled.
For a large number of columns, for which exactly one must be filled in, I tend to switch to an alternative structure:
ALTER TABLE T ADD CONSTRAINT CK_One_Or_Tother CHECK (
1 = (
CASE WHEN ColumnA IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN ColumnB IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN ColumnC IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN ColumnD IS NOT NULL THEN 1 ELSE 0 END
)
)
Which has the advantage of only naming each column once, but can look a bit ugly.
Upvotes: 8