Подтвердить что ты не робот

Почему T-SQL ISNULL() усекает строку, а COALESCE - нет?

Учитывая следующее:

SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ

Почему эти утверждения возвращают разные результаты?

4b9b3361

Ответ 1

Согласно документации Microsoft , для функции:

ISNULL(check_expression, replacement_value)

replacement_value должен иметь тип, который неявно конвертируется в тип check_expression. Обратите внимание: тип 'xy'+NULL равен VARCHAR(3). Из-за этого ваша строка 'ABCDEFGHIJ' добавляется к VARCHAR(3) и таким образом обрезается.

Звучит странно, почему это не VARCHAR(2), но так оно и есть - один символ длиннее 'xy'. Вы можете играть с этим SQLFiddle и сами убедиться, что тип для 'xy'+NULL совпадает с типом выражения CASE WHEN 1=2 THEN 'XYZ' ELSE NULL END, который NULL, но неявно совместимо с VARCHAR(3).

Кажется, что для выражения 'xy'+NULL воспринимаемая длина может быть вычислена как 'xy' длина строки (2) плюс 1 для каждого добавленного NULL. Например, тип 'xy'+NULL+NULL равен VARCHAR(4), тип для 'xy'+NULL+NULL+NULL - VARCHAR(5) и т.д. - проверьте этот SQLFiddle. Это очень странно, но так работают MS SQL Server 2008 и 2012.

Ответ 3

ISNULL() преобразует значение замены в тип выражения проверки. В этом случае тип выражения проверки CHAR(2), поэтому преобразование значения замены обрезает его (вы уверены, что получаете ABC, а не только AB?).

В документации Microsoft :

replacement_value может быть усечен, если replacement_value больше, чем check_expression.

Ответ 4

Вот как я работаю над своим кодом, читаю сообщение:

DECLARE @helpISNULL VARCHAR(10) --replacement_value.DataType
SET @helpISNULL = NULL
...
WHERE [field] = ISNULL(check_expression + @helpISNULL, replacement_value)