SQL Server自动修剪varchar值,相等比较但不喜欢比较


13

今天,我在SQL Server上遇到了一些有趣的行为(在2005年和2012年观察到),希望有人能解释一下。

使用=NVARCHAR字段进行比较的查询会忽略字符串中的尾随空格(或在比较之前自动修剪值),但是使用like运算符的同一查询不会忽略该空格。2012年使用的归类为Latin1_General_CI_AS。

考虑以下SQL Fiddle:http://sqlfiddle.com/#!6/72262/4

请注意,like运算符不会返回结尾空格字符串的结果,但=运算符会返回结果。为什么是这样?

优点:我无法在VARCHAR字段上复制它,我会认为在两种数据类型中都将以相同的方式处理空间-这是真的吗?


我当时想编写一个检查约束,以修剪字符串。我发现了一个解决方法是检查MyString+'x' = ltrim(rtrim(MyString))+'x'的建议在这个博客上
default.kramer

Answers:


15

我最初的答案建议将ANSI_PADDING标志设置为OFF可能是由于行为上的差异。但是,这是不正确的。该标志仅对存储有影响,而对相等比较没有影响。

差异源自Microsoft对SQL标准的实施。该标准指出,在检查相等性时,必须对相等性运算符的左右两个字符串进行填充以使其长度相同。这解释了以下结果:

insert into test_padding (varchar_clmn, nvarchar_clmn) values ('space ', 'nspace ')
go
-- equality for varchar column
select count(*) from test_padding where varchar_clmn = 'space' -- returns 1
select count(*) from test_padding where varchar_clmn = 'space ' -- returns 1
select count(*) from test_padding where varchar_clmn = 'space    ' --returns 1
-- equality for nvarchar column
select count(*) from test_padding where nvarchar_clmn = 'nspace' -- returns 1
select count(*) from test_padding where nvarchar_clmn = 'nspace ' -- returns 1
select count(*) from test_padding where nvarchar_clmn = 'nspace    ' --returns 1

LIKE运算符不填充其操作数。对于VARCHARNVARCHAR列类型,它的行为也不同

-- likeness for varchar column
select count(*) from test_padding where varchar_clmn like 'space' -- returns 1
select count(*) from test_padding where varchar_clmn like 'space ' -- returns 1
select count(*) from test_padding where varchar_clmn like 'space    ' -- returns 0
-- likeness for nvarchar column
select count(*) from test_padding where nvarchar_clmn like 'nspace' -- returns 0
select count(*) from test_padding where nvarchar_clmn like 'nspace ' -- returns 1
select count(*) from test_padding where nvarchar_clmn like 'nspace    ' -- returns 0

对于ASCII类型,LIKE运算符的行为是特定于SQL Server的。对于Unicode类型,它符合ANSI。


4

SQL诞生于一个时代,即大多数数据处理语言对每个字段/变量都使用固定长度。带有额外空格的文本字段的自动填充也是该图片的一部分。为了与该行为保持一致,原始SQL CHAR类型已明确定义为其“ =”运算符,以忽略尾随空格。(如果您觉得很奇怪,请给我看一个令人信服的案例,其中附加在文本后的尾随空格具有实际的实际业务意义。)

从那时起,SQL CHAR类型已经朝着各种方向发展,但是并非无法想象某些更现代的数据类型仍然继承了其历史前辈的某些特征。


“向我展示一个令人信服的案例,其中添加到文本的尾随空格具有实际的实际业务意义”-存储重要的空格数据,例如某些原始控制台输出和不安全的XML片段。

1

LIKE(Transact-SQL)的文档中,Microsoft写(强调我的意思):

使用LIKE进行模式匹配

LIKE支持ASCII模式匹配和Unicode模式匹配。当所有参数...均为ASCII字符数据类型时,将执行ASCII模式匹配。如果任何一个参数都是Unicode数据类型,则所有参数都将转换为Unicode并执行Unicode模式匹配。当您将Unicode数据...与LIKE一起使用时,尾随空格很重要;但是,对于非Unicode数据,尾随空格并不重要。Unicode LIKE与ISO标准兼容。ASCII LIKE与SQL Server的早期版本兼容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.