Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Was ist der Sinn von COLLATIONS für nvarchar (Unicode)-Spalten?

Das Speichern und Darstellen von Zeichen ist eine Sache, und zu wissen, wie man sie sortiert und vergleicht, eine andere.

Unicode-Daten, gespeichert im XML und N -Präfix-Typen in SQL Server können alle Zeichen in allen Sprachen (zum größten Teil, und das ist ihr Ziel) mit einem einzigen Zeichensatz darstellen. Also für NCHAR / NVARCHAR Daten (ich lasse NTEXT weg da es nicht mehr verwendet werden sollte, und XML da es nicht von Sortierungen betroffen ist), ändern die Sortierungen nicht, welche Zeichen gespeichert werden können. Für CHAR und VARCHAR Daten, tun die Kollationen beeinflussen, was gespeichert werden kann, da jede Sortierung auf eine bestimmte Codepage verweist, die bestimmt, was in den Werten 128 - 255 gespeichert werden kann.

Nun, obwohl es eine Standard-Sortierreihenfolge für alle Zeichen gibt, kann dies unmöglich in allen Sprachen und Kulturen funktionieren. Es gibt viele Sprachen, die einige / viele / alle Zeichen gemeinsam haben, aber unterschiedliche Regeln haben, wie sie sortiert werden. Beispielsweise steht der Buchstabe „C“ in den meisten Alphabeten, die diese Buchstaben verwenden, vor dem Buchstaben „D“. Im US-Englisch würde eine Kombination aus „C“ und „H“ (d. h. „CH“ als zwei separate Buchstaben) natürlich vor jeder Zeichenfolge stehen, die mit einem „D“ beginnt. Aber in einigen Sprachen ist die Zwei-Buchstaben-Kombination von "CH" etwas Besonderes und wird nach sortiert "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!';

Rückgabe:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

Beispiele für Sortierregeln in verschiedenen Kulturen finden Sie unter:Collation Charts .

Außerdem entsprechen in einigen Sprachen bestimmte Buchstaben oder Buchstabenkombinationen anderen Buchstaben auf eine Weise, die sie in den meisten anderen Sprachen nicht haben. Zum Beispiel ist ein „å“ nur im Dänischen gleichbedeutend mit „aa“. Aber das „å“ entspricht nicht nur einem einzelnen „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!';

Rückgabe:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Das ist alles sehr komplex, und ich habe noch nicht einmal die Behandlung von rechts-nach-links-Sprachen (Hebräisch und Arabisch), Chinesisch, Japanisch, Kombinieren von Zeichen usw. erwähnt.

Wenn Sie einen tieferen Einblick in die Regeln wünschen, sehen Sie sich den Unicode Collation Algorithm (UCA) . Die obigen Beispiele basieren auf Beispielen in dieser Dokumentation, obwohl ich nicht glaube, dass alle Regeln in der UCA implementiert wurden, insbesondere da die Windows-Sortierungen (Sortierungen nicht beginnend mit SQL_ ) basieren auf Unicode 5.0 oder 6.0, je nachdem, welches Betriebssystem Sie verwenden und welche Version des .NET Framework installiert ist (siehe SortVersion für Einzelheiten).

Das ist es also, was die Collations tun. Wenn Sie alle verfügbaren Sortierungen sehen möchten, führen Sie einfach Folgendes aus:

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