Разница между NULL в SQL и null в языках программирования - PullRequest
2 голосов
/ 02 марта 2012

Я только что натолкнулся на интересный сценарий того, как 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 также считаются неизвестными?

Ответы [ 3 ]

3 голосов
/ 02 марта 2012

В SQL мы заинтересованы в хранении фактов в таблицах (отношения a.k.a).

Что Кодд попросил было:

Правило 3: Систематическая обработка нулевых значений:

СУБД должна позволять каждому полю оставаться пустым (или пустым). В частности, он должен поддерживать представление «отсутствующей информации и неприменимой информации», которое является систематическим, отличным от всех обычных значений (например, «отличным от нуля или любого другого числа», в случае числовых значений), и независимым от данных тип. Также подразумевается, что такие представления должны систематически обрабатываться СУБД.

В результате мы получили трехзначную логику (как сказано в @zmbq). Почему так?

У нас есть две вещи, которые мы пытаемся сравнить на равенство. Они равны? Что ж, получается, что мы (пока) не знаем, что такое элемент 1, и мы (пока) не знаем, что такое элемент 2 (оба NULL). Они могут быть равны. Они могут быть неравными. Было бы одинаково неправильно отвечать на сравнение равенства либо TRUE, либо FALSE. Поэтому мы отвечаем UNKNOWN.


В других языках null обычно используется с указателями (или ссылками на языках без указателей, но особенно без C ++), чтобы указать, что указатель в данный момент ни на что не указывает.

2 голосов
/ 02 марта 2012

Добро пожаловать в Трехзначная логика , где все может быть правдой, ложью или неизвестностью.

Значение null==null не верно, и это не ложь, это неизвестно ...

1 голос
/ 02 марта 2012

но я не понимаю, почему NULL в этом случае считается "НЕИЗВЕСТНЫМ", а не пусто / неинициализировано / ничего

?? Что тут не понять. Это так, потому что это было определено, как это. У кого-то возникла идея, что это так. Он был введен в стандарт.

Да, это немного рекурсивно, но довольно часто проектные решения принимаются именно так.

Это больше связано с арифметикой. Сумма из 20 строк с одним Null is Null - как бы вы относились к нему как к неизвестному? C # и т. Д. Реагируют с исключением, но это мешает вам при выполнении статистического анализа. Неизвестные значения должны переместить все, с чем они соприкасаются, в неизвестное, и ни одно неизвестное не является тем же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...