Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jaki jest sens COLLATIONS dla kolumn nvarchar (Unicode)?

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];


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak ustawić nazwę aplikacji w parametrach połączenia ADODB?

  2. jdbc.SQLServerException:Logowanie nie powiodło się dla użytkownika dla dowolnego użytkownika

  3. Używanie sp_help_jobschedule w SQL Server

  4. Odmowa dostępu podczas wstawiania pliku do tabeli plików Sql Server 2012 przy użyciu File.CreateFile w witrynie ASP.NET

  5. Jak zahaszować hasło administratora w tabeli Użytkownicy?