我的同事和我在SQL-Server中遇到了一个奇怪的行为。
请考虑以下代码:
select a =
case when 1=1 then
'a '
else
'b '
end + 'c'
应该合理地假设上面的代码产生字符串'a c'。确实如此。
但是,如果我用额外的空格扩展else
的常量('b'),会发生奇怪的事情:
select a =
case when 1=1 then
'a '
else
'b '
end + 'c'
现在结果是'ac','a'的空间消失了。反之亦然:
select a =
case when 1=0 then
'a '
else
'b '
end + 'c'
这将产生'bc'。因此,无论返回的常量是否超过返回的常量,返回的常量都会被右边修剪。
它只是一个正确的修剪,因为以下代码将产生'ac':
select a =
case when 1=1 then
' a '
else
'b '
end + 'c'
这种行为有原因吗?我假设它可能与清理字符串尾随空格有关,但是为什么它只发生在未返回的常量更长时间?
在SQL Server 2014 Express Edition上已观察到上述行为。
更新
如评论中所述,在SQL Server 2014的标准安装中,此行为似乎无法重现。
答案 0 :(得分:3)
您的会话看起来像SET ANSI_PADDING OFF
,它会修剪varchar
的尾随空格。尝试使用SET ANSI_PADDING ON
(推荐设置)运行。
SET ANSI_PADDING OFF;
--trims trailing spaces
SELECT a =
CASE WHEN 1=1 THEN
'a '
ELSE
'b '
END + 'c';
--does not trim trailing spaces
SET ANSI_PADDING ON;
SELECT a =
CASE WHEN 1=1 THEN
'a '
ELSE
'b '
END + 'c';
修改强>
根据SQL Server ANSI_PADDING documentation,该设置应仅适用于列存储,而不适用于表达式结果。我询问了这种行为,SQL Server MVP Erland Sommarskog使用古老的SQL Server版本进行了一些回归测试,并将此行为识别为SQL 7中引入的错误。它已在SQL 2000中得到纠正,但仅适用于ANSI_PADDING ON
; ANSI_PADDING OFF
到目前为止仍然行为不端。
我强烈建议您更改代码,以免依赖于无证件和错误的行为。可能会在将来的SQL Server版本或修补程序中修复此错误并破坏您的代码。如果您的应用程序需要删除尾随空格,请明确使用RTRIM
函数。