鉴于以下情况:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
为什么这些语句返回不同的结果?
鉴于以下情况:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
为什么这些语句返回不同的结果?
根据 Microsoft文档,对于功能:
ISNULL(check_expression, replacement_value)
replacement_value
必须是可隐式转换为 的类型的类型check_expression
。请注意, for 的类型'xy'+NULL
是VARCHAR(3)
。因此,您的字符串'ABCDEFGHIJ'
被投射VARCHAR(3)
并因此被修剪。
为什么不是这样听起来很奇怪VARCHAR(2)
,但它就是这样 - 一个字符长于'xy'
. 您可以使用此SQLFiddle并亲自查看类型 for'xy'+NULL
与 for expression 相同CASE WHEN 1=2 THEN 'XYZ' ELSE NULL END
,NULL
但隐式兼容VARCHAR(3)
。
似乎对于表达式'xy'+NULL
的感知长度可以计算为'xy'
字符串长度 (2) 加上每个NULL
添加的 1。例如,类型 of 'xy'+NULL+NULL
is VARCHAR(4)
,类型 for 'xy'+NULL+NULL+NULL
isVARCHAR(5)
等等 - 看看这个SQLFiddle。这非常奇怪,但这就是 MS SQL Server 2008 和 2012 的工作方式。
您可以在这里查看所有差异,非常清楚
MSDN:http: //msdn.microsoft.com/en-us/library/ms190349.aspx
MSDN 博客:http: //blogs.msdn.com/b/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx
ISNULL()
将替换值转换为检查表达式的类型。在这种情况下,检查表达式的类型是CHAR(2)
,因此转换替换值会截断它(你确定你得到的ABC
不仅仅是AB
?)。
从微软文档:
replacement_value
replacement_value
如果长于可以截断check_expression
。