Eri*_*ric 11 t-sql sql-server unique-index string-comparison
我正在使用Microsoft SQL Server 2008 R2(带有最新的Service Pack/patches),数据库排序规则是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
Run Code Online (Sandbox Code Playgroud)
产生以下结果:
(1排受影响)
Msg 2601,Level 14,State 1,Line 8
无法在对象'dbo.Test'中插入具有唯一索引'UniqueIndex'的重复键行.重复键值为(样本).
该语句已终止.
------------
>样品<
(1排受影响)
我的问题是:
任何帮助/指针在正确的方向将不胜感激.谢谢.
Ole*_*Dok 14
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
Run Code Online (Sandbox Code Playgroud)
这里有关于尾随空白和LIKE子句的更多细节.
关于指数:
如果提供的值仅通过尾随空格提供与现有值不同的值,则插入其值必须唯一的列将失败.以下字符串将被唯一约束,主键或唯一索引视为等效.同样,如果您有一个包含以下数据的现有表并尝试添加唯一限制,则它将失败,因为这些值被视为相同.
Run Code Online (Sandbox Code Playgroud)PaddedColumn ------------ 'abc' 'abc ' 'abc ' 'abc '
(取自这里.)