| Author |
Topic |
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 10:55:34
|
Hi allI keep getting an error when I run an INSERT command against a table. The error is as follows:The INSERT statement conflicted with the CHECK constraint "CK_tbl_UserTargetLevels". The conflict occurred in database "myDB", table "dbo.tbl_UserTargetLevels".[code]I can't see what's causing this, although it must be something really simple because I've been staring at it far too long. Please can anyone spot the problem with the insert? Here's the full code:[code]CREATE TABLE tbl_UserTargetLevels ( [ID] INT IDENTITY(1,1) PRIMARY KEY, userID int NOT NULL, sgsID int NOT NULL, targetLevel numeric(5, 2) NULL, notApplicable bit NULL )GO-- Set default bit column value to 0ALTER TABLE tbl_UserTargetLevels ADD CONSTRAINT DF_tbl_UserTargetLevels_notApplicable DEFAULT 0 FOR notApplicableGO-- Ensure that targetLevel and notApplicable are not both NULLALTER TABLE tbl_UserTargetLevels ADD CONSTRAINT CK_tbl_UserTargetLevels CHECK (notApplicable IS NULL AND targetLevel IS NULL)GOINSERT INTO tbl_UserTargetLevels (userID, sgsID, targetLevel, notApplicable) VALUES (1, 1, NULL, 1) -- ERROR!!GO |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2009-08-17 : 11:02:29
|
Your CHECK "...And targetLevel IS NULL" is being violated by your insert. You are passing "1" which is obviously not null EDIT:Odd - why create columns that you want to enforces are always NULL ???Be One with the OptimizerTG |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 11:18:06
|
quote: Originally posted by TG Your CHECK "...And targetLevel IS NULL" is being violated by your insert. You are passing "1" which is obviously not null EDIT:Odd - why create columns that you want to enforces are always NULL ???Be One with the OptimizerTG
Okay I'm still confused... I need to ensure that targetLevel and notApplicable are never NULL at the same time. Either one can be NULL on its own, but they cannot both be NULL. This is the first time I've written a constraint like this so my T-SQL is a bit rusty (to put it politely!). Based on your reply, should the code therefore read:ALTER TABLE tbl_UserTargetLevels ADD CONSTRAINT CK_tbl_UserTargetLevels CHECK (notApplicable IS NOT NULL AND targetLevel IS NOT NULL) |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 11:20:26
|
| Well no it shouldn't, because that isn't working either. So what should the CONSTRAINT actually say...?? |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-08-17 : 11:44:55
|
a few ways. here's 2CHECK (isnull(notApplicable, 1) + isnull(targetLevel, 1) < 2) CHECK ((notApplicable is not null) or (targetLevel is not null)) |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-08-17 : 11:48:38
|
if one must be null and the other not null (in which case it actually could have been one column) can do thisCHECK ((notApplicable is null) ^ (targetLevel is null)) |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 12:14:24
|
Thanks RussellYour suggestions did fix the problem, however, there is another part which I overlooked originally.The constraint should actually state that the columns cannot both be NULL at the same time, plus, they cannot both be NOT NULL at the same time!quote: in which case it actually could have been one column
I don't think that's possible in this instance. Both columns are containing values that are used for completely different functions within an application. Within the app though, the presence of one value stops the other being required. The app has code to catch this from happening, but I wanted to just give that little bit of extra security and get SQL Server to also watch for it happening (in case I edited the table directly, for example).So, would this work, or is there a much simpler way...?CHECK ((isnull(notApplicable, 1) + isnull(targetLevel, 1) <> 2) AND (isnull(notApplicable, 0) + isnull(targetLevel, 0) <> 0)) |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 12:32:26
|
| No that doesn't work either. I presume therefore I need to use two separate constraints to achieve this. I can't figure out how the both NOT NULL one would be written though... |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-08-17 : 12:39:16
|
quote: Originally posted by russell if one must be null and the other not null (in which case it actually could have been one column) can do thisCHECK ((notApplicable is null) ^ (targetLevel is null))
this way |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2009-08-17 : 13:16:09
|
So you are trying to inforce "mutual exclusivity" where exactly one value needs to be null while the other is not null.I got a syntax error with russell's solution (above).This works:use tempdbgoCREATE TABLE tbl_UserTargetLevels ( [ID] INT IDENTITY(1,1) PRIMARY KEY, userID int NOT NULL, sgsID int NOT NULL, targetLevel numeric(5, 2) NULL, notApplicable bit NULL )GO-- Set default bit column value to 0ALTER TABLE tbl_UserTargetLevels ADD CONSTRAINT DF_tbl_UserTargetLevels_notApplicable DEFAULT 0 FOR notApplicableGO-- Ensure that targetLevel and notApplicable are not both NULLALTER TABLE tbl_UserTargetLevels ADD CONSTRAINT CK_tbl_UserTargetLevels CHECK (coalesce(targetLevel, notapplicable) is not null and targetLevel + notapplicable is null) GOINSERT INTO tbl_UserTargetLevels (userID, sgsID, targetLevel, notApplicable) VALUES (1, 1, NULL, 1) INSERT INTO tbl_UserTargetLevels (userID, sgsID, targetLevel, notApplicable) VALUES (1, 1, 1.2, null) INSERT INTO tbl_UserTargetLevels (userID, sgsID, targetLevel, notApplicable) VALUES (1, 1, null, null) INSERT INTO tbl_UserTargetLevels (userID, sgsID, targetLevel, notApplicable) VALUES (1, 1, 2.1, 0) select * from tbl_UserTargetLevelsGOdrop table tbl_UserTargetLevelsOUTPUT:Msg 547, Level 16, State 0, Line 4The INSERT statement conflicted with the CHECK constraint "CK_tbl_UserTargetLevels". The conflict occurred in database "tempdb", table "dbo.tbl_UserTargetLevels".The statement has been terminated.Msg 547, Level 16, State 0, Line 5The INSERT statement conflicted with the CHECK constraint "CK_tbl_UserTargetLevels". The conflict occurred in database "tempdb", table "dbo.tbl_UserTargetLevels".The statement has been terminated.ID userID sgsID targetLevel notApplicable----------- ----------- ----------- --------------------------------------- -------------1 1 1 NULL 12 1 1 1.20 NULL EDIT:added a line break to avoid scrollingBe One with the OptimizerTG |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-08-17 : 14:05:27
|
| you're right. can't do it that way in check constraint. yours works, or the other way i showed. |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 15:09:57
|
quote: So you are trying to inforce "mutual exclusivity" where exactly one value needs to be null while the other is not null.
Yes, after writing down the allowable variations, yes, it does mean mutual exclusivity.In your statement:CHECK (coalesce(targetLevel, notapplicable) is not null and targetLevel + notapplicable is null) can you please explain how targetLevel + notapplicable is null works?Thanks! |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 15:13:36
|
Also I get an error when I try to execute the command: ALTER TABLE dbo.tbl_UserTargetLevels ADD CONSTRAINT CK_tbl_UserTargetLevels CHECK (coalesce(targetLevel, notapplicable) is not null and targetLevel + notapplicable is null) The ALTER TABLE statement conflicted with the CHECK constraint "CK_tbl_UserTargetLevels". The conflict occurred in database "MyDB", table "dbo.tbl_UserTargetLevels".Does that error not imply that the constraint is conflicting with itself?? |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2009-08-17 : 15:21:32
|
| I think the error is probably because you are trying to add the new version version of the check constraint without dropping the current one first.As to your first question, any expression using a NULL will resolve to NULL. So if either (targetLevel or notapplicable) is null when you attempt to ADD them the result must be NULL. So that half of the check inures that at lease one of the values is NULL.Be One with the OptimizerTG |
 |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2009-08-17 : 15:42:45
|
| Okay, thanks for the explanation. I think I have enough info to be getting along with now.Thank you very much everyone for your help. |
 |
|
|
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2009-08-18 : 07:23:35
|
quote: Originally posted by TG I think the error is probably because you are trying to add the new version version of the check constraint without dropping the current one first.As to your first question, any expression using a NULL will resolve to NULL. So if either (targetLevel or notapplicable) is null when you attempt to ADD them the result must be NULL. So that half of the check inures that at lease one of the values is NULL.Be One with the OptimizerTG
IF you have CONCAT_NULL_YEILDS_NULL set ON. (is it ON by default? I forget.)http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspxHow to ask: http://weblogs.sqlteam.com/brettk/archive/2005/05/25.aspxFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp |
 |
|
|
|