Причудливый ГДЕ col = NULL поведение - PullRequest
3 голосов
/ 09 апреля 2010

Это проблема, которую один из наших разработчиков принес мне. Он наткнулся на старую хранимую процедуру, которая несколько раз использовала WHERE col = NULL. Когда хранимая процедура выполняется, она возвращает данные.

Если запрос внутри хранимой процедуры выполняется вручную, он не вернет данные, пока ссылки «WHERE col = NULL» не будут изменены на «WHERE col IS NULL».

Кто-нибудь может объяснить это поведение?

Ответы [ 3 ]

5 голосов
/ 09 апреля 2010

Это так: если вы сравниваете что-либо с null, оно оценивается как unknown. Любая логика с unknown сама по себе unknown. Поэтому любое утверждение с anything = null всегда будет ложным.

Важное различие между этими двумя конструкциями:

1 = null --> unknown
1 is null --> false

Итак:

1 = null or 1=1 --> unknown (false)
1 is null or 1=1 --> true

Итак, как вы можете видеть, unknown портит целое выражение.

Исходя из комментариев, лучшим ответом, вероятно, будет проверка на наличие ANSI_NULL с:

SELECT SESSIONPROPERTY ('ANSI_NULLS')

Если это возвращает false, конструкция = null будет работать как is null:

set ansi_nulls on -- default
SELECT SESSIONPROPERTY ('ANSI_NULLS') -- 1
select 1 where not null = 1 -- no rows returned
set ansi_nulls off
SELECT SESSIONPROPERTY ('ANSI_NULLS') -- 0
select 1 where not null = 1 -- returns a row

По умолчанию установлено значение ansi_nulls on, и очень необычно видеть его выключенным. Хранимая процедура запоминает настройку с момента ее создания:

set ansi_nulls off
go
create procedure dbo.TestNulls as select 1 where not null = 1
go
set ansi_nulls on
exec dbo.TestNulls -- Still prints a row

Вы можете проверить сохраненные настройки, написав процедуру из SSMS.

3 голосов
/ 09 апреля 2010

ОК, думаю, я должен был ответить на этот вопрос:

Проверьте настройку ANSI_NULLS

0 голосов
/ 09 апреля 2010

В SQL X = NULL всегда будет иметь значение false, так как NULL представляет отсутствие данных, нельзя сказать, равно ли это «другому» отсутствию данных или нет (NULL = NULL равно false) Вот почему существует ключевое слово IS ...

...