T-SQL NULLIF возвращает NULL вместо нуля

Почему приведенный ниже скрипт возвращает NULL вместо 0?

DECLARE @number BIGINT = 0;

SELECT  NULLIF(@number, '');

Согласно MSDN, он должен вернуть 0:

NULLIF
Возвращает нулевое значение, если два указанных выражения равны.

Для SQL-сервера 0 и '' считаются одинаковыми (= равными)? В чем логика?


person DNac    schedule 12.12.2017    source источник
comment
meta-dupe: Почему 0 равен пустой строке?   -  person underscore_d    schedule 12.12.2017
comment
Возможный дубликат сравнения пустой строки SQL Server 2012 с 0   -  person underscore_d    schedule 12.12.2017


Ответы (5)


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

SELECT CONVERT(bigint, '')
SELECT CONVERT(float, '')
SELECT CONVERT(date, '')

0
0
1900-01-01

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-precedence-transact-sql

person Rawitas Krungkaew    schedule 12.12.2017

Как BOL гласит: «правила приоритета типов данных определяют, что тип данных с более низким приоритетом преобразуется в тип данных с более высоким приоритетом». У вас есть два разных типа данных, bigint и nvarchar. Чтобы сравнить их, они должны быть одного типа данных. Следуя описанному правилу, nvarchar неявно преобразуется в bigint. Попробуйте select convert(bigint, ''), вы обнаружите, что это приводит к 0. Так что они одинаковы.

person HoneyBadger    schedule 12.12.2017

Этот скрипт должен возвращать ноль, и это правда! Причина этого в том, что '' является строкой, поэтому она будет неявно приведена к целочисленному значению при сравнении его с целым числом, как вы делаете сейчас! В общем, вы напрашиваетесь на неприятности, когда сравниваете значения разных типов данных, поскольку неявные преобразования происходят за кулисами.

person Shahrzad Jahanbaz    schedule 12.12.2017

Это результат неявного преобразования. В некоторых случаях строковое значение может быть преобразовано в целое число (например, пустая строка преобразуется в 0).

По сути, SQL Server сначала пытается сопоставить тип данных двух выражений, а затем проверяет значения.

DECLARE @number BIGINT = 0;

SELECT 
    CONVERT(BIGINT, '')
    , NULLIF(@number, '')
    , NULLIF(@number, CONVERT(BIGINT, ''))
person Pred    schedule 12.12.2017

Он преобразовал '' в целое число, которое равно 0, поскольку целое число имеет более высокий приоритет в типе данных. Посмотрите пример ниже, как '' становится 0

SELECT CONVERT(INT, '')  -- 0
SELECT CAST('' AS INT)   -- 0
person Susang    schedule 12.12.2017