唯一索引、varchar列和(空白)空格的行为



我使用的是Microsoft SQL Server 2008 R2(带有最新的service pack/修补程序),数据库排序规则为SQL_Latin1_General_CP1_CI_AS。

以下代码:

SET ANSI_PADDING ON;
GO
CREATE TABLE Test (
   Code VARCHAR(16) NULL
);
CREATE UNIQUE INDEX UniqueIndex
    ON Test(Code);
INSERT INTO Test VALUES ('sample');
INSERT INTO Test VALUES ('sample ');
SELECT '>' + Code + '<' FROM Test WHERE Code = 'sample        ';
GO

产生以下结果:

(1行受影响)

消息2601,14级,状态1,第8行

无法在具有唯一索引"UniqueIndex"的对象"dbo.Test"中插入重复的键行。重复的键值为(sample)。

语句已终止。

‐‐‐‐

>样本<

(1行受影响)

我的问题是:

  1. 我认为索引无法存储尾部空格。有人能给我指一下指定/定义这种行为的官方文件吗
  2. 是否有一个设置可以更改此行为,即使其将"sample"one_answers"sample"识别为两个不同的值(顺便说一句,它们是),以便两者都可以在索引中
  3. 到底为什么SELECT返回一行?SQL Server一定对WHERE子句中的空格做了一些非常有趣/聪明的处理,因为如果我删除索引中的唯一性,两个INSERT都将运行正常,SELECT将返回两行

如有任何正确方向的帮助/指示,我们将不胜感激。谢谢

解释了尾随空格:

SQL Server遵循ANSI/ISO SQL-92规范(第8.2节,,关于如何比较字符串的一般规则#3)带有空格。ANSI标准要求对字符进行填充比较中使用的字符串,以便它们的长度在比较它们。填充直接影响WHERE的语义和HAVING子句谓词和其他Transact-SQL字符串比较。例如,Transact-SQL考虑字符串"abc"one_answers"abc"对于大多数比较操作是等效的。

该规则的唯一例外是LIKE谓词。当权利LIKE谓词表达式的侧面有一个尾随的值空格,SQL Server不会将这两个值填充到相同的长度在进行比较之前。因为LIKE的目的根据定义,谓词是为了方便模式搜索与简单的字符串相等性测试相比,这并不违反本节前面提到的ANSI SQL-92规范。

下面是上面提到的所有情况的一个众所周知的例子:

DECLARE @a VARCHAR(10)
DECLARE @b varchar(10)
SET @a = '1'
SET @b = '1 ' --with trailing blank
SELECT 1
WHERE 
    @a = @b 
AND @a NOT LIKE @b
AND @b LIKE @a

以下是有关尾随空格和LIKE子句的更多详细信息。

关于指数:

如果您提供的值与现有值的差异为仅尾部空格。以下字符串都将被考虑由唯一约束、主键或唯一索引等效。同样,如果您有一个包含以下数据的现有表,并尝试添加一个唯一的限制,它将失败,因为值为被认为是相同的。

PaddedColumn
------------
'abc'
'abc '
'abc  '
'abc    '

(取自此处。)

相关内容

  • 没有找到相关文章