Przechowywanie i reprezentowanie postaci to jedno, a umiejętność ich sortowania i porównywania to drugie.
Dane Unicode przechowywane w XML
i N
-typy z przedrostkiem w SQL Server, mogą reprezentować wszystkie znaki we wszystkich językach (w większości i to jest jego celem) za pomocą jednego zestawu znaków. Więc dla NCHAR
/ NVARCHAR
dane (pomijam NTEXT
ponieważ nie powinien być już używany, a XML
ponieważ sortowanie nie ma na niego wpływu), sortowania nie zmieniają tego, jakie znaki mogą być przechowywane. Dla CHAR
i VARCHAR
danych, sortowania do wpływają na to, co może być przechowywane, ponieważ każde sortowanie wskazuje na konkretną stronę kodową, która określa, co może być przechowywane w wartościach 128 - 255.
Teraz, chociaż istnieje domyślna kolejność sortowania dla wszystkich znaków, nie może ona działać we wszystkich językach i kulturach. Istnieje wiele języków, które dzielą niektóre / wiele / wszystkie znaki, ale mają różne zasady ich sortowania. Na przykład litera „C” występuje przed literą „D” w większości alfabetów, które używają tych liter. W angielskim amerykańskim kombinacja „C” i „H” (tj. „CH” jako dwie oddzielne litery) naturalnie pojawia się przed każdym ciągiem zaczynającym się od „D”. Ale w kilku językach dwuliterowa kombinacja „CH” jest wyjątkowa i jest sortowana po „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!';
Zwroty:
Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!
Aby zobaczyć przykłady reguł sortowania w różnych kulturach, zobacz:Wykresy sortowania .
Ponadto w niektórych językach pewne litery lub kombinacje liter odpowiadają innym literom w sposób, w jaki nie występują one w większości innych języków. Na przykład tylko w języku duńskim „å” oznacza „aa”. Ale „å” nie oznacza tylko jednego „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!';
Zwroty:
Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!
To wszystko jest bardzo skomplikowane i nawet nie wspomniałem o obsłudze języków pisanych od prawej do lewej (hebrajskiego i arabskiego), chińskiego, japońskiego, łączenia znaków itp.
Jeśli chcesz dokładniej poznać zasady, zapoznaj się z Algorytm sortowania Unicode (UCA) . Powyższe przykłady są oparte na przykładach z tej dokumentacji, chociaż nie wierzę, że wszystkie zasady w UCA zostały zaimplementowane, zwłaszcza od czasu porównywania Windows (porównania nie zaczynając od SQL_
) są oparte na standardzie Unicode 5.0 lub 6.0, w zależności od używanego systemu operacyjnego i zainstalowanej wersji .NET Framework (zobacz SortVersion
szczegóły).
Tak właśnie robią Collations. Jeśli chcesz zobaczyć wszystkie dostępne sortowania, po prostu uruchom następujące polecenie:
SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];