Given the following:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
Why are these statements returning different results?
Given the following:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
Why are these statements returning different results?
According to Microsoft documentation, for function:
ISNULL(check_expression, replacement_value)
replacement_value
must be of a type that is implicitly convertible to the type of check_expression
. Note that type for 'xy'+NULL
is VARCHAR(3)
. Because of this your string 'ABCDEFGHIJ'
is cast to VARCHAR(3)
and thus trimmed.
It sounds strange why it is not VARCHAR(2)
, but this is the way it is - one character longer than 'xy'
. You can play with this SQLFiddle and see for yourself that type for 'xy'+NULL
is the same as for expression CASE WHEN 1=2 THEN 'XYZ' ELSE NULL END
, which is NULL
but is implicitly compatible to VARCHAR(3)
.
It seems that for expression 'xy'+NULL
perceived length can be computed as 'xy'
string length (2) plus 1 for every NULL
added. For example, type of 'xy'+NULL+NULL
is VARCHAR(4)
, type for 'xy'+NULL+NULL+NULL
is VARCHAR(5)
and so on - check out this SQLFiddle. This is extremely weird, but that is how MS SQL Server 2008 and 2012 work.
You can check all the difference here, its very clear
MSDN : http://msdn.microsoft.com/en-us/library/ms190349.aspx
MSDN Blog : http://blogs.msdn.com/b/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx
ISNULL()
converts the replacement value to the type of the check expression. In this case, the type of the check expression is CHAR(2)
, so converting the replacement value truncates it (are you sure you're getting ABC
and not just AB
?).
From the Microsoft documentation:
replacement_value
can be truncated ifreplacement_value
is longer thancheck_expression
.