Ответ 1
Хранение и представление символов - это одно, а знание того, как их сортировать и сравнивать, - другое.
Данные Unicode, хранящиеся в типах XML
и N
-prefixed в SQL Server, могут представлять все символы на всех языках (по большей части, и это является его целью) с одним набором символов. Поэтому для данных NCHAR
/NVARCHAR
(я опускаю NTEXT
, так как они больше не должны использоваться, и XML
, поскольку на них не влияют параметры сортировки), параметры сортировки не изменяют то, какие символы могут быть сохранены., Для данных CHAR
и VARCHAR
параметры сортировки влияют на то, что может быть сохранено, так как каждое сопоставление указывает на конкретную кодовую страницу, которая определяет, что может храниться в значениях 128 - 255.
Теперь, хотя для всех символов существует порядок сортировки по умолчанию, он не может работать на всех языках и культурах. Есть много языков, которые разделяют некоторые/многие/все символы, но имеют разные правила их сортировки. Например, буква "C" стоит перед буквой "D" в большинстве алфавитов, которые используют эти буквы. В американском английском языке комбинация "C" и "H" (то есть "CH" в виде двух отдельных букв), естественно, будет стоять перед любой строкой, начинающейся с "D". Но в некоторых языках двухбуквенная комбинация "CH" является особенной и сортируется после "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!';
Returns:
Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!
Чтобы увидеть примеры правил сортировки в разных культурах, см. диаграммы сопоставления.
Кроме того, в некоторых языках определенные буквы или комбинации букв приравниваются к другим буквам так, как это не происходит в большинстве других языков. Например, только на датском языке "å" приравнивается к "aa". Но "å" не означает только "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!';
Returns:
Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!
Все это очень сложно, и я даже не упомянул обработку языков справа налево (иврит и арабский), китайского, японского, комбинирование символов и т.д.
Если вы хотите получить более глубокое представление о правилах, ознакомьтесь с алгоритмом сопоставления Unicode (UCA). Приведенные выше примеры основаны на примерах в этой документации, хотя я не верю, что все правила в UCA были реализованы, тем более что параметры сортировки Windows (параметры сортировки не начинаются с SQL_
) основаны на Unicode 5.0 или 6.0, в зависимости от в той операционной системе, которую вы используете, и в версии .NET Framework, которая установлена (подробности см. в SortVersion).
Это то, что делают сортировки. Если вы хотите просмотреть все доступные параметры сортировки, просто выполните следующее:
SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];