sql >> Database >  >> RDS >> Sqlserver

Wat is het nut van COLLATIONS voor nvarchar (Unicode)-kolommen?

Tekens opslaan en weergeven is één ding, weten hoe je ze moet sorteren en vergelijken is iets anders.

Unicode-gegevens, opgeslagen in de XML en N -prefixtypes in SQL Server, kunnen alle tekens in alle talen vertegenwoordigen (voor het grootste deel, en dat is het doel) met een enkele tekenset. Dus voor NCHAR / NVARCHAR gegevens (ik laat NTEXT weg) omdat het niet meer mag worden gebruikt, en XML aangezien het niet wordt beïnvloed door Collations), veranderen de Collations niet welke tekens kunnen worden opgeslagen. Voor CHAR en VARCHAR gegevens, de Collations doen beïnvloeden wat kan worden opgeslagen omdat elke sortering verwijst naar een bepaalde codepagina, die bepaalt wat kan worden opgeslagen in waarden 128 - 255.

Hoewel er een standaard sorteervolgorde voor alle tekens is, kan dat onmogelijk in alle talen en culturen werken. Er zijn veel talen die sommige / veel / alle tekens delen, maar verschillende regels hebben om ze te sorteren. De letter "C" komt bijvoorbeeld voor de letter "D" in de meeste alfabetten die deze letters gebruiken. In het Amerikaans-Engels zou een combinatie van "C" en "H" (d.w.z. "CH" als twee afzonderlijke letters) natuurlijk voor elke tekenreeks komen die met een "D" begint. Maar in een paar talen is de tweelettercombinatie van "CH" speciaal en sorteert na "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!';

Retourneren:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

Zie voor voorbeelden van sorteerregels in verschillende culturen:Collation Charts .

Ook zijn in sommige talen bepaalde letters of combinaties van letters gelijk aan andere letters op een manier die ze in de meeste andere talen niet hebben. Alleen in het Deens is een "å" bijvoorbeeld gelijk aan "aa". Maar de "å" is niet gelijk aan slechts een enkele "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!';

Retourneren:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Dit is allemaal zeer complex, en dan heb ik het nog niet eens gehad over de behandeling van rechts-naar-links talen (Hebreeuws en Arabisch), Chinees, Japans, het combineren van karakters, enz.

Als je diepgaand inzicht in de regels wilt, bekijk dan de Unicode Collation Algorithm (UCA) . De bovenstaande voorbeelden zijn gebaseerd op voorbeelden in die documentatie, hoewel ik niet geloof dat alle regels in de UCA zijn geïmplementeerd, vooral sinds de Windows-sorteringen (sorteringen niet beginnend met SQL_ ) zijn gebaseerd op Unicode 5.0 of 6.0, afhankelijk van het besturingssysteem dat u gebruikt en de versie van het .NET Framework die is geïnstalleerd (zie SortVersion voor details).

Dat is dus wat de Collations doen. Als u alle beschikbare sorteringen wilt zien, voert u gewoon het volgende uit:

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


  1. Mysql groeperen per weekdag, vul ontbrekende weekdagen in

  2. Hoe gegevens uit een pl/sql-functie te halen als een parameter meer dan één waarde heeft in functie met enkele parameters?

  3. Splits IPv4-adres in 4 cijfers in Oracle sql

  4. Selecteer onderscheiden op blob