鉴于以下内容:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
为什么这些陈述会返回不同的结果?
答案 0 :(得分:15)
根据Microsoft documentation,功能:
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)加上每添加NULL
的1。例如,'xy'+NULL+NULL
的类型为VARCHAR(4)
,'xy'+NULL+NULL+NULL
的类型为VARCHAR(5)
,依此类推 - 请查看此 SQLFiddle 。这非常奇怪,但这就是MS SQL Server 2008和2012的工作方式。
答案 1 :(得分:4)
你可以在这里检查所有的区别,非常清楚
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
答案 2 :(得分:0)
ISNULL()
将替换值转换为检查表达式的类型。在这种情况下,检查表达式的类型为CHAR(2)
,因此转换替换值会截断它(您确定要获得ABC
而不只是AB
吗?)。
来自Microsoft documentation:
如果replacement_value
超过replacement_value
,则
check_expression
会被截断。