sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cuál es el punto de COLLATIONS para columnas nvarchar (Unicode)?

Almacenar y representar caracteres es una cosa, y saber ordenarlos y compararlos es otra.

Datos Unicode, almacenados en el XML y N -Los tipos prefijados en SQL Server pueden representar todos los caracteres en todos los idiomas (en su mayor parte, y ese es su objetivo) con un solo conjunto de caracteres. Así que para NCHAR / NVARCHAR datos (estoy omitiendo NTEXT ya que no debería usarse más, y XML ya que no se ve afectado por intercalaciones), las intercalaciones no cambian los caracteres que se pueden almacenar. Para CHAR y VARCHAR datos, las Intercalaciones hacen afectan lo que se puede almacenar, ya que cada colación apunta a una página de códigos en particular, lo que determina lo que se puede almacenar en los valores 128 - 255.

Ahora, si bien existe un orden de clasificación predeterminado para todos los caracteres, no es posible que funcione en todos los idiomas y culturas. Hay muchos idiomas que comparten algunos/muchos/todos los caracteres, pero tienen diferentes reglas sobre cómo clasificarlos. Por ejemplo, la letra "C" viene antes de la letra "D" en la mayoría de los alfabetos que usan esas letras. En inglés estadounidense, una combinación de "C" y "H" (es decir, "CH" como dos letras separadas) vendría naturalmente antes de cualquier cadena que comience con una "D". Pero, en algunos idiomas, la combinación de dos letras "CH" es especial y se ordena después "D":

IF (   N'CH' COLLATE Czech_CI_AI > N'D' COLLATE Czech_CI_AI
   AND N'C'  COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   AND N'CI' COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   ) PRINT 'Czech_CI_AI';

IF (   N'CH' COLLATE Czech_100_CI_AI > N'D' COLLATE Czech_100_CI_AI
   AND N'C'  COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   AND N'CI' COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   ) PRINT 'Czech_100_CI_AI';

IF (   N'CH' COLLATE Slovak_CI_AI > N'D' COLLATE Slovak_CI_AI
   AND N'C'  COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   AND N'CI' COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   ) PRINT 'Slovak_CI_AI';

IF (   N'CH' COLLATE Slovak_CS_AS > N'D' COLLATE Slovak_CS_AS
   AND N'C'  COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   AND N'CI' COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   ) PRINT 'Slovak_CS_AS';

IF (   N'CH' COLLATE Latin1_General_100_CI_AS > N'D' COLLATE Latin1_General_100_CI_AS
   AND N'C'  COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   AND N'CI' COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   ) PRINT 'Latin1_General_100_CI_AS'
ELSE PRINT 'Nope!';

Devoluciones:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

Para ver ejemplos de reglas de clasificación en varias culturas, consulte:Gráficos de clasificación .

Además, en algunos idiomas, ciertas letras o combinaciones de letras equivalen a otras letras en formas que no lo hacen en la mayoría de los otros idiomas. Por ejemplo, solo en danés una "å" equivale a "aa". Pero, la "å" no equivale a una sola "a":

IF (N'aa' COLLATE Danish_Greenlandic_100_CI_AI =  N'å' COLLATE Danish_Greenlandic_100_CI_AI
AND N'a'  COLLATE Danish_Greenlandic_100_CI_AI <> N'å' COLLATE Danish_Greenlandic_100_CI_AI
   ) PRINT 'Danish_Greenlandic_100_CI_AI';

IF (   N'aa' COLLATE Danish_Norwegian_CI_AI =  N'å' COLLATE Danish_Norwegian_CI_AI
   AND N'a'  COLLATE Danish_Norwegian_CI_AI <> N'å' COLLATE Danish_Norwegian_CI_AI
   ) PRINT 'Danish_Norwegian_CI_AI';

IF (   N'aa' COLLATE Latin1_General_100_CI_AI =  N'å' COLLATE Latin1_General_100_CI_AI
   AND N'a'  COLLATE Latin1_General_100_CI_AI <> N'å' COLLATE Latin1_General_100_CI_AI
   ) PRINT 'Latin1_General_100_CI_AI'
ELSE PRINT 'Nope!';

Devoluciones:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Todo esto es muy complejo y ni siquiera he mencionado el manejo de idiomas de derecha a izquierda (hebreo y árabe), chino, japonés, combinación de caracteres, etc.

Si desea obtener información detallada sobre las reglas, consulte el Unicode Collation Algorithm (UCA) . Los ejemplos anteriores se basan en ejemplos de esa documentación, aunque no creo que se hayan implementado todas las reglas en el UCA, especialmente desde que las intercalaciones de Windows (intercalaciones no comenzando con SQL_ ) se basan en Unicode 5.0 o 6.0, según el sistema operativo que utilice y la versión de .NET Framework que esté instalada (consulte SortVersion para más detalles).

Así que eso es lo que hacen las colaciones. Si desea ver todas las intercalaciones disponibles, simplemente ejecute lo siguiente:

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];