Почему SQL Server полагает, что N' 㐢㐢㐢㐢' и N' 㐢㐢㐢' равны?

Мы тестируем наше приложение на совместимость Unicode и выбирали случайные символы вне латинского набора символов для тестирования.

И в латинских и в сопоставленных японцами системах следующее равенство верно (U+3422):

N'㐢㐢㐢㐢' = N'㐢㐢㐢'

но следующее не (U+30C1):

N'チチチチ' = N'チチチ'

Это было обнаружено, когда тестовый сценарий с помощью первого примера (использующий U+3422) нарушил уникальный индекс. Мы должны быть более выборочными о символах, которые мы используем для тестирования? Очевидно, мы не знаем семантическое значение вышеупомянутых сравнений. Это поведение было бы очевидно для носителя языка?

14
задан Ignacio Vazquez-Abrams 12 May 2010 в 12:20
поделиться

3 ответа

У Майкла Каплана есть запись в блоге, где он объясняет, как сравниваются строки Unicode. Все сводится к тому, что строка должна иметь вес, если его нет, то она будет считаться равной пустой строке.

Сортировка: Присяжные не придают этой строке никакого веса

В SQL Server на этот вес влияет определенная колляция. Microsoft добавила соответствующие коллизии для унифицированных идеограмм CJK в Windows XP/2003 и SQL Server 2005. Это сообщение рекомендует использовать Chinese_Simplified_Pinyin_100_CI_AS или Chinese_Simplified_Stroke_Order_100_CI_AS:

Вы всегда можете использовать любые бинарные и бинарные2 колляции, хотя это не даст вам лингвистически корректного результата. Для SQL Server 2005 вы ДОЛЖНЫ использовать Chinese_PRC_90_CI_AS или Chinese_PRC_Stoke_90_CI_AS, которые поддерживают сравнение суррогатных пар (но не лингвистическое). Для SQL Server 2008 вы должны использовать Chinese_Simplified_Pinyin_100_CI_AS и Chinese_Simplified_Stroke_Order_100_CI_AS, которые имеют лучшее лингвистическое сравнение суррогатов. Я предлагаю вам использовать эти коллизии в качестве коллизии вашего сервера/базы данных/таблицы вместо того, чтобы передавать имя коллизии во время сравнения.

Таким образом, следующий оператор SQL будет работать, как и ожидалось:

select * from MyTable where N'' = N'㐀' COLLATE Chinese_Simplified_Stroke_Order_100_CI_AS;

Список всех поддерживаемых коллизий можно найти в MSDN:

SQL Server 2008 Books Online: Windows Collation Name

12
ответ дан 1 December 2019 в 13:21
поделиться

Если вы посмотрите на страницу данных Unihan , у персонажа окажется только поле «K-Source», которое соответствует Карты правительства Южной Кореи.

Я предполагаю, что MS SQL спрашивает: «Является ли этот символ китайским?» Если это так, используйте японский стандарт сортировки, отбрасывая символ, если номер сопоставления недоступен - вероятно, проблема, связанная с SQL-сервером.

Я очень сомневаюсь, что это политический спор, как предположил другой плакат, поскольку у персонажа даже нет карты кодировки Тайваня или Гонконга.

Дополнительная техническая информация: J-Source (японский порядок сортировки, предписанный правительством Японии) пуст, поскольку он, вероятно, использовался только в классической корейской хандже (китайские иероглифы, которые сейчас используются только используется в некоторых контекстах.)

В стандартах сортировки JIS правительства Японии обычно сортируются иероглифы кандзи японцами по чтению (что обычно является приблизительным китайским произношением, когда символы были импортированы в Япония.) Но этот символ, вероятно, мало используется в японском языке и может даже не иметь японского произношения, связанного с ним, поэтому не был добавлен в данные.

2
ответ дан 1 December 2019 в 13:21
поделиться

Этот символ U + 3422 взят из таблиц CJK Unified Ideographs , которые являются относительно неясной (и политически загруженной) частью стандарт Юникода. Я предполагаю, что SQL Server просто не знает эту часть - или, возможно, даже намеренно не реализует ее по политическим соображениям.

Правка : похоже, мое предположение было неверным, и настоящая проблема заключалась в том, что ни латинское, ни японское сопоставление не определяют веса для этого символа.

5
ответ дан 1 December 2019 в 13:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: