Хранение и представление символов — это одно, а умение их сортировать и сравнивать — другое.
Данные Unicode, хранящиеся в типах с префиксом XML
и N
в SQL Server, могут представлять все символы на всех языках (по большей части, и это его цель) с помощью одного набора символов. Таким образом, для данных NCHAR
/NVARCHAR
(я опускаю NTEXT
, так как его больше не следует использовать, и XML
, так как на него не влияют сопоставления), сопоставления не меняют, какие символы могут быть сохранены. Для данных CHAR
и VARCHAR
параметры сортировки do влияют на то, что может быть сохранено, поскольку каждое сопоставление указывает на конкретную кодовую страницу, которая определяет, что может храниться в значениях 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!';
Возвращает:
Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!
Чтобы увидеть примеры правил сортировки для разных культур, см. таблицы сопоставления.
Кроме того, в некоторых языках определенные буквы или комбинации букв приравниваются к другим буквам, чего нет в большинстве других языков. Например, только в датском языке «å» соответствует «аа». Но «å» не означает только одну «а»:
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!';
Возвращает:
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];
person
Solomon Rutzky
schedule
30.09.2015
ש
и сделал «упорядочить по», поэтому он должен упорядочить по своим символам, включаяש
. .....нет ? - person Royi Namir   schedule 18.03.2012NVARCHAR
/NCHAR
. Для полейVARCHAR
иCHAR
сортировка действительно определяет, что может там храниться, поскольку она содержит LCID, который определяет кодовую страницу. - person Solomon Rutzky   schedule 30.09.2015