SQL Server 2005 - Использование Null в сравнении - PullRequest
4 голосов
/ 04 июня 2010

Это больше вопрос для удовлетворения моего собственного любопытства. Учитывая следующее утверждение:

DECLARE @result BIT
SET @result = CASE WHEN NULL <> 4 THEN 0
                   ELSE 1
              END
PRINT @result

Почему я получаю обратно "1" вместо "0"

Изменение на:

DECLARE @result BIT
SET @result = CASE WHEN NULL IS NULL
                        OR NULL <> 4 THEN 0
                   ELSE 1
              END
PRINT @result

Правильно возвращает мне "0"

Я знаю, что сравнение NULL может быть сложным, но этот конкретный пример проскочил через наш процесс проверки кода.

Любые разъяснения будут с благодарностью

Ответы [ 3 ]

9 голосов
/ 04 июня 2010

Это из-за 3-значной логики . В первом случае Unknown не оценивается как true, поэтому вы попадаете в else

DECLARE @result BIT
SET @result = CASE WHEN Unknown THEN 0
                   ELSE 1
              END
PRINT @result

Во втором случае вы делаете True или Unknown, который оценивается как true.

DECLARE @result BIT
SET @result = CASE WHEN True
                        OR Unknown THEN 0
                   ELSE 1
              END
PRINT @result
1 голос
/ 04 июня 2010

С чисто технической точки зрения причина, по которой первый оператор возвращает 1, заключается в том, что для ANSI_NULLS задано значение "ON", что рассматривает NULL как "Неизвестный", что соответствует стандарту ISO.

Чтобы значения оценивались так, как вы ожидаете, запустите ваш скрипт с SET ANSI_NULLS OFF перед ним.

В реальной жизни, конечно, ISNULL() - самый удивительный / самый безопасный подход.

1 голос
/ 04 июня 2010

Это связано со стандартом ANSI SQL и поведением операторов сравнения с NULL.Всякий раз, когда вы хотите сравнить значение со значением, которое может быть NULL, вам нужно использовать оператор IS, чтобы явно проверить случай, когда значение может быть NULL.Или вы можете отключить параметр ANSI_NULLS в SQL Server.

Следующие примеры делают то, что вы хотите:

DECLARE @result BIT  
DECLARE @input INT

SET @input = NULL
SET @result = CASE WHEN (@input IS NULL OR @input <> 4) THEN 0  
                   ELSE 1  
              END  
PRINT @result  

Или это:

SET ANSI_NULLS OFF

DECLARE @result BIT 
SET @result = CASE WHEN NULL <> 4 THEN 0 
                   ELSE 1 
              END 
PRINT @result 

Ссылки:

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

...