我正在使用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行)
Msg 2601,第14级,状态1,第8行
无法在具有唯一索引'UniqueIndex'的对象'dbo.Test'中插入重复的键行。重复的键值为(sample)。
该语句已终止。
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
>样本<
(影响1行)

我的问题是:

我假设索引不能存储尾随空格。谁能指出我指定/定义此行为的官方文档?
是否有设置可以更改此行为,即,使其将“ sample”和“ sample”识别为两个不同的值(顺便说一下,它们是),因此两者都可以在索引中。
为什么在地球上SELECT返回行? SQL Server必须使用WHERE子句中的空格来做一些真正有趣的事情,因为如果删除索引中的唯一性,则两个INSERT都将运行OK,而SELECT将返回两行!

任何在正确方向上的帮助/指针将不胜感激。谢谢。

最佳答案

Trailing blanks explained


SQL Server遵循ANSI / ISO SQL-92规范(第8.2节,
,一般规则#3)如何比较字符串
与空格。 ANSI标准要求字符填充
比较中使用的字符串,以便它们的长度之前匹配
比较它们。填充直接影响WHERE的语义
和HAVING子句谓词以及其他Transact-SQL字符串
比较。例如,Transact-SQL将字符串“ abc”和
对于大多数比较操作,“ 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


这是有关trailing blanks and the LIKE clause的更多详细信息。

关于指标:


如果您提供的值与现有值有所不同,则插入其值必须唯一的列将失败。
仅尾随空格。以下字符串都将被考虑
等价于唯一约束,主键或唯一索引。
同样,如果您已有一个包含以下数据的表,请尝试
添加一个唯一的限制,它将失败,因为值是
被认为是相同的。

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



(摘自here。)

10-06 13:58