Почему SET ANSI_NULLS OFF не работает для сравнения полей? - PullRequest
4 голосов
/ 10 февраля 2012

Я бы посчитал режим SET ANSI_NULLS OFF очень удобным и использовал бы его по умолчанию, если бы он работал согласованно - позволяет сравнивать нули, используя = или! = Везде. Но это работает, только если я сравниваю с явным встроенным нулем, но если я сравниваю с полем, содержащим нуль - это НЕ РАБОТАЕТ. Почему Microsoft разработала это так? Не удивительно, почему никто не использует режим SET ANSI_NULLS OFF по умолчанию. Я предпочел бы остаться с болью «is null» и «not null», чем думать о том, что я использую inline, а что нет.

Вот пример, который показывает проблему - строка с ??? должен вернуть 2 строки, но возвращает только одну строку.

CREATE TABLE t1 (a int null, b int null)
INSERT INTO t1 values (null,null)
INSERT INTO t1 values (0,null)
INSERT INTO t1 values (null,0)
INSERT INTO t1 values (0,0)
set ansi_nulls ON
select * from t1 where a=null -- empty result
select * from t1 where a=b  -- (0,0)
select * from t1 where null=null -- empty result
set ansi_nulls OFF
select * from t1 where a=null -- (null,null),(null,0)
select * from t1 where a=b -- why only (0,0) ???, it should be (0,0),(null,null)
select * from t1 where null=null -- returns all 4 rows
drop table t1

1 Ответ

6 голосов
/ 10 февраля 2012

Здесь ответили:

Как работает ANSI_NULLS в TSQL?

Отключение ansi_nulls влияет только на сравнение, если один из операндов является пустой переменной илибуквальное значение null.

Кроме того, вам не следует писать новый код, используя параметр off, поскольку он не будет поддерживаться в будущем:

http://msdn.microsoft.com/en-us/library/ms188048.aspx

Обновить:

После повторного прочтения вашего вопроса, я думаю, что вы фактически говорите, почему:

select * from t1 where a=b

не работает так:

select * from t1 where a=b or (a=null and b=null)

, который вернется(нуль, ноль), (0,0) в вашем примере.

Итак, вы проверяете два условия:

  1. Оба значения столбца равны
  2. Оба значения столбца неизвестны

КогдаВаше выражение написано как = NULL, довольно ясно, что вы пытаетесь сделать.Но если записано как a = b, вы собираетесь проверить только 1-е условие или оба?

Еще один способ подумать, скажем, вы пишете запрос, чтобы вернуть всех клиентов с одинаковым номером дома + мобильный.Хотите ли вы вернуть клиентов с нулевыми значениями в обоих этих столбцах?

Короче говоря, MSFT не хочет автоматически проверять два условия, когда указано только одно - я думаю, что это правильный дизайн.

...