«= NULL» является выражением значения
Теперь «IS NULL» является предпочтительным методом для оценки состояния переменной, равной NULL.
Более подробное обсуждение того же вопроса можно найти по следующей ссылке
http://www.sqlservercentral.com/articles/T-SQL/understandingthedifferencebetweenisnull/871/
Не уверен, что можно прочитать статью, не заходя на сайт, поэтому выложите копию здесь
Понимание разницы между «IS NULL» и «= NULL»
Когда переменная создается в SQL с помощью оператора объявления, она создается без данных и сохраняется в таблице переменных (vtable) в области памяти SQL. Vtable содержит имя и адрес памяти переменной. Тем не менее, когда переменная создается, ей не присваивается адрес памяти, и поэтому переменная не определяется в терминах памяти.
Когда вы УСТАНАВЛИВАЕТЕ переменную, ей назначается адрес памяти, и исходные данные сохраняются в этом адресе. Когда вы снова УСТАНАВЛИВАЕТЕ значение, данные в адресе памяти, на который указывает переменная, затем изменяются на новое значение.
Теперь по поводу разницы и почему каждый ведет себя так, как он.
«= NULL»
«= NULL» является выражением значения. Это означает, что если переменная установлена и память для хранения данных, она имеет значение. Фактически переменная может быть установлена в NULL, что означает, что значение данных объектов неизвестно. Если значение было установлено так:
DECLARE @val CHAR(4)
SET @val = NULL
Вы явно установили значение данных на неизвестное, и поэтому, когда вы делаете:
If @val = NULL
Это будет оцениваться как истинное выражение.
Но если я сделаю:
DECLARE @val CHAR(4)
If @val = NULL
Будет оцениваться как ложное.
Причина этого в том, что я проверяю NULL как значение @val. Поскольку я не установил значение @val, адрес памяти не был назначен, и поэтому для @ val значения не существует.
Примечание: См. Раздел о SET ANSI_NULLS (ON | OFF) из-за различий в настройках по умолчанию в SQL 7 и 2000, из-за которых примеры не работают. Это основано на SQL 7.
«НУЛЬ» 1043 *
Теперь «IS NULL» немного сложнее и является предпочтительным методом для оценки состояния переменной как NULL. Когда вы используете предложение «IS NULL», оно проверяет как адрес переменной, так и данные в переменной как неизвестные. Поэтому, если я, например, сделаю:
DECLARE @val CHAR(4)
If @val IS NULL
PRINT ‘TRUE’
ELSE
PRINT ‘FALSE’
SET @val = NULL
If @val IS NULL
PRINT ‘TRUE’
ELSE
PRINT ‘FALSE’
Оба выхода будут ИСТИНА. Причина в первом @val IS NULL. Я только объявил переменную, и не было задано адресное пространство для данных, для которых проверяется «IS NULL». А во втором значение было явно установлено в NULL, которое также проверяется «IS NULL».
SET ANSI_NULLS (ON | OFF)
Теперь позвольте мне бросить излом в работе. В предыдущих примерах вы видите, что = NULL будет работать до тех пор, пока значение явно задано. Однако, когда вы установите ANSI_NULLS ON, все будет немного по-другому.
Ex.
DECLARE @val CHAR(4)
SET @val = NULL
SET ANSI_NULLS ON
If @val =NULL
PRINT ‘TRUE’
ELSE
PRINT ‘FALSE’
SET ANSI_NULLS OFF
If @val =NULL
PRINT ‘TRUE’
ELSE
PRINT ‘FALSE’
Вы заметите, что в первый раз, когда вы выполняете оператор = NULL, после выполнения SET ANSI_NULLS ON вы получаете FALSE, а после установки OFF вы получаете TRUE. Причина в следующем.
Выдержка из статьи SQL BOL «SET ANSI_NULLS»
Стандарт SQL-92 требует, чтобы сравнение с равным (=) или не равным (<>) с нулевым значением оценивалось как FALSE. Когда SET ANSI_NULLS включен, оператор SELECT с использованием WHERE column_name = NULL возвращает ноль строк, даже если в column_name есть нулевые значения. Оператор SELECT, использующий WHERE column_name <> NULL, возвращает ноль строк, даже если в column_name есть ненулевые значения.
Когда SET ANSI_NULLS выключено, равно (=)и не равно (<>) операторы сравнения не соответствуют стандарту SQL-92. Оператор SELECT с использованием WHERE column_name = NULL возвращает строки с нулевыми значениями в column_name. Оператор SELECT с использованием WHERE column_name <> NULL возвращает строки с ненулевыми значениями в столбце. Кроме того, оператор SELECT, использующий WHERE имя_ столбца <> XYZ_value, возвращает все строки, которые не являются значениями XYZ и не равны NULL.
Конец выдержки
Так, как определено в SQL92, «= NULL» всегда должно оценивать false. Так что даже установка значения явно означает, что вы никогда не встретите = NULL, если условие и ваш код могут работать не так, как задумано. Основная причина, по которой = NULL будет стрелять в вас, заключается в том, что SQL 7 при поставке и установке по умолчанию имеет значение ANSI_NULL OFF, а SQL 2000 по умолчанию - ANSI_NULL ON. Конечно, вы можете изменить это несколькими способами, но если вы обновили базу данных с 7 до 2000 и обнаружили, что = NULL работает только тогда, когда вы явно указали, когда вы развертываете сервер 2000 по умолчанию, ваш код теперь ломается и может вызвать проблемы с данными.
Еще одна причина использовать IS NULL вместо этого, поскольку в соответствии с рекомендациями SQL 92 он все равно будет оцениваться в TRUE, и, следовательно, ваш код безопаснее для обновления сервера.
Резюме
Если сводка, если вам не нужно проверять, чтобы значение переменной было установлено равным NULL, и вы установили ANSI_NULLS ON, то всегда используйте условие «IS NULL» для проверки, если переменная имеет значение NULL. Вместо этого, используя = NULL, вы можете причинить себе много головной боли, пытаясь устранить проблемы, которые могут возникнуть из-за этого, сейчас или неожиданно в будущем.
основа
Часть предоставленной информации проистекает из того, как работает C ++ и как SQL ведет себя при любых обстоятельствах. К сожалению, в SQL, насколько мне известно, нет функции addressof, которая позволяла бы мне выводить фактический адрес памяти, чтобы показать, что происходит под капотом. В C ++ при создании переменной она имеет адрес 0xddddddd (в режиме отладки, но это могут быть и другие нереальные адреса). Когда вы устанавливаете переменную, первая проверка адреса даст вам действительный адрес памяти, где хранятся данные. Кроме того, дополнительную информацию можно получить из SQL Books Online в разделах IS NULL и SET ANSI_NULLS….