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?
ISNULL()
converts the replacement value to the type of the check expression. In this case, the type of the check expression isCHAR(2)
, so converting the replacement value truncates it (are you sure you're gettingABC
and not justAB
?).From the Microsoft documentation:
According to Microsoft documentation, for function:
replacement_value
must be of a type that is implicitly convertible to the type ofcheck_expression
. Note that type for'xy'+NULL
isVARCHAR(3)
. Because of this your string'ABCDEFGHIJ'
is cast toVARCHAR(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 expressionCASE WHEN 1=2 THEN 'XYZ' ELSE NULL END
, which isNULL
but is implicitly compatible toVARCHAR(3)
.It seems that for expression
'xy'+NULL
perceived length can be computed as'xy'
string length (2) plus 1 for everyNULL
added. For example, type of'xy'+NULL+NULL
isVARCHAR(4)
, type for'xy'+NULL+NULL+NULL
isVARCHAR(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