鉴于以下情况:
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
为什么这些语句返回不同的结果?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的工作方式。
ISNULL()
将替换值转换为检查表达式的类型。在本例中,检查表达式的类型是 CHAR(2)
,因此将替换值转换会将其截断(您确定获取到的是 ABC
而不仅仅是 AB
吗?)。
来自 Microsoft 文档:
如果
replacement_value
长度超过check_expression
,则可能会截断replacement_value
。
CASE WHEN (expression1 IS NOT NULL) THEN expression1 WHEN (expression2 IS NOT NULL) THEN expression2
... ELSE expressionN END -> CASE返回类型由最高expr优先级给出。 - natenhoCOALESCE
的行为,但并没有说明为什么'xy'+NULL
的类型是VARCHAR(3)
。这一定与SQL Server内部有关。 - mvp