Кодовая точка Unicode 9619 - это символ под названием «Темная тень»: ▓
( http://unicode-table.com/en/search/?q=9619 ).
Используя параметры SQL_Latin1_General_CP1_CI_AS
сортировки и кодовую страницу 1252, я ожидал бы, что приведение / преобразование этого символа Unicode в тип данных не-Unicode приведет к появлению вопросительного знака ( ?
), поскольку кодовая страница 1252 не содержит этот символ, и это похоже на SQL Server поведение при конверсии не может иметь место.
Поэтому мой вопрос: почему SQL Server преобразует этот символ в коде ASCII 166 , который является «Pipe, Разбитая вертикальная черта»: ¦
?
SELECT NCHAR(9619), CAST(NCHAR(9619) AS CHAR(1)), ASCII(CAST(NCHAR(9619) AS CHAR(1)))
sql-server
collation
encoding
unicode
Генри Ли
источник
источник
Ответы:
SQL Server здесь не использует никакой специальной пользовательской логики; он использует стандартные службы операционной системы для выполнения преобразования.
В частности, тип SQL Server и выражение service (
sqlTsEs
) обращаются к подпрограмме ОСWideCharToMultiByte
вkernel32.dll
. SQL Server устанавливает входные параметрыWideCharToMultiByte
так, чтобы подпрограмма выполняла «быстрый перевод». Это быстрее, чем запросить использование определенного символа по умолчанию, если прямой перевод не существует.Быстрый перевод опирается на целевую кодовую страницу, чтобы выполнить сопоставление наилучшим образом для любых непревзойденных символов, как упомянуто в ссылке, которую Мартин Смит предоставил в комментарии к вопросу:
Когда входные параметры установлены для быстрого перевода,
WideCharToMultiByte
вызывается служба ОСGetMBNoDefault
( источник ). Проверка стека вызовов SQL Server при выполнении преобразования, указанного в вопросе, подтверждает это:источник
Преобразование данных Unicode в конкретную кодовую страницу использует так называемую стратегию «наилучшего соответствия» (как отмечено в ответе @ Paul и по ссылке, которую @Martin отметил в комментарии к Вопросу). Согласно этой странице MSDN для кодировки символов в .NET Framework :
Но что именно эти отображения? Эта страница MSDN используется заявить следующее:
Однако это было не совсем правильно. Возможно, «стратегии» определения отображений точно не задокументированы. Хорошо. Но, отображения сами являются документированные, просто не в самых простых местах , чтобы найти.
Итак, благодаря Microsoft, переместившей документацию на GitHub, эта страница теперь гласит следующее (потому что я обновил ее 😸):
Если вы перейдете по следующему URL-адресу, вы увидите список из нескольких файлов, каждый из которых назван для кодовой страницы, в которую он отображает символы Unicode:
ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/
Большинство файлов были в последний раз обновлены (или, по крайней мере, размещены там) 2006-10-04, а один из них был обновлен 2012-03-14. Первая часть этих файлов отображает коды ASCII в эквивалентную кодовую точку Unicode. Но вторая часть каждого файла отображает символы Unicode в их «эквиваленты» ASCII.
Я написал тестовый скрипт, который использует сопоставления Кодовой страницы, чтобы проверить, действительно ли SQL Server использует эти сопоставления. Это можно определить, ответив на эти два вопроса:
?
" символ?Тестовый скрипт слишком длинный, чтобы разместить его здесь, поэтому я разместил его на Pastebin по адресу:
Unicode для сопоставления кодовых страниц в SQL Server
Запуск сценария покажет, что ответом на первый вопрос выше является «Да» (что означает, что все предоставленные сопоставления соблюдаются). Это также покажет, что ответом на второй вопрос является «Нет» (то есть ни один из не нанесенных на карту кодовых точек не превращается ни во что, кроме символа «неизвестный»). Следовательно, этот файл отображения очень точный :-).
источник