2015-09-21 2 views
1

Вслед за https://stackoverflow.com/a/32233795/14731, я с удивлением обнаружил, что:Почему знак подчеркивания SQL_Latin1_General_CP1_CI_AS под знаком подчеркивания?

DECLARE @SampleData TABLE (ANSI VARCHAR(50), UTF16 NVARCHAR(50)); 
INSERT INTO @SampleData (ANSI, UTF16) VALUES 
    ('##MS_PolicyTsqlExecutionLogin##', N'##MS_PolicyTsqlExecutionLogin##'), 
    ('_gaia', N'_gaia'); 

SELECT sd.ANSI AS [ANSI-SQL_Latin1_General_CP1_CI_AS] 
FROM @SampleData sd 
ORDER BY sd.ANSI COLLATE SQL_Latin1_General_CP1_CI_AS ASC; 

SELECT sd.UTF16 AS [UTF16-SQL_Latin1_General_CP1_CI_AS] 
FROM @SampleData sd 
ORDER BY sd.UTF16 COLLATE SQL_Latin1_General_CP1_CI_AS ASC; 

Результаты в:

ANSI-SQL_Latin1_General_CP1_CI_AS 
------------------------------------- 
##MS_PolicyTsqlExecutionLogin## 
_gaia 

UTF16-SQL_Latin1_General_CP1_CI_AS 
------------------------------------- 
##MS_PolicyTsqlExecutionLogin## 
_gaia 

Когда, в соответствии с «Why doesn't ICU4J match UTF-8 sort order?», результаты Unicode должны быть в обратном порядке , Почему это так?

ответ

0

Оказывается, что @一二三 права насчет SQL Server не выполнения правил Unicode Collation алгоритма по умолчанию, но он был неправ об этом, используя кодовую страницу для сортировки Юникода. https://stackoverflow.com/a/32706510/14731 содержит подробное объяснение того, как действительно выполняется сортировка юникода.

1

В первую очередь: связанный вопрос - Why doesn't ICU4J match UTF-8 sort order? - пока не показано, что он еще совсем исправлен ;-).

Это родственный информация в сторону, давайте посмотрим на различные части:

  1. VARCHAR поле с COLLATE SQL_Latin1_General_CP1_CI_AS:

    Это будет сортировать в первую очередь на основе значений ASCII, и в случае алфавитных символов , сортирует и сравнивает на основе правил, определенных в Code Page 1 (aka Code Page 1252).

    # символ ASCII-код 35, а _ символ ASCII код 95. Это не буквы алфавита поэтому следует предположить, что они будут отсортированы с # приходит первым, делая в ASC конечный порядок, как вы делаете здесь ,

  2. NVARCHAR поле с COLLATE SQL_Latin1_General_CP1_CI_AS:

    Это будет сортировать по правилам Unicode. В Юникоде нет кодовых страниц, но может быть культурными различиями, которые переопределяют правила сортировки по умолчанию и порядок. И, чтобы сделать вещи еще более интересными, как базовые правила, так и специальные ограничения в отношении культуры/локали могут меняться с годами. Поставщики программного обеспечения не всегда быстро внедряют новые версии стандартов. Это не отличается от различных браузеров, реализующих различные особенности W3C в разные моменты времени. Основные обновления в SQL Server поставлялись с версией 2008, в которой были представлены серии сопоставлений 100. В SQL Server 2012 были введены варианты серии 90 и 100, заканчивающиеся на _SC, для обработки дополнительных символов (т. Е. Остальная часть символов UTF-16 за пределами набора UCS-2).

    Возвращаясь к тому, что было упомянуто мгновение назад, каждый язык/культура может указывать переопределения любого из правил (а не только правила сортировки). Текущая версия, 28 (выпущено всего 4 дня назад !!), имеет следующий за локали США (находится по адресу: http://www.unicode.org/repos/cldr/tags/release-27/common/collation/en_US_POSIX.xml)

    <collation type="standard"> 
        <cr> 
        <![CDATA[ 
        &A<*'\u0020'-'/'<*0-'@'<*ABCDEFGHIJKLMNOPQRSTUVWXYZ<*'['-'`'<*abcdefghijklmnopqrstuvwxyz <*'{'-'\u007F' 
        ]]> 
        </cr> 
    </collation> 
    

    Чтение новый синтаксис не супер-легкий, но я не» Думаю, они переупорядочивают любой из этих знаков препинания. И если вы перейдете к их Collation Charts и нажмите на ссылку 4 вниз (начиная сверху, влево), для «Пунктуации», она, безусловно, перечисляет «_» как приближающуюся перед всеми, кроме одного символа.

    Если мы вернемся несколько версий, мы находим (по адресу: http://www.unicode.org/repos/cldr/tags/release-23/common/collation/en_US_POSIX.xml):

    <collation type="standard"> 
        <rules> 
        <reset>A</reset> 
        <pc>!"#$%&'()*+,-./</pc> 
        <pc>:;<=>[email protected]</pc> 
        <pc>ABCDEFGHIJKLMNOPQRSTUVWXYZ</pc> 
        <pc>[\]^_`</pc> 
        <pc>abcdefghijklmnopqrstuvwxyz</pc> 
        <pc>{|}~</pc> 
        </rules> 
    </collation> 
    

    Теперь вот это делает конечно, посмотреть, как они заказаны, и в том же порядке, как и значение ASCII ?

    Если вы измените URL-адрес, чтобы указать на версию 24, это будет выглядеть так же, как и текущая версия 28 XML.

    В соответствии с датами выпуска, найденными здесь CLDR Releases/Downloads, версия 24 вышла в 2013 году, после того, как были закодированы серии сортировок 100.

+0

У вас есть источник претензии, что SQL Server использует правила UCA или CLDR? Вы ссылаетесь на правила POSIX, но почему Windows использует эти правила для Latin1 (это другой набор символов)? Кроме того, два заказа POSIX, которые вы даете, одинаковы, они просто [обновили синтаксис] (http://unicode.org/cldr/trac/ticket/5551). –

+0

@ 一 二三 см. Http://stackoverflow.com/a/32706510/14731 – Gili

+0

Хорошая теория, но я не думаю, что это действительно правильно. Оказывается, что версии сопоставления диаграмм публикуются по адресу http://cldr.unicode.org/index/charts. Сравнение http://www.unicode.org/cldr/charts/23/by_type/patterns.characters.html#6cf943e652b01478 с http://www.unicode.org/cldr/charts/28/by_type/core_data.alphabetic_information.html # 6cf943e652b01478 похоже, что порядок сортировки (для двух символов, о котором идет речь) идентичен. Таким образом, либо SQL Server использует старую версию, либо что-то еще должно продолжаться. – Gili

Смежные вопросы