Sql server 唯一索引、varchar列和(空白)空格的行为
我正在使用Microsoft SQL Server 2008 R2和最新的service pack/修补程序,数据库排序规则为SQL\u Latin1\u General\u CP1\u CI\u AS 以下代码:Sql server 唯一索引、varchar列和(空白)空格的行为,sql-server,tsql,string-comparison,unique-index,Sql Server,Tsql,String Comparison,Unique Index,我正在使用Microsoft SQL Server 2008 R2和最新的service pack/修补程序,数据库排序规则为SQL\u Latin1\u General\u CP1\u CI\u AS 以下代码: SET ANSI_PADDING ON; GO CREATE TABLE Test ( Code VARCHAR(16) NULL ); CREATE UNIQUE INDEX UniqueIndex ON Test(Code); INSERT INTO Test
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
声明已终止
‐‐‐‐‐‐‐‐‐
>样本:
SQL Server遵循ANSI/ISO SQL-92规范第8.2节,
,关于如何比较字符串的一般规则3
有空格。ANSI标准要求字符填充
用于比较的字符串,以便它们的长度在比较之前匹配
比较它们。填充直接影响WHERE的语义
并具有子句谓词和其他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
这里有更多的细节
关于指标:
如果您提供的值与现有值不同,则插入值必须唯一的列将失败
仅限尾随空格。将考虑以下所有字符串
由唯一约束、主键或唯一索引等效。
同样,如果您有一个包含以下数据的现有表,请尝试
添加唯一的限制,它将失败,因为值为
被认为是相同的
PaddedColumn
------------
'abc'
'abc '
'abc '
'abc '
摘自。谢谢大家的指点。我为自己懒得用谷歌搜索而感到内疚。在我看来,标准定义的行为是不直观的。我可以想象,十分之九的开发人员会说“a”和“a”不是同一个字符串,但哦,好吧。这是我在Azure SQL中遇到的最不直观的事情之一。。。