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

Почему скрипт ниже NULL вместо 0?

DECLARE @number BIGINT = 0;

SELECT  NULLIF(@number, '');

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

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

Для сервера SQL, 0 а также '' считается одинаковым (= равным)? Какая логика позади?

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

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

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

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

SELECT CONVERT(INT, '')  -- 0
SELECT CAST('' AS INT)   -- 0

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

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

DECLARE @number BIGINT = 0;

SELECT 
    CONVERT(BIGINT, '')
    , NULLIF(@number, '')
    , NULLIF(@number, CONVERT(BIGINT, ''))
Другие вопросы по тегам