我正在使用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,Level 14,State 1,Line 8
无法在对象'dbo.Test'中插入具有唯一索引'UniqueIndex'的重复键行。重复键值为(样本)。
声明已经终止。
------------
&GT;样品&LT;
(1行受影响)
我的问题是:
任何正确方向的帮助/指针都将受到赞赏。感谢。
答案 0 :(得分:13)
SQL Server遵循ANSI / ISO SQL-92规范(第8.2节, ,关于如何比较字符串的一般规则#3) 有空格。 ANSI标准要求填充字符 比较中使用的字符串,以便它们的长度匹配 比较它们。填充直接影响WHERE的语义 和HAVING子句谓词和其他Transact-SQL字符串 比较。例如,Transact-SQL认为字符串'abc'和 'abc'与大多数比较操作相同。
此规则的唯一例外是LIKE谓词。当正确的时候 LIKE谓词表达式的一侧具有带尾随的值 空间,SQL Server不会将这两个值填充到相同的长度 在比较之前。因为喜欢的目的 根据定义,谓词是为了促进模式搜索 比简单的字符串相等测试,这不违反该部分 前面提到的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。)