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, ''))