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

Qual è il punto di COLLATIONS per le colonne nvarchar (Unicode)?

Memorizzare e rappresentare i personaggi è una cosa, e saperli ordinare e confrontare è un'altra.

Dati Unicode, archiviati in XML e N -tipi con prefisso in SQL Server, possono rappresentare tutti i caratteri in tutte le lingue (per la maggior parte, e questo è il suo obiettivo) con un unico set di caratteri. Quindi per NCHAR / NVARCHAR dati (escludo NTEXT poiché non dovrebbe più essere utilizzato e XML poiché non è influenzato dalle Fascicolazioni), le Fascicolazioni non cambiano i caratteri che possono essere archiviati. Per CHAR e VARCHAR dati, le Collations fa influiscono su ciò che può essere archiviato poiché ciascuna Fascicolazione punta a una particolare tabella codici, che determina ciò che può essere archiviato nei valori 128 - 255.

Ora, mentre esiste un ordinamento predefinito per tutti i caratteri, non è possibile che funzioni in tutte le lingue e culture. Esistono molte lingue che condividono alcuni/molti/tutti i caratteri, ma hanno regole diverse su come ordinarli. Ad esempio, la lettera "C" viene prima della lettera "D" nella maggior parte degli alfabeti che utilizzano quelle lettere. Nell'inglese americano, una combinazione di "C" e "H" (cioè "CH" come due lettere separate) verrebbe naturalmente prima di qualsiasi stringa che inizia con una "D". Ma, in alcune lingue, la combinazione di due lettere di "CH" è speciale e ordina dopo "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!';

Resi:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

Per vedere esempi di regole di ordinamento tra diverse culture, vedere:Grafici di confronto .

Inoltre, in alcune lingue alcune lettere o combinazioni di lettere equivalgono ad altre lettere in modi che non nella maggior parte delle altre lingue. Ad esempio, solo in danese una "å" equivale a "aa". Ma la "å" non 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!';

Resi:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Tutto ciò è molto complesso e non ho nemmeno menzionato la gestione delle lingue da destra a sinistra (ebraico e arabo), cinese, giapponese, combinazione di caratteri, ecc.

Se desideri approfondire le regole, dai un'occhiata a Unicode Collation Algorithm (UCA) . Gli esempi sopra si basano su esempi in quella documentazione, anche se non credo che tutte le regole nell'UCA siano state implementate, soprattutto perché le regole di confronto di Windows (le regole di confronto non a partire da SQL_ ) sono basati su Unicode 5.0 o 6.0, a seconda del sistema operativo in uso e della versione di .NET Framework installata (consultare SortVersion per i dettagli).

Quindi questo è ciò che fanno le Collations. Se vuoi vedere tutte le regole di confronto disponibili, esegui quanto segue:

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