【发布时间】:2013-09-23 23:33:33
【问题描述】:
鉴于以下情况:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
为什么这些语句返回不同的结果?
【问题讨论】:
标签: sql-server tsql coalesce isnull truncation
鉴于以下情况:
SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
为什么这些语句返回不同的结果?
【问题讨论】:
标签: sql-server tsql coalesce isnull truncation
根据微软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 的工作方式。
【讨论】:
COALESCE 的行为,但没有说明为什么'xy'+NULL 的类型是VARCHAR(3)。这一定与 SQL Server 内部有关。
【讨论】:
ISNULL() 将替换值转换为检查表达式的类型。在这种情况下,检查表达式的类型是CHAR(2),因此转换替换值会截断它(你确定你得到的是ABC 而不仅仅是AB?)。
来自微软documentation:
如果
replacement_value比check_expression长,replacement_value可以被截断。
【讨论】: