我正在使用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。)
关于sql-server - 唯一索引,varchar列和(空白)空间的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9460671/