Я хочу установить строковую переменную Unicode для конкретного символа на основе ее кодовой точки Unicode.
Я хочу использовать кодовую точку за пределами 65535, но база данных SQL Server 2008 R2 имеет параметры сортировки SQL_Latin1_General_CP1_CI_AS
.
Согласно документации NCHAR от Microsoft , NCHAR
функция принимает целое число следующим образом:
integer_expression
Когда сопоставление базы данных не содержит флаг дополнительных символов (SC), это положительное целое число от 0 до 65535 (от 0 до 0xFFFF). Если указано значение вне этого диапазона, возвращается значение NULL. Для получения дополнительной информации о дополнительных символах см. Поддержка сопоставления и Unicode.
Когда сортировка базы данных поддерживает флаг дополнительных символов (SC), это положительное целое число от 0 до 1114111 (от 0 до 0x10FFFF). Если указано значение вне этого диапазона, возвращается значение NULL.
Итак, этот код:
SELECT NCHAR(128512);
Возвращает NULL
в эту базу данных.
Я хотел бы вернуть то же самое, что и это:
SELECT N'😀';
Как я могу установить строковую переменную Unicode (например, nvarchar) для эмодзи, используя код (без использования фактического символа эмодзи) в базе данных, где сопоставление «не содержит флаг дополнительного символа (SC)»?
Полный список эмодзи кодов Unicode
(В конечном итоге я хочу, чтобы любой персонаж работал. Я просто выбрал смайлики для удобства.)
(Хотя сервером является SQL Server 2008 R2, мне также любопытно узнать о любых решениях для более поздних версий.)
Предполагая, что нет никакого способа, могу ли я сослаться на встроенную пользовательскую функцию в другой базе данных, которая имела соответствующее сопоставление?
Как найти сопоставление с флагом «дополнительный символ»?
Это не возвращает никаких записей на нашем сервере:
SELECT * FROM sys.fn_helpcollations()
WHERE name LIKE 'SQL%[_]SC';
Кажется, что SQL Server 2012 представил, Latin1_General_100_CI_AS_SC
который будет работать. Можете ли вы установить сопоставления на более старых экземплярах?
Сравнение ссылок:
- Ответ. В чем разница между char, nchar, varchar и nvarchar в SQL Server?
- Информация о сопоставлении дополнительных символов Microsoft
- Список сортировки Microsoft SQL Server 2008 R2
Есть ли объяснение того, почему, независимо от параметров сортировки, SQL Server может понимать расширенные символы и работать с ними, кроме как с точки зрения NCHAR
?
Ответы:
Кодировка UCS-2 всегда составляет 2 байта на символ и имеет диапазон от 0 до 65535 (0x0000 - 0xFFFF). UTF-16 (независимо от Big Endian или Little Endian) имеет диапазон от 0 до 1114111 (0x0000 - 0x10FFFF). Диапазон 0 - 65535 / 0x0000 - 0xFFFF UTF-16 составляет 2 байта на символ, а диапазон выше 65536 / 0xFFFF составляет 4 байта на символ.
Windows и SQL Server начали использовать кодировку UCS-2, потому что она была доступна, а UTF-16 еще не был завершен. К счастью, однако, в конструкции UCS-2 и UTF-16 было внесено достаточно предварительных мыслей, чтобы отображения UCS-2 были полным подмножеством отображений UTF-16 (то есть: диапазон 0 - 65535 / 0x0000 - 0xFFFF UTF-16 - это UCS-2). И, диапазон 65536 - 1114111 (0x10000 - 0x10FFFF) UTF-16 состоит из двух кодовых точек в диапазоне UCS-2 (диапазоны 0xD800 - 0xDBFF и 0xDC00 - 0xDFFF, в частности), которые были зарезервированы для этой цели и в противном случае не имеют смысл. Эта комбинация двух кодовых точек известна как суррогатная пара, а суррогатные пары представляют символы за пределами диапазона UCS-2, которые известны как дополнительные символы.
Вся эта информация объясняет два аспекта данных
NVARCHAR
/ Unicode в SQL Server:NCHAR()
) не обрабатывать суррогатных пар / дополнительные символы , если не используется дополнительный символ-Aware Collation (SCA, то есть один с_SC
, или_140_
, но не_BIN*
в названии) , потому что не-SCA Параметры сортировки (особенноSQL_
Сопоставления) были первоначально реализованы до завершения UTF-16 (я думаю, что в 2000 году). Номера дляSQL_
сортировок, которые имеют_90_
или_100_
в своих именах, но не_SC
имеют минимальной поддержки дополнительных символов с точки зрения сравнения и сортировки.NVARCHAR
/NCHAR
/XML
/,NTEXT
поскольку UCS-2 и UTF-16 являются точно такими же байтовыми последовательностями. Единственное отличие состоит в том, что UTF-16 использует суррогатные кодовые точки для создания суррогатных пар, а UCS-2 просто не может сопоставить их с какими-либо символами, поэтому они отображаются во встроенных функциях как два неизвестных символа.Имея в виду эту справочную информацию, теперь мы можем перейти к конкретным вопросам:
Это может произойти только в том случае, если текущая база данных - там, где выполняется запрос - имеет сопоставление по умолчанию, которое является дополнительным символьно-зависимым, и было введено в SQL Server 2012. Встроенные функции, которые имеют строковые входные параметры, могут иметь сопоставление встроенный через
COLLATE
предложение (т.е.LEN(N'string' COLLATE Some_Collation_SC)
) и не должен выполняться в базе данных, которая имеет сопоставление по умолчанию SCA. Тем не менее, встроенные функции, такие какNCHAR()
принятьINT
входной параметр, иCOLLATE
в этом контексте предложение именно поэтомуNCHAR()
поддерживаются дополнительные символы только в том случае, если в текущей базе данных используется сопоставление по умолчанию с поддержкой дополнительных символов; но это не нужно). неудобства, которые можно изменить, поэтому, пожалуйста, проголосуйте за мое предложение:Функция NCHAR () всегда должна возвращать дополнительный символ для значений 0x10000 - 0x10FFFF независимо от параметров сортировки активной базы данных по умолчанию ).Как SQL Server может хранить и извлекать дополнительные символы без потери данных, было объяснено в верхней части этого ответа. Но это не правда, что
NCHAR
это единственная встроенная функция, которая имеет проблемы с дополнительными символами (если не используется сопоставление SCA). Например,LEN(N'😀' COLLATE SQL_Latin1_General_CP1_CI_AS)
возвращает значение 2, аLEN(N'😀' COLLATE Latin1_General_100_CI_AS_SC)
возвращает значение 1.Если вы перейдете ко второй ссылке, опубликованной в Вопросе (т.е. «Информация о сопоставлении дополнительных символов Microsoft»), и прокрутите немного вниз, вы увидите диаграмму встроенных функций и их поведение в зависимости от эффективного сопоставления.
В версии SQL Server до 2012 вы не можете. Но, начиная с SQL Server 2012, вы можете использовать следующий запрос:
Ваш запрос был близок, но шаблон начался с того,
SQL
что параметры сортировки SQL Server (то есть те, которые начинаются сSQL_
) на некоторое время устарели в пользу параметров сравнения Windows (те, которые не начинаются сSQL_
). Таким образом, параметрыSQL_
сортировки не обновляются и, следовательно, не имеют более новых версий, которые включали бы этот_SC
параметр (и начиная с SQL Server 2017 все новые параметры сортировки автоматически поддерживают дополнительные символы и не требуют или не имеют_SC
флаг; и да, запрос это показано выше, учитывает это, а также_UTF8
подборку сопоставлений, добавленных в SQL Server 2019).Нет, вы не можете установить параметры сортировки в предыдущую версию SQL Server.
Когда сортировка SCA не используется, вы можете ввести кодовые точки выше 65535 / U + FFFF двумя способами:
NCHAR()
функции, каждый из которых состоит из одной части пары.VARBINARY
формы байтовой последовательности Little Endian (т.е. обращенной).Эти два метода вставки дополнительных символов / суррогатных пар будут работать, даже если эффективная сортировка является вспомогательной символьно-зависимой, и должны работать одинаково во всех версиях SQL Server, по крайней мере, еще в 2005 году (хотя, вероятно, также будут работать в SQL Server 2000 также).
Пример:
💩
ОБНОВИТЬ
Вы можете использовать следующую функцию iTVF для получения значений суррогатной пары (как в форме, так
INT
и вBINARY
форме) из любой кодовой точки между 65536 - 1114111 (0x010000 - 0x10FFFF). И, хотя входной параметр имеет типINT
, вы можете передать двоичную / шестнадцатеричную форму кодовой точки, и она неявно преобразуется в правильное целочисленное значение.Используя вышеуказанную функцию, выполняются два следующих запроса:
оба возвращают следующее:
ОБНОВЛЕНИЕ 2: еще лучшее обновление!
Я адаптировал показанный выше iTVF, чтобы теперь возвращать 188 657 кодовых точек, так что вам не нужно устанавливать какое-либо конкретное значение. Конечно, будучи TVF, вы можете добавить
WHERE
предложение для фильтрации по определенной кодовой точке, или диапазону кодовых точек, или «схожим символам» и т. Д. Кроме того, он включает дополнительные столбцы с предварительно отформатированными escape-последовательностями для построения каждого кода. точка (как BMP, так и дополнительные символы) в T-SQL, HTML и C-стиле (т.е.\xHHHH
). Прочтите все об этом здесь:Совет № 3 по SSMS: легкий доступ / исследование ВСЕХ символов Unicode (да, включая Emojis 😸)
источник