O que há nos Phone
valores inseridos abaixo que o SQL Server os trata como idênticos em um índice exclusivo?
CREATE TABLE Phone
(
Id int identity(1, 1) primary key,
Phone nvarchar(448) not null
)
go
create unique index IX_Phone on Phone(Phone)
with (data_compression = page);
go
insert into Phone Values ('?281/?263-?8400');
insert into Phone Values ('281/263-8400');
select * from Phone;
drop table Phone;
Recebo uma mensagem de erro:
Msg 2601, Level 14, State 1, Line 13 Não é possível inserir linha de chave duplicada no objeto 'dbo.Phone' com índice exclusivo 'IX_Phone'. O valor da chave duplicada é (?281/?263-?8400).
Seu problema é que você passa strings unicode como non-unicode .
Seu '281/263-8400' é uma string de 15 caracteres, não 12, existem 3 símbolos 8206 não imprimíveis, marca da esquerda para a direita
Tente este código onde eu passo os valores unicode como unicode e vejo que não há problema algum:
E é isso que sua string '281/263-8400' realmente contém (
dbo.nums
é minha tabela que contém números naturais):Agora, o que acontece quando você passa sua string unicode como não unicode.
Seu símbolo não imprimível 8206 é transformado em
?
, é assim que as strings não-unicode funcionam: cada caractere que não pode ser encontrado na página de código correspondente e representado como código ascii é substituído por um ponto de interrogação.Então, por exemplo, se você usar Latin Collation e tentar comparar caracteres hebraicos e cirílicos (o mesmo número de caracteres), pois
varchar
eles sempre são iguais apenas porque são transformados em pontos de interrogação ao comparar,nvarchar
pois são diferentes:Portanto, se agora você tentar inserir esses 2 valores (hebraico + cirílico) na sua tabela Phone passando-os como
non-unicode
(sem usarN
), apenas um deles será inserido e o outro será rejeitado por restrição exclusiva. E se você tentar selecionar em Telefone, '?????' será retornadoNão sei por que '281/263-8400' está retornando o mesmo valor que '?281/?263-?8400'. Para corrigi-lo, basta alterar seus
INSERT
comandos para que eles usem valores unicode: