Почему NULL = NULL оценивается как ложное в SQL-сервере - PullRequest
127 голосов
/ 04 декабря 2009

На сервере SQL, если в предложении where указано nullParam=NULL, оно всегда оценивается как ложное. Это нелогично и вызвало у меня много ошибок. Я понимаю, что ключевые слова IS NULL и IS NOT NULL являются правильным способом сделать это. Но почему SQL-сервер ведет себя так?

Ответы [ 16 ]

3 голосов
/ 04 декабря 2009

В MSDN есть хорошая описательная статья о нулях и трех логиках состояний, которые они порождают.

Короче говоря, спецификация SQL92 определяет NULL как неизвестный, а NUL, используемый в следующих операторах, приводит к неожиданным результатам для непосвященных:

= operator NULL   true   false 
NULL       NULL   NULL   NULL
true       NULL   true   false
false      NULL   false  true

and op     NULL   true   false 
NULL       NULL   NULL   false
true       NULL   true   false
false      false  false  false

or op      NULL   true   false 
NULL       NULL   true   NULL
true       true   true   true
false      NULL   true   false
2 голосов
/ 04 декабря 2009

Вопрос:
Соответствует ли одно неизвестное другому неизвестному?
(NULL = NULL)
На этот вопрос никто не может ответить, поэтому по умолчанию он имеет значение true или false в зависимости от настроек ansi_nulls.

Однако вопрос:
Эта неизвестная переменная неизвестна?
Этот вопрос совершенно другой, и на него можно ответить правдой.

nullVariable = ноль сравнивает значения
nullVariable - значение null сравнивает состояние переменной

0 голосов
/ 13 апреля 2019

Если вы ищете выражение, возвращающее true для двух NULL, вы можете использовать:

SELECT 1 
WHERE EXISTS (
    SELECT NULL
    INTERSECT
    SELECT NULL
)

Это полезно, если вы хотите скопировать данные из одной таблицы в другую.

0 голосов
/ 23 августа 2018

Кажется, что ответы здесь все приходят с точки зрения CS, поэтому я хочу добавить один с точки зрения разработчика.

Для разработчика NULL очень полезен. Ответы здесь говорят, что NULL означает неизвестный, и, возможно, в теории CS это правда, не помню, это было давно. В реальной разработке, хотя, по моему опыту, это происходит примерно в 1% случаев. Остальные 99% используются в тех случаях, когда значение не UNKNOWN, но оно известно, что оно отсутствует.

Например:

  • Client.LastPurchase, для нового клиента. Это не неизвестно, известно, что он еще не совершил покупку.

  • При использовании ORM с таблицей для Класс Иерархия отображение, некоторые значения просто не отображаются для определенных классов.

  • При отображении древовидной структуры корень обычно будет иметь Parent = NULL

  • и многое другое ...

Я уверен, что большинство разработчиков в какой-то момент написали WHERE value = NULL, не получили никаких результатов, и вот как они узнали о синтаксисе IS NULL. Посмотрите, сколько голосов имеют этот вопрос и связанные с ним.

Базы данных SQL - это инструмент, и они должны быть спроектированы так, чтобы их пользователям было проще понять.

0 голосов
/ 14 апреля 2015

Просто дополнение к другим замечательным ответам:

AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.

OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.

NOT: The result of not unknown is unknown
0 голосов
/ 04 декабря 2009

ноль неизвестен в sql, поэтому мы не можем ожидать, что два неизвестных будут одинаковыми.

Однако вы можете получить такое поведение, установив для ANSI_NULLS значение Выкл. (По умолчанию включено) Вы сможете использовать = оператор для нулей

SET ANSI_NULLS off
if null=null
print 1
else 
print 2
set ansi_nulls on
if null=null
print 1
else 
print 2
...