25

鉴于以下情况:

SELECT ISNULL('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABC (Why?)
SELECT COALESCE('XY' + NULL, 'ABCDEFGHIJ') -- Outputs ABCDEFGHIJ

为什么这些语句返回不同的结果?

4

3 回答 3

22

根据 Microsoft文档,对于功能:

ISNULL(check_expression, replacement_value)

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

为什么不是这样听起来很奇怪VARCHAR(2),但它就是这样 - 一个字符长于'xy'. 您可以使用此SQLFiddle并亲自查看类型 for'xy'+NULL与 for expression 相同CASE WHEN 1=2 THEN 'XYZ' ELSE NULL ENDNULL但隐式兼容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 的工作方式。

于 2013-09-19T02:23:54.350 回答
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

于 2013-09-19T02:30:24.247 回答
0

ISNULL()将替换值转换为检查表达式的类型。在这种情况下,检查表达式的类型是CHAR(2),因此转换替换值会截断它(你确定你得到的ABC不仅仅是AB?)。

从微软文档

replacement_valuereplacement_value如果长于可以截断check_expression

于 2013-09-19T02:22:50.260 回答