今天我在 SQL Server 上遇到了一些有趣的行为(在 2005 年和 2012 年观察到),我希望有人能解释一下。
=
使用NVARCHAR 字段进行比较的查询忽略了字符串中的尾随空格(或在比较之前自动修剪值),但使用like
运算符的相同查询没有忽略空格。使用的排序规则是 2012 年的 Latin1_General_CI_AS。
考虑这个 SQL Fiddle:http ://sqlfiddle.com/#!6/72262/4
请注意,like
运算符不会返回尾随空格字符串的结果,但=
运算符会。为什么是这样?
加分项:我无法在 VARCHAR 字段上复制它,我原以为在两种数据类型中都会以相同的方式处理空格 - 这是真的吗?
我最初的回答表明,设置为 OFF 的 ANSI_PADDING 标志可能是造成行为差异的原因。但是,这是不正确的;此标志仅对存储有影响,但对相等比较没有影响。
差异源于微软对 SQL 标准的实现。该标准规定,在检查相等性时,相等运算符的左右字符串都必须填充为具有相同的长度。这解释了以下结果:
LIKE 运算符不填充其操作数。对于
VARCHAR
和NVARCHAR
列类型,它的行为也不同:ASCII 类型的 LIKE 运算符的行为是特定于 SQL Server 的;对于 Unicode 类型,它符合 ANSI。
SQL 诞生于大多数数据处理语言对每个字段/变量使用固定长度的时代。带有额外空格的文本字段的自动填充也是该图片的一部分。为了与这种行为保持一致,原始 SQL CHAR 类型被明确定义为其 '=' 运算符以忽略尾随空格。(如果你觉得这很奇怪,请给我看一个令人信服的案例,其中附加到文本的尾随空格具有实际的真正商业意义。)
从那时起,SQL CHAR 类型已经向各个方向发展,但某些更现代的数据类型仍然继承了其历史前辈的一些特征并非不可想象。
在LIKE (Transact-SQL)的文档中,微软写道(强调我的):