Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Какъв е смисълът на COLLATIONS за колони nvarchar (Unicode)?

Съхраняването и представянето на символи е едно, а знанието как да ги сортирате и сравнявате е друго.

Unicode данни, съхранени в XML и N -префиксирани типове в SQL Server, може да представя всички знаци на всички езици (в по-голямата си част и това е неговата цел) с един набор от знаци. Така че за NCHAR / NVARCHAR данни (изпускам NTEXT тъй като не трябва да се използва повече, и XML тъй като не се влияе от Collations), Collations не променят кои знаци могат да бъдат съхранени. За 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!';

Връща:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

За да видите примери за правила за сортиране в различни култури, моля, вижте:Collation Charts .

Освен това в някои езици определени букви или комбинации от букви се равняват на други букви по начини, които не са в повечето други езици. Например само на датски "å" се равнява на "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!';

Връща:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

Всичко това е много сложно и дори не съм споменал обработката на езици с писане отдясно наляво (иврит и арабски), китайски, японски, комбиниране на знаци и т.н.

Ако искате задълбочена представа за правилата, вижте алгоритъма за съпоставяне на Unicode (UCA) . Примерите по-горе се основават на примери в тази документация, въпреки че не вярвам, че всички правила в UCA са приложени, особено след сравнението на Windows (съпоставяне не започвайки с SQL_ ) са базирани на Unicode 5.0 или 6.0, в зависимост от това коя операционна система използвате и версията на .NET Framework, която е инсталирана (вижте SortVersion за подробности).

Така че това е, което правят Collations. Ако искате да видите всички налични колации, просто изпълнете следното:

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. Активни сесии и състояние на SQL Server

  2. Как да напиша UTF-8 знаци с помощта на групово вмъкване в SQL Server?

  3. Намиране на нов ред в текстов низ в SQL таблица?

  4. VBA код за добавяне на свързана таблица с първичен ключ

  5. Проблем с разрешения при стартиране на SSIS пакет от Sql Job