sql >> Database teknologi >  >> RDS >> Sqlserver

Hvad er meningen med SAMLINGER for nvarchar (Unicode) kolonner?

At gemme og repræsentere karakterer er én ting, og at vide, hvordan man sorterer og sammenligner dem er en anden.

Unicode-data, gemt i XML og N -præfikstyper i SQL Server, kan repræsentere alle tegn på alle sprog (for det meste, og det er dens mål) med et enkelt tegnsæt. Så for NCHAR / NVARCHAR data (jeg udelader NTEXT da det ikke skal bruges længere, og XML da det ikke er påvirket af Collations), ændrer Collations ikke, hvilke tegn der kan gemmes. For CHAR og VARCHAR data, gør sorteringerne påvirke, hvad der kan gemmes, når hver sortering peger på en bestemt kodeside, som bestemmer, hvad der kan gemmes i værdierne 128 - 255.

Nu, mens der er en standard sorteringsrækkefølge for alle tegn, kan det umuligt fungere på tværs af alle sprog og kulturer. Der er mange sprog, der deler nogle/mange/alle tegn, men har forskellige regler for, hvordan de skal sorteres. For eksempel kommer bogstavet "C" før bogstavet "D" i de fleste alfabeter, der bruger disse bogstaver. På amerikansk engelsk vil en kombination af "C" og "H" (dvs. "CH" som to separate bogstaver) naturligvis komme før enhver streng, der begynder med et "D". Men på nogle få sprog er kombinationen af ​​to bogstaver af "CH" speciel og sorterer efter "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!';

Returnerer:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

For at se eksempler på sorteringsregler på tværs af forskellige kulturer, se venligst:Sorteringsdiagrammer .

På nogle sprog er visse bogstaver eller kombinationer af bogstaver lig med andre bogstaver på måder, som de ikke gør på de fleste andre sprog. For eksempel er det kun på dansk, at et "å" er lig med "aa". Men "å" er ikke lig med et enkelt "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!';

Returnerer:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Det hele er meget komplekst, og jeg har ikke engang nævnt håndtering af højre-til-venstre-sprog (hebraisk og arabisk), kinesisk, japansk, kombination af tegn osv.

Hvis du vil have en dyb indsigt i reglerne, så tjek Unicode Collation Algorithm (UCA) . Eksemplerne ovenfor er baseret på eksempler i den dokumentation, selvom jeg ikke mener, at alle reglerne i UCA er blevet implementeret, især siden Windows-sammenstillingerne (sorteringer ikke starter med SQL_ ) er baseret på Unicode 5.0 eller 6.0, afhængigt af hvilket OS du bruger og versionen af ​​.NET Framework, der er installeret (se SortVersion for detaljer).

Så det er det, Collations gør. Hvis du vil se alle de tilgængelige sorteringer, skal du blot køre følgende:

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


  1. Brug FILEGROUP_NAME() til at returnere navnet på en filgruppe i SQL Server

  2. MYSQL ind i outfil adgang nægtet - men min bruger har ALT adgang.. og mappen er CHMOD 777

  3. Er der en databasemotor, der tillader forespørgselsfeltbegrænsninger angivet af RegEx?

  4. SQLite - Opdater data