Tipo sensible al acento


19

¿Por qué estas dos SELECTdeclaraciones dan como resultado un orden de clasificación diferente?

USE tempdb;
CREATE TABLE dbo.OddSort 
(
    id INT IDENTITY(1,1) PRIMARY KEY
    , col1 NVARCHAR(2)
    , col2 NVARCHAR(2)
);
GO
INSERT dbo.OddSort (col1, col2) 
VALUES (N'e', N'eA')
    , (N'é', N'éB')
    , (N'ë', N'ëC')
    , (N'è', N'èD')
    , (N'ê', N'êE')
    , (N'ē', N'ēF');
GO

SELECT * 
FROM dbo.OddSort 
ORDER BY col1 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ id ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ é ║ éB ║
║ 4 ║ è ║ èD ║ - debería ser id 3?
║ 5 ║ ê ║ êE ║
║ 3 ║ ë ║ ëC ║
║ 6 ║ ē ║ ēF ║
╚════╩══════╩══════╝
SELECT * 
FROM dbo.OddSort 
ORDER BY col2 COLLATE Latin1_General_100_CS_AS;
╔════╦══════╦══════╗
║ id ║ col1 ║ col2 ║
╠════╬══════╬══════╣
║ 1 ║ e ║ eA ║
║ 2 ║ é ║ éB ║
║ 3 ║ ë ║ ëC ║
║ 4 ║ è ║ èD ║
║ 5 ║ ê ║ êE ║
║ 6 ║ ē ║ ēF ║
╚════╩══════╩══════╝

Respuestas:


13

Esta pregunta no está tan relacionada con las bases de datos, sino más sobre el manejo y las reglas de Unicode.

Basado en https://docs.microsoft.com/en-us/sql/t-sql/statements/windows-collation-name-transact-sql Latin1_General_100_CS_AS significa: "La clasificación utiliza las reglas y mapas de clasificación general del diccionario Latin1 en la página de códigos 1252 "con el agregado CS = mayúsculas y minúsculas y AS = acento sensible.

La asignación entre la página de códigos de Windows 1252 y Unicode ( http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT ) muestra los mismos valores para todos los caracteres con los que estamos tratando (excepto e con macron eso no existe en el mapeo de Microsoft, así que no tengo idea de qué hace con este caso), por lo que podemos concentrarnos en las herramientas y la terminología de Unicode por ahora.

Primero, háganos saber con precisión a qué nos enfrentamos, para todas sus cadenas:

0065  LATIN SMALL LETTER E
0041  LATIN CAPITAL LETTER A
00E9  LATIN SMALL LETTER E WITH ACUTE
0042  LATIN CAPITAL LETTER B
00EB  LATIN SMALL LETTER E WITH DIAERESIS
0043  LATIN CAPITAL LETTER C
00E8  LATIN SMALL LETTER E WITH GRAVE
0044  LATIN CAPITAL LETTER D
00EA  LATIN SMALL LETTER E WITH CIRCUMFLEX
0045  LATIN CAPITAL LETTER E
0113  LATIN SMALL LETTER E WITH MACRON
0046  LATIN CAPITAL LETTER F

El algoritmo de colación Unicode se describe aquí: https://www.unicode.org/reports/tr10/

Eche un vistazo a la sección 1.3 "Sensibilidad contextual" que explica que la clasificación no puede depender de un solo carácter después del otro, ya que algunas reglas son sensibles al contexto.

Tenga en cuenta también estos puntos en 1.8:

La clasificación no es una propiedad de cadenas. El orden de clasificación no se conserva bajo operaciones de concatenación o subcadena, en general.

Por defecto, el algoritmo utiliza tres niveles totalmente personalizables. Para la escritura latina, estos niveles corresponden aproximadamente a:

alphabetic ordering
diacritic ordering
case ordering.

Pero el algoritmo en sí mismo es un poco denso. La esencia de esto es: En pocas palabras, el Algoritmo de clasificación Unicode toma una cadena Unicode de entrada y una Tabla de elementos de clasificación, que contiene datos de mapeo para los caracteres. Produce una clave de clasificación, que es una matriz de enteros de 16 bits sin signo. Dos o más claves de clasificación así producidas se pueden comparar en binario para dar la comparación correcta entre las cadenas para las que se generaron.

Puede ver las reglas específicas de clasificación en latín aquí: http://developer.mimer.com/collations/charts/latin.htm o más directa y específicamente para MS SQL: http://collation-charts.org/mssql/mssql. 0409.1252.Latin1_General_CS_AS.html

Para el epersonaje que muestra:

e E é É è È ê Ê ë Ë

Esto explica sus resultados al realizar el pedido, col1excepto que ē no existe en la página de códigos 1252, por lo que no tengo absolutamente ninguna idea de lo que hace con él.

O si hacemos el algoritmo Unicode a mano, utilizando el valor de las claves de DUCET en http://www.unicode.org/Public/UCA/latest/allkeys.txt :

Paso 1: Forma de normalización D, por lo que cada caso se convierte en:

e => U+0065
é => U+0065 U+0301
ë => U+0065 U+0308
è => U+0065 U+0300
ê => U+0065 U+0302
ē => U+0065 U+0304

paso 2, Producir matrices de intercalación (búsqueda en archivo allkeys.txt)

e => [.1D10.0020.0002]
é => [.1D10.0020.0002] [.0000.0024.0002]
ë => [.1D10.0020.0002] [.0000.002B.0002]
è => [.1D10.0020.0002] [.0000.0025.0002]
ê => [.1D10.0020.0002] [.0000.0027.0002]
ē => [.1D10.0020.0002] [.0000.0032.0002]

paso 3, Forme las claves de clasificación (para cada nivel, tome cada valor dentro de cada matriz de clasificación, luego coloque 0000 como delimitador y comience nuevamente para el siguiente nivel)

e => 1D10 0000 0020 0000 0002
é => 1D10 0000 0020 0024 0000 0002 0002
ë => 1D10 0000 0020 002B 0000 0002 0002
è => 1D10 0000 0020 0025 0000 0002 0002
ê => 1D10 0000 0020 0027 0000 0002 0002
ē => 1D10 0000 0020 0032 0000 0002 0002

Paso 4, Comparar claves de clasificación (comparación binaria simple de cada valor uno por uno): el cuarto valor es suficiente para ordenarlos todos, por lo que el orden final se convierte en:

e
é
è
ê
ë
ē

De la misma manera para ordenar col2:

paso 1: NFD

eA => U+0065 U+0041
éB => U+0065 U+0301 U+0042
ëC => U+0065 U+0308 U+0043
èD => U+0065 U+0300 U+0044
êE => U+0065 U+0302 U+0045
ēF => U+0065 U+0304 U+0046

paso 2: matrices de intercalación

eA => [.1D10.0020.0002] [.1CAD.0020.0008]
éB => [.1D10.0020.0002] [.0000.0024.0002] [.1CC6.0020.0008]
ëC => [.1D10.0020.0002] [.0000.002B.0002] [.1CE0.0020.0008]
èD => [.1D10.0020.0002] [.0000.0025.0002] [.1CF5.0020.0008]
êE => [.1D10.0020.0002] [.0000.0027.0002] [.1D10.0020.0008]
ēF => [.1D10.0020.0002] [.0000.0032.0002] [.1D4B.0020.0008]

Paso 3: claves de clasificación de formulario

eA => 1D10 1CAD 0000 0020 0020 0000 0002 0008
éB => 1D10 1CC6 0000 0020 0024 0020 0000 0002 0002 0008
ëC => 1D10 1CE0 0000 0020 002B 0020 0000 0002 0002 0008
èD => 1D10 1CF5 0000 0020 0025 0020 0000 0002 0002 0008
êE => 1D10 1D10 0000 0020 0027 0020 0000 0002 0002 0008
ēF => 1D10 1D4B 0000 0020 0032 0020 0000 0002 0002 0008

Paso 4: Comparar las claves de clasificación: el segundo valor es suficiente para ordenarlas todas, y de hecho ya está en orden creciente, por lo que el orden final es:

eA
éB
ëC
èD
êE
ēF

Actualización : agregar el tercer caso de Solomon Rutzky, que es más complicado debido al espacio que permite nuevas reglas (elegí el "caso no ignorable"):

paso 1, NFD:

è 1 => U+0065 U+0300 U+0020 U+0031
ê 5 => U+0065 U+0302 U+0020 U+0035
e 2 => U+0065 U+0020 U+0032
é 4 => U+0065 U+0301 U+0020 U+0034
ē 3 => U+0065 U+0304 U+0020 U+0033
ë 6 => U+0065 U+0308 U+0020 U+0036

Paso 2, Producir matrices de intercalación:

è 1 => [.1D10.0020.0002] [.0000.0025.0002] [*0209.0020.0002] [.1CA4.0020.0002]
ê 5 => [.1D10.0020.0002] [.0000.0027.0002] [*0209.0020.0002] [.1CA8.0020.0002]
e 2 => [.1D10.0020.0002] [*0209.0020.0002] [.1CA5.0020.0002]
é 4 => [.1D10.0020.0002] [.0000.0024.0002] [*0209.0020.0002] [.1CA7.0020.0002]
ē 3 => [.1D10.0020.0002] [.0000.0032.0002] [*0209.0020.0002] [.1CA6.0020.0002]
ë 6 => [.1D10.0020.0002] [.0000.002B.0002] [*0209.0020.0002] [.1CA9.0020.0002]

Paso 3, claves de clasificación de formulario:

è 1 => 1D10 0209 1CA4 0000 0020 0025 0020 0020 0000 0002 0002 0002 0002
ê 5 => 1D10 0209 1CA8 0000 0020 0027 0020 0020 0000 0002 0002 0002 0002
e 2 => 1D10 0209 1CA5 0000 0020 0020 0020 0000 0002 0002 0002
é 4 => 1D10 0209 1CA7 0000 0020 0024 0020 0020 0000 0002 0002 0002 0002
ē 3 => 1D10 0209 1CA6 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002
ë 6 => 1D10 0209 1CA9 0000 0020 002B 0020 0020 0000 0002 0002 0002 0002

Paso 4, compara las claves de clasificación:

Básicamente, el tercer valor determina el orden, y de hecho solo se basa en el último dígito, por lo que el orden debería ser:

è 1
e 2
ē 3
é 4
ê 5
ë 6

Segunda actualización basada en el comentario de Solomon Rutzky sobre las versiones de Unicode.

Usé los allkeys.txtdatos sobre la última versión de Unicode en este momento, es decir, la versión 10.0

Si necesitamos tener en cuenta Unicode 5.1 , esto sería: http://www.unicode.org/Public/UCA/5.1.0/allkeys.txt

Acabo de comprobar, para todos los caracteres anteriores, las matrices de intercalación son las siguientes:

e => [.119D.0020.0002.0065]
é => [.119D.0020.0002.0065] [.0000.0032.0002.0301]
ë => [.119D.0020.0002.0065] [.0000.0047.0002.0308]
è => [.119D.0020.0002.0065] [.0000.0035.0002.0300]
ê => [.119D.0020.0002.0065] [.0000.003C.0002.0302]
ē => [.119D.0020.0002.0065] [.0000.005B.0002.0304]

y:

eA => [.119D.0020.0002.0065] [.1141.0020.0008.0041]
éB => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [.1157.0020.0008.0042]
ëC => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [.116F.0020.0008.0043]
èD => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [.1182.0020.0008.0044]
êE => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [.119D.0020.0008.0045]
ēF => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [.11D5.0020.0008.0046]

y:

è 1 => [.119D.0020.0002.0065] [.0000.0035.0002.0300] [*0209.0020.0002.0020] [.1138.0020.0002.0031]
ê 5 => [.119D.0020.0002.0065] [.0000.003C.0002.0302] [*0209.0020.0002.0020] [.113C.0020.0002.0035]
e 2 => [.119D.0020.0002.0065] [*0209.0020.0002.0020] [.1139.0020.0002.0032]
é 4 => [.119D.0020.0002.0065] [.0000.0032.0002.0301] [*0209.0020.0002.0020] [.113B.0020.0002.0034]
ē 3 => [.119D.0020.0002.0065] [.0000.005B.0002.0304] [*0209.0020.0002.0020] [.113A.0020.0002.0033]
ë 6 => [.119D.0020.0002.0065] [.0000.0047.0002.0308] [*0209.0020.0002.0020] [.113D.0020.0002.0036]

que luego se calculan con las siguientes claves de clasificación:

e => 119D 0000 0020 0000 0002 0000 0065
é => 119D 0000 0020 0032 0000 0002 0002 0000 0065 0301
ë => 119D 0000 0020 0047 0000 0002 0002 0000 0065 0308
è => 119D 0000 0020 0035 0000 0002 0002 0000 0065 0300
ê => 119D 0000 0020 003C 0000 0002 0002 0000 0065 0302
ē => 119D 0000 0020 005B 0000 0002 0002 0000 0065 0304

y:

eA => 119D 1141 0000 0020 0020 0000 0002 0008 0000 0065 0041
éB => 119D 1157 0000 0020 0032 0020 0000 0002 0002 0008 0000 0065 0301 0042
ëC => 119D 116F 0000 0020 0047 0020 0000 0002 0002 0008 0000 0065 0308 0043
èD => 119D 1182 0000 0020 0035 0020 0000 0002 0002 0008 0000 0065 0300 0044
êE => 119D 119D 0000 0020 003C 0020 0000 0002 0002 0008 0000 0065 0302 0045
ēF => 119D 11D5 0000 0020 005B 0020 0000 0002 0002 0008 0000 0065 0304 0046

y:

è 1 => 119D 0209 1138 0000 0020 0035 0020 0020 0000 0002 0002 0002 0002 0000 0065 0300 0020 0031
ê 5 => 119D 0209 113C 0000 0020 003C 0020 0020 0000 0002 0002 0002 0002 0000 0065 0302 0020 0035
e 2 => 119D 0209 1139 0000 0020 0020 0020 0000 0002 0002 0002 0000 0065 0020 0032
é 4 => 119D 0209 113B 0000 0020 0032 0020 0020 0000 0002 0002 0002 0002 0000 0065 0301 0020 0034
ē 3 => 119D 0209 113A 0000 0020 005B 0020 0020 0000 0002 0002 0002 0002 0000 0065 0304 0020 0033
ë 6 => 119D 0209 113D 0000 0020 0047 0020 0020 0000 0002 0002 0002 0002 0000 0065 0308 0020 0036

que nuevamente da estos tres resultados ordenados:

e
é
è
ê
ë
ē

y

eA
éB
ëC
èD
êE
ēF

y

è 1
e 2
ē 3
é 4
ê 5
ë 6

Hola patricio Gracias por publicar esta información detallada. Algunas notas: 1) Puede ignorar la página de códigos 1252. Eso es para datos VARCHAR(es decir, no Unicode), que no se utilizan aquí. Es por eso que el ēpersonaje funciona bien. 2) La información de "gráficos de colación" está un poco desactualizada. Es para una versión anterior de esta Clasificación y no han publicado nada desde 2009. 3) La versión Unicode aquí definitivamente no es la última (Versión 10). La _100_serie Collations llegó con SQL 2008, por lo que sería Unicode 5.0 o 5.1: unicode.org/standard/versions/#TUS_Earlier_Versions
Solomon Rutzky

No creo que los allKeys.txt cambios entre la versión Unicode, además de la adición de nuevos caracteres, por lo que lo anterior deba seguir siendo cierto pero, por supuesto, podría rehacerse con los datos anteriores anteriores, solo me falta la energía de volver a dedicar algunas horas. En cuanto a CP1252, solo provenía de la definición dada por MS-SQL (no uso este producto yo mismo).
Patrick Mevzek

1) Probablemente no haya cambios importantes entre las versiones, pero estoy bastante seguro de que hay correcciones de peso / clasificación, como mínimo. Pero sí, ciertamente tengo limitaciones de tiempo;) 2) Con respecto a CP1252, lo estaba mencionando porque el concepto de páginas de códigos no existe en Unicode. Unicode es un medio para nunca necesitar páginas de códigos. El documento de MS no está claro sobre esto, pero menciona en la parte superior " La página de códigos utilizada para almacenar datos de caracteres que no son Unicode ". Tienes razón en que el único personaje no está en CP1252, pero las páginas de códigos no entran en juego aquí.
Solomon Rutzky

Sí, nunca dije nada sobre la página de códigos relacionada con Unicode. Es solo la documentación de MS SQL que dice que este nombre de clasificación funciona con la "página de códigos 1252". Probablemente no tenga sentido (no lo tiene para mí, pero de nuevo, no es un usuario de él), pero es lo que está escrito en la documentación de este software. En cuanto a rehacer el trabajo, siéntase libre de hacerlo o simplemente proporcione los cambios sobre la clasificación relacionada con los personajes en juego aquí entre Unicode 5 y más reciente, si los hay y si lo desea. Creo que mi respuesta se mantiene como es, es precisa y construye los resultados basados ​​en la entrada, no al revés.
Patrick Mevzek

3) re: oración n. ° 1: aunque principalmente se trata de Unicode, esta pregunta es un problema del sistema operativo ya que MS implementó la especificación y podría no haberlo hecho todo y / o haber cometido algunos errores. Encontré 2 errores en .NET con respecto a cómo determina la "categoría" o "bloque" en el que se encuentra un personaje en particular (estaban identificando erróneamente un pequeño segmento de caracteres). Además, esto es , al menos un poco, un problema de SQL Server, solo porque SQL Server tiene efectivamente una instantánea de cada intercalación en un punto en el tiempo (por coherencia entre versiones), por lo que podrían tener lo que ahora es un comportamiento específico de SQL Server.
Solomon Rutzky

16

El comportamiento que está viendo aquí se debe, en un sentido general, al hecho de que el Algoritmo de clasificación Unicode (UCA) permite una ordenación compleja de niveles múltiples. Más específicamente:

  1. Ordenar no es comparación:

    Determinar si dos cadenas son iguales o diferentes es bastante sencillo (dado un entorno / idioma particular y un conjunto de sensibilidades). Pero determinar el orden de 2 o más cadenas puede ser muy complejo.

  2. La clasificación se realiza en una serie de pasos, con cada paso aplicado a toda la cadena, no carácter por carácter:

    1. Estándar: ordena los caracteres base (independientemente del acento y las diferencias de mayúsculas y minúsculas)
    2. Si es sensible al acento, aplique pesos de acento / diacríticos
    3. SI distingue entre mayúsculas y minúsculas, aplique pesos de carcasa

Cuando ordena por col1(carácter único), primero determina que todos los caracteres tienen el mismo peso ya que son todos " e ". Luego, aplica el acento / peso diacrítico. No hay diferencias de carcasa, por lo que el tercer paso no cambiaría nada. Entonces, las únicas diferencias están en el paso 2, por lo que hay un orden preferido para esas filas en función col1.

Cuando ordena por col2(dos caracteres), primero determina que cada fila tiene un peso diferente, ya que ambos caracteres se utilizan para determinar el peso de clasificación (por ejemplo, " ea ", " eb ", etc.). Luego, aplica el acento / peso diacrítico. No hay diferencias de carcasa, por lo que el tercer paso no cambiaría nada. Entonces, hay diferencias en los pasos 1 y 2 esta vez. Pero dado que las diferencias en el paso 1 ya se han aplicado a cada cadena antes de considerar los pesos del paso 2, los pesos del paso 2 no tienen ningún efecto en el orden; solo se aplicarían si los pesos del paso 1 para dos o más filas fueran iguales.

La siguiente adaptación del código de muestra de la pregunta, con suerte, ilustra el comportamiento de clasificación descrito anteriormente. Agregué algunas filas adicionales y una columna adicional para ayudar a mostrar el impacto de la clasificación que distingue entre mayúsculas y minúsculas (ya que los datos de la muestra original son minúsculas):

PREPARAR

USE [tempdb];

-- DROP TABLE dbo.OddSort;
CREATE TABLE dbo.OddSort
(
    id INT IDENTITY(1,1) PRIMARY KEY,
    col1 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col2 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS,
    col3 NVARCHAR(5) COLLATE Latin1_General_100_CS_AS
);
GO

INSERT dbo.OddSort (col1, col2, col3)
VALUES (N'e', N'eA', N'e A')
     , (N'ê', N'êE', N'ê E')
     , (N'é', N'éH', N'é H')
     , (N'ë', N'ëC', N'ë C')
     , (N'E', N'EG', N'E G')
     , (N'Ë', N'ëh', N'ë h')
     , (N'è', N'èD', N'è D')
     , (N'é', N'éB', N'é B')
     , (N'ë', N'ëH', N'ë H')
     , (N'ē', N'ēF', N'ē F');

PRUEBA 1

SELECT [id], [col1], UNICODE([col1]) AS [CodePoint]
FROM dbo.OddSort 
ORDER BY col1;

Devoluciones:

id    col1    CodePoint
1     e       101
5     E       69
8     é       233
3     é       233
7     è       232
2     ê       234
4     ë       235
9     ë       235
6     Ë       203
10    ē       275

Lo que podemos ver en los resultados anteriores:

  1. El punto de código no determina el orden de clasificación
  2. Los caracteres no acentuados se ordenan antes que los caracteres acentuados (dentro de la misma letra: f aún vendría después de todo esto). Claramente, los pesos de acento se aplican antes que los casos.
  3. Las minúsculas se clasifican antes que las mayúsculas dentro del mismo carácter acentuado (o no acentuado) (es decir, la e luego E y la ë luego Ë ). La mayoría de las intercalaciones de Windows utilizan esta adaptación, mientras que la mayoría de las intercalaciones de SQL Server ordenan las mayúsculas primero.

PRUEBA 2

SELECT [id], [col2]
FROM dbo.OddSort 
ORDER BY col2;

Devoluciones:

id    col2
1     eA
8     éB
4     ëC
7     èD
2     êE
10    ēF
5     EG
3     éH
6     ëh
9     ëH

Lo que podemos ver en los resultados anteriores:

  1. La clasificación de primer nivel realmente son los personajes base. Si se tratara de acentos / signos diacríticos, las filas ëC (id = 4), ēF (id = 10) y EG (id = 5) no estarían donde están. Si fuera una carcasa, entonces la fila EG (id = 5) no estaría donde está.
  2. La clasificación de segundo nivel realmente son los acentos / signos diacríticos. Esto explica por qué las últimas tres filas son éH -> ëh -> ëH en lugar de ëh -> éH -> ëH (es decir, ID 3 -> 6 -> 9 en lugar de 6 -> 3 -> 9).
  3. La clasificación de tercer nivel es realmente la carcasa. Es por eso que las últimas 2 filas son ëh -> ëH , ya que las minúsculas se ordenan primero.

PRUEBA 3

SELECT [id], [col3]
FROM dbo.OddSort 
ORDER BY col3;

Devoluciones:

id    col3
1     e A
8     é B
4     ë C
7     è D
2     ê E
10    ē F
5     E G
3     é H
6     ë h
9     ë H

Lo que podemos ver en los resultados anteriores:

  1. El orden de clasificación es exactamente el mismo que en la Prueba 2. La única diferencia en los valores de prueba aquí es que hay un espacio entre cada carácter, eliminando la posibilidad de reglas contextuales. Por lo tanto, sabemos que la razón de la diferencia en el orden de clasificación de col2la pregunta se debe nuevamente a la "Comparación multinivel" y no a la "Sensibilidad contextual".

Notas adicionales:

  1. Con respecto a obtener las reglas exactas, eso no es tan fácil como debería ser. El problema para obtener explicaciones concretas de estas reglas es que las reglas de clasificación Unicode, aunque definitivamente están documentadas, son una recomendación. Depende de los proveedores, como Microsoft, implementar esas recomendaciones. Microsoft no implementó las recomendaciones exactamente como se indica en la documentación de Unicode, por lo que hay una desconexión allí (similar a cómo ni las especificaciones HTML o CSS se implementan completamente, ni siquiera de la misma manera, en todos los proveedores). Luego, hay diferentes versiones de las intercalaciones de Windows (está utilizando la versión 100que salió con SQL Server 2008) y que está vinculada a una versión Unicode que es mucho más antigua que la versión actual de Unicode o de la demostración de colación ICUesta usando. Por ejemplo, la sección Novedades en las colaciones de SQL Server 2008 de la documentación "Compatibilidad y compatibilidad con Unicode" para SQL Server 2008 presenta dos puntos muy interesantes sobre lo que es "nuevo" en la _100_serie Colaciones:

    1. Tabla de casos Unicode 5.0.

      Unicode 5.0 se publicó en julio de 2006 (bueno, la base de datos de personajes se lanzó entonces, y la especificación completa siguió a fines de 2006). La versión actual es la 10.0 que se publicó en junio de 2017. Y dado el patrón de lanzamiento de los últimos 4 años, es probable que la versión 11.0 salga en algún momento a mediados de 2018.

    2. La ponderación se ha agregado a caracteres previamente no ponderados que se habrían comparado por igual.

      Esos pesos probablemente se definieron en el estándar Unicode, pero no en esta implementación del mismo.

     
    Aún así, la documentación de UCA vinculada anteriormente es un buen lugar para comenzar.

  2. Las claves de clasificación utilizadas por Windows / .NET / SQL Server no son exactamente las mismas que se muestran en el estándar Unicode (ver la respuesta de @ Patrick) o implementadas en la UCI . Para ver qué uso de Windows / .NET / SQL Server, puede probar el método CompareInfo.GetSortKey . Creé un UDF SQLCLR para pasar estos valores y obtener la clave de clasificación. Tenga en cuenta que estoy usando SQL Server 2017 en Windows 10 con .NET Framework 4.5 - 4.6.1 instalado, por lo que .NET debería usar Unicode 6.0.0. Además, Level4 no se está utilizando para estas cadenas.

    CHAR    L1     L2     L3     L4
    e      0E21
    E      0E21           12
    ë      0E21    13
    Ë      0E21    13     12

    Observar estas claves de clasificación para la Prueba 1 y darse cuenta de que los niveles se clasifican como columnas múltiples dentro de una ORDER BYcláusula (L3 se clasifica dentro de los mismos valores de L2, que se clasifica dentro de los mismos valores de L1), debería ilustrar que la razón del comportamiento En la pregunta se señala, de hecho, la capacidad de clasificación de varios niveles de Unicode. Igualmente:

    CHAR       L1         L2       L3       L4
    EG      0E210E25              1212
    éH      0E210E2C      0E      0212
    ëh      0E210E2C      13
    ëH      0E210E2C      13      0212

    Al observar algunas de las teclas de clasificación para la Prueba 2, podemos ver que los caracteres base se ordenan primero (L1), luego se ordenan los acentos (L2) y luego se ordena la carcasa (L3).

  3. Dado que el tipo de datos es NVARCHAR, solo nos interesan los puntos de código Unicode y los algoritmos de clasificación, de ahí el uso de la UNICODE()función en TEST 1. Si bien la mayoría de las colaciones especifican páginas de códigos, solo se refieren a VARCHARdatos. Es decir, aunque la página de códigos 1252 está especificada por la Latin1_General*serie de intercalaciones, eso puede ignorarse aquí.

  4. Los pesos descritos en la Tabla de elementos de clasificación Unicode predeterminada (DUCET) ( Versión 5.0.0 que debería correlacionarse con las _100_Series de clasificación) están bien para el inglés de EE. UU., Pero no para otros idiomas / idiomas. Otros idiomas deben comenzar con el DUCET y luego aplicar reglas de anulación específicas de la configuración regional según lo definido por el proyecto del Repositorio de datos de configuración regional común (CLDR). Por lo que puedo decir, las versiones 1.4 / 1.4.1 se lanzaron en 2006. Para obtener esas anulaciones, descargue el archivo "núcleo" CLDR 1.4 a través de http://unicode.org/Public/cldr/1.4.0/core.zip , luego, en ese archivo zip, vaya a la carpeta de intercalación y busque el archivo XML correspondiente a la configuración regional que se está utilizando. Esos archivos contienen solo las anulaciones y no son conjuntos completos de reglas de clasificación.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.