鉴于以下情况:
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+NULLis VARCHAR(4),类型 for 'xy'+NULL+NULL+NULLisVARCHAR(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_valuereplacement_value如果长于可以截断check_expression。