Я только что натолкнулся на интересный сценарий того, как NULL обрабатывается в T-SQL (и, возможно, других формах SQL). Проблема довольно хорошо описана и на нее ответил этот вопрос , и я проиллюстрировал проблему ниже;
-- SET ANSI_NULLS ON -- Toggle this between ON/OFF to see how it changes behaviour
DECLARE @VAR1 DATETIME
DECLARE @VAR2 DATETIME
SET @VAR1 = (SELECT CURRENT_TIMESTAMP)
SET @VAR2 = (SELECT NULL)
-- This will return 1 when ansi_nulls is off and nothing when ansi_nulls is on
SELECT 1 WHERE @VAR1 != @VAR2
DECLARE @TstTable TABLE (
COL1 DATETIME,
COL2 DATETIME)
INSERT INTO @TstTable
SELECT @VAR1, @VAR1
UNION
SELECT @VAR1, NULL
-- This won't ever return a value irrespective of the ansi_nulls setting
SELECT * FROM @TstTable WHERE COL1 != COL2
Эта ситуация заставила меня усомниться в моем понимании нулевых представлений, в частности, в SQL. Я всегда понимал, что ноль означает, что он не имеет значения. Это неверное предположение, учитывая первый абзац этой страницы . В нем говорится (мой акцент ... хотя я мог бы легко выделить целый абзац);
Значение NULL указывает на значение неизвестно . Значение NULL
отличается от пустого или нулевого значения. Нет двух нулевых значений равных.
Сравнение между двумя нулевыми значениями, или между NULL и любыми другими
значение, вернуть неизвестное, поскольку значение каждого NULL неизвестно.
Действительно ли это верно и для условий переменных T-SQL? Это, конечно, подходит для моего SELECT 1 WHERE @VAR1 != @VAR2
примера выше, но я не понимаю, почему NULL в этом случае считается «НЕИЗВЕСТНЫМ», а не пустым / неинициализированным / ничем и т. Д. Я знаю, что ANSI_NULLS меняет работу, но она устарела и будет быть удаленным из будущей версии.
Может ли кто-нибудь предложить хорошее объяснение того, почему NULL в T-SQL относится к неизвестному значению, а не неинициализированному значению? Если да, можете ли вы расширить свой ответ, чтобы показать, почему переменные T-SQL со значением NULL также считаются неизвестными?