Почему SQL Server считает N '㐢 㐢 㐢 㐢' и N '㐢 㐢 㐢' равными?
Мы тестируем наше приложение для совместимости с Unicode и выбираем случайные символы за пределами латинского набора символов для тестирования.
В обеих латинских и японских системах справедливо следующее равенство (U + 3422):
N'㐢㐢㐢㐢' = N'㐢㐢㐢'
но следующее не (U + 30C1):
N'チチチチ' = N'チチチ'
Это было обнаружено, когда тестовый пример с использованием первого примера (с использованием U + 3422) нарушил уникальный индекс. Нужно ли быть более избирательным в отношении символов, которые мы используем для тестирования? Очевидно, мы не знаем семантического значения вышеупомянутых сравнений. Было ли это поведение очевидным для носителей языка?
Ответы
Ответ 1
У Майкла Каплана есть сообщение в блоге, где он объясняет, как сравниваются строки Юникода. Все сводится к тому, что строка должна иметь вес, если она не будет считаться равной пустой строке.
Сортировка всего: Out: Жюри не придаст этой строке никакого веса
В SQL Server на этот вес влияет определенная сортировка. Microsoft добавила соответствующие сопоставления для Унифицированные идеограммы CJK в Windows XP/2003 и SQL Server 2005. Это post рекомендует использовать Chinese_Simplified_Pinyin_100_CI_AS
или Chinese_Simplified_Stroke_Order_100_CI_AS
:
Вы всегда можете использовать любые бинарные и двоичные сопоставления, хотя это не даст вам лингвистический правильный результат. Для 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: имя сортировки Windows
Ответ 2
Этот символ U + 3422 является таблицей CJK Unified Ideographs, которая является относительно неясной (и политически загруженной) частью юникода стандарт. Я предполагаю, что SQL Server просто не знает эту часть или, возможно, даже намеренно не реализует ее из-за политических соображений.
Изменить: похоже, моя догадка была неправильной, и реальная проблема заключалась в том, что ни латинская, ни японская сортировка не определяют весы для этого символа.
Ответ 3
Если вы посмотрите страницу данных Unihan, у символа появится только поле "K-Source", которое соответствует югу Корейское правительство.
Мое предположение заключается в том, что MS SQL спрашивает: "Этот персонаж - китайский символ?" Если это так, используйте японский стандарт сортировки, отбрасывая символ, если номер сортировки недоступен - вероятно, проблема с SQL-сервером.
Я очень сомневаюсь, что это политический спор, поскольку другой плакат предположил, что у персонажа нет даже тайваньского или гонконгского кодирования.
Дополнительная техническая информация: J-Source (японский порядок сортировки, предписанный японским правительством) пуст, поскольку он, вероятно, использовался только в классическом Корейский Hanja (китайские символы, которые теперь используются только в некоторых контекстах.)
Японское правительство JIS стандарты сортировки обычно сортируются Kanji от японского On reading (обычно это приближенное китайское произношение, когда символы были импортированы в Японию.) Но этот персонаж, вероятно, мало используется на японском языке и может даже не иметь японского произношение для общения с ним, поэтому он не был добавлен к данным.