为什么T-SQL ISNULL()截断字符串而COALESCE不是?

nat*_*nho 19 t-sql sql-server coalesce isnull truncation

鉴于以下内容:

SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ
Run Code Online (Sandbox Code Playgroud)

为什么这些陈述会返回不同的结果?

mvp*_*mvp 16

根据Microsoft 文档,功能:

ISNULL(check_expression, replacement_value)
Run Code Online (Sandbox Code Playgroud)

replacement_value必须是可隐式转换为类型的类型check_expression.请注意,类型'xy'+NULLVARCHAR(3).因此,你的字符串'ABCDEFGHIJ'被转换为VARCHAR(3)并因此被修剪.

听起来很奇怪为什么它不是VARCHAR(2),但这是它的方式 - 一个字符长于'xy'.您可以使用此SQLFiddle并自己查看类型'xy'+NULLfor表达式是否与表达式相同CASE WHEN 1=2 THEN 'XYZ' ELSE NULL END,NULL但是它是隐式兼容的VARCHAR(3).

似乎对于表达式,'xy'+NULL感知长度可以计算'xy'为每个NULL添加的字符串长度(2)加1 .例如,类型为'xy'+NULL+NULLis VARCHAR(4),type为'xy'+NULL+NULL+NULLis VARCHAR(5)等等 - 请查看此SQLFiddle.这非常奇怪,但这就是MS SQL Server 2008和2012的工作方式.

  • 我必须增加此处的信息,以从Microsoft [文档](http://technet.microsoft.com/zh-cn/library/ms190349.aspx)来解释有关ISNULL行为的更多有关COALESCE行为的信息:COALESCE表达式是一个CASE表达式的语法快捷方式。也就是说,查询优化器将代码COALESCE(expression1,... n)重写为以下CASE表达式:CASE WHEN(表达式1非空)THEN expression1 When(表达式2非空)THEN expression2 ... ELSE expressionN END->案例返回类型由最高expr优先级给出。 (2认同)