2016-01-06 4 views
3

Я столкнулся с несколько странным поведением с преобразованиями типа данных при использовании ISNULL. Посмотрите на это:ISNULL и неявные преобразования типов данных в TSQL

PRINT CASE WHEN ISNULL('', 0) = 0 THEN 'true' ELSE 'false' END 
PRINT CASE WHEN ISNULL('', 0) = '' THEN 'true' ELSE 'false' END 
PRINT CASE WHEN ISNULL(NULL, 0) = '' THEN 'true' ELSE 'false' END 

Все эти выражения оцениваются как истинные. Но когда я объявляю переменную NVARCHAR и установите его в NULL, то происходит следующее:

DECLARE @charType nvarchar; SET @charType = NULL; 
PRINT CASE WHEN ISNULL(@charType, 0) = '' THEN 'true' ELSE 'false' END 

Это должно также оценить, правда, но это имеет значение ложь. Зачем?

ответ

2

Здесь ISNULL('', 0) возвращает '' и ISNULL(NULL, 0) возвращает 0

Data Type Precedence ...

Когда оператор объединяет два выражения различных типов данных, то правила типа данных старшинства указать, что тип данных с нижний приоритет преобразуется в тип данных с более высоким приоритетом . Если преобразование не поддерживается неявным преобразованием, возвращается .

В int оказывает более Precedence над char, '' будут преобразованы в int.

select cast('' as int) ==> 0 

Таким образом, в первом случае все '' будут преобразованы в 0, поэтому запрос будет сведено к

PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END 
PRINT CASE WHEN '' = '' THEN 'true' ELSE 'false' END 
PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END 

Поэтому печать true

ISNULL ...

Возвращает тот же тип, что и check_expression. Если литерал NULL равен , предоставленному как check_expression, возвращает тип данных replacement_value.Если литерал NULL предоставляется как check_expression и не предоставляется replacement_value, возвращает INT

Но во втором случае, как @charType является null, ISNULL будет отбрасывать значение 0 к nvarchar то запрос становится

Так

PRINT CASE WHEN '0' = '' THEN 'true' ELSE 'false' END 

Поэтому печать false

+0

Красиво объяснено. Пальцы вверх! – shadow

+0

Я не нашел объяснения поведения преобразования ISNULL, и это, конечно же, объяснение - ноль, так как значение замены преобразуется в «0». Это ответили на вопрос. Спасибо, Правен. –

+0

Что заставило меня опубликовать этот вопрос, так это то, что общее правило о приоритете типа данных не выполняется между выражением проверки и значением замены в выражениях ISNULL. Я ошибался в этом. На самом деле тип выражения проверки всегда имеет приоритет (что сейчас ясно для меня). –

0

Попробуйте это:

PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = 0 THEN 'true' ELSE 'false' END 
PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END 
PRINT CASE WHEN CAST(ISNULL(NULL, 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END 

Как вы можете видеть, SQL знает, что нужно бросить в NVARCHAR, когда @charType установлен на тип NVARCHAR.

Что вы пытаетесь достичь?

+0

Недавно я наткнулся на несколько вариантов использования ISNULL в существующем коде, что привело меня к тому, чтобы я полностью и подробно понял, что здесь происходит. Поэтому я пытаюсь ничего не добиться, кроме понимания кода, написанного другими. –

Смежные вопросы