Добро пожаловать в замечательную трехзначную логику SQL.Как вы можете знать или не знать, результатом любого стандартного сравнения с null
будет не TRUE
или FALSE
, а UNKNOWN
.
В предложении WHERE
всепредложение должно оцениваться как TRUE
.
В ограничении CHECK
все ограничение должно оцениваться как не FALSE
.
Итак, мы имеем:
([Code] IS NULL AND [System] IS NULL) --Both null
OR
([Code] IS NOT NULL AND [System] = 1) --Both not null ????
Что становится (для данных запроса):
(FALSE AND TRUE)
OR
(TRUE AND UNKNOWN)
И любой оператор с UNKNOWN
на одной или другой стороне оценивается как UNKNOWN
, поэтому общий результат равен UNKNOWN
.Который не FALSE
, и поэтому проверка ограничения проверки прошла успешно.
Если вы хотите, чтобы System
не был нулевым, мне будет понятно, если вы добавите это как дополнительное явное требование.
([Code] IS NULL AND [System] IS NULL) --Both null
OR
([Code] IS NOT NULL AND [System] IS NOT NULL AND [System] = 1) --Both not null ????
Может показаться странным то, как это определено, но это согласуется с тем, как работают другие ограничения - например, ограничение внешнего ключа может иметь столбцы, допускающие обнуляемость, и еслилюбой из этих столбцов имеет значение null, в ссылочной таблице не должно быть соответствующей строки.