La consulta de igualdad en la columna NVARCHAR produce múltiples resultados en SQL Server 2012

8

Estoy en el proceso de mover un proyecto favorito de PostgreSQL (9.2.2) a SQL Server (2012 Standard).

He notado un fenómeno interesante al consultar palabras unicode. Dada la definición:

CREATE TABLE [word](
    [id] [int] IDENTITY(0,1) NOT NULL,
    [value] [nvarchar](255) NULL    
 );

y los datos:

insert into word (value) values (N'ῥύπῳ');
insert into word  (value) values (N'ἀπὸ');
insert into word  (value) values (N'ἀπό');
insert into word (value) values  (N'ἐπὶ');
insert into word (value) values  (N'ἐπί');
insert into word (value) values  (N'ὑπὸ');
insert into word (value) values  (N'ὑπό');
insert into word (value) values  (N'πίῃ');

insert into word  (value) values (N'λόγους');
insert into word  (value) values (N'λόγχῃ');
insert into word (value) values  (N'λόγων');
insert into word  (value) values (N'ἀλόης');

una consulta para una palabra en particular devolverá coincidencias cercanas. Por ejemplo:

select * from word where value = N'ἀπὸ'

devoluciones:

id  value
102137  ῥύπῳ
102141  ἀπὸ
102142  ἀπό
102143  ἐπὶ
102144  ἐπί
102145  ὑπὸ
102146  ὑπό
102147  πίῃ

http://sqlfiddle.com/#!6/1ab66/1

Sin embargo, el mismo patrón en PostgreSQL solo devuelve la coincidencia exacta. ¿Cómo puedo hacer que SQL Server haga lo mismo?

(Enlace de violín PostgreSQL): http://sqlfiddle.com/#!12/c57a6/1

Tengo la clara sensación de que me falta algo, pero no soy capaz de entender qué es.

La intercalación de la base de datos es SQL_Latin1_General_CP1_CI_AS(que también es la intercalación del servidor) en una instalación local.

swasheck
fuente

Respuestas:

8

La colación determina la semántica de comparación.

Si lo intento

CREATE TABLE [word](
    [id] [int] IDENTITY(0,1) NOT NULL,
    [value] [nvarchar](255) COLLATE Latin1_General_100_CI_AS NULL    
 );

Solo vuelve ἀπὸ.

Cambiando el sufijo a AIpor acento insensible retorna ἀπόtambién.

En mi instalación, he intentado cada colación y 1526devolución 1(presumiblemente ASy BINcolaciones), 1264devolver 2 filas (presumiblemente AI) y 1095volver 8.

De un vistazo rápido a este último grupo, se busca incluir todas las SQLcolaciones y 90colaciones, mientras que todas 100están en los primeros 2 grupos, así que supongo que este es un problema que se ha solucionado en el lote de colaciones de 2008. (Consulte Novedades en las intercalaciones de SQL Server 2008 )

Script para probar esto usted mismo

DECLARE @Results TABLE
(
Count INT,
Collation SYSNAME
)

SET NOCOUNT ON;
DECLARE @N SYSNAME;
DECLARE @C1 AS CURSOR;
SET @C1 = CURSOR FAST_FORWARD FOR 
SELECT name
FROM sys.fn_helpcollations();
OPEN @C1;
FETCH NEXT FROM @C1 INTO @N ;
WHILE @@FETCH_STATUS = 0
BEGIN
  INSERT @Results
  EXEC('SELECT COUNT(*), ''' + @N + ''' from word where value = N''ἀπὸ'' COLLATE ' + @N)
  FETCH NEXT FROM @C1 INTO @N ;
END

SELECT *
FROM @Results
ORDER BY Count DESC
Martin Smith
fuente