У меня есть таблица с колонной Varchar. Это позволяет использовать товарный знак (™), авторские права (©) и другие символы Юникода, как показано ниже.
Create table VarcharUnicodeCheck
(
col1 varchar(100)
)
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
insert into VarcharUnicodeCheck (col1) values ('MyCompany™')
insert into VarcharUnicodeCheck (col1) values ('MyCompany░')
insert into VarcharUnicodeCheck (col1) values ('MyCompanyï')
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
select * from VarcharUnicodeCheck
Но определение varchar гласит, что он допускает строковые данные не в Юникоде. Но торговые марки (™) и зарегистрированные (®) символы являются символами Unicode . Противоречит ли определение свойству типа данных varchar? Я прочитал пару ссылок, как первая и вторая . Но все же я не мог понять, почему он допускает строку в кодировке Юникод, когда в определении говорится, что он допускает только значения строк, отличные от Юникод.
Ответы:
Вы не правы здесь. Ваши строки содержат только
ascii
символы.Вот простой тест, который показывает, что все ваши символы - ascii (+ некоторые
extended ascii
с кодами ascii между 128 и 255):Здесь вы можете ясно видеть, что все ваши символы закодированы в 1 байт:
Да, они не являются чистыми символами ASCII, но они являются расширенными ASCII .
Здесь я покажу вам настоящий символ Юникода,
Trademark(™)
его код и двоичное представление:Наконец, вы можете видеть, что
Trademark(™)
символ Unicode имеет код 8482, а не 153:источник
Ö
), а в ISO-8859-1 (иногда называемом Latin1) это контрольный код без печатаемого представления. Если вы не знаете, что всегда будете использовать одну и ту же кодовую страницу, безопаснее придерживаться символов ANSI (127 или менее) или использовать типы Unicode. Кодовая страница 1252 наиболее распространена в SQL Server, но далеко не повсеместна.Из комментариев я согласен, что «расширенный ASCII» - это действительно плохой термин, который фактически означает кодовую страницу, которая отображает символы / кодовые точки в диапазоне 128–255, за пределы стандартного диапазона 0–127 кодовых точек, определенного ASCII.
SQL Server поддерживает множество кодовых страниц с помощью сопоставлений. Символы, не входящие в ASCII, могут храниться в varchar до тех пор, пока базовое сопоставление поддерживает этот символ.
Символ '™' может храниться в столбцах varchar / char, если кодовая страница сопоставления SQL Server 1250 или более. Ниже приведен запрос:
Но только их подмножество также поддерживает символ '©', поэтому для поддержки обоих параметров сортировки столбцов должно быть одно из следующих:
источник
Хотя другие ответы не являются правильными, я думаю, что это поможет указать на путаницу в базовой терминологии. Я подчеркнул два слова в приведенной выше цитате из вопроса в качестве примера этой путаницы. Когда документация по SQL Server говорит о Unicode и не-Unicode данных , они не говорят о символах . Они говорят о последовательности байтов, которые представляют определенные символы. Основное различие между типами Unicode (
NCHAR
,NVARCHAR
,XML
, и устаревшим / злойNTEXT
) и типами не-Unicode (CHAR
,VARCHAR
и устаревший / зломTEXT
) является то , что типы из последовательности байт они могут хранить.Типы, отличные от Unicode, хранят одну из нескольких 8-битных кодировок, а типы Unicode хранят одну 16-битную кодировку Unicode: UTF-16 Little Endian. Как уже упоминалось в других ответах, какие символы могут быть сохранены в 8-битной кодировке / кодировке, не относящейся к Юникоду, зависит от кодовой страницы, которая определяется с помощью сортировки. В то время как другие отметили, что значение байта «символа» может варьироваться в зависимости от кодовых страниц, на которых он обнаружен, значение байта может даже варьироваться в пределах одной и той же кодовой страницы при работе с одной из нескольких кодовых страниц EBCDIC (разновидности Windows- 1252), которые можно найти только в более старых версиях, которые не должны использоваться в действительности в SQL Server Collations (то есть, имена, начинающиеся с
SQL_
).Следовательно, определение является точным: любые символы, которые вы можете сохранить в не-Unicode-типе, всегда являются 8-битными (даже если они используют два 8-битных значения в комбинации как один «символ», что является Набор байтовых символов / кодовые страницы DBCS позволяют). И типы данных Unicode всегда 16-битные, даже если они иногда используют два 16-битных значения в комбинации как один «символ» (т. Е. Суррогатная пара, которая, в свою очередь, представляет дополнительный символ).
И, поскольку SQL Server изначально поддерживает кодировку UTF-8
VARCHAR
иCHAR
типы данных с SQL Server 2019,VARCHAR
больше не может называться «не-Unicode». Итак, начиная с первой общедоступной бета-версии SQL Server 2019 в сентябре 2018 года, мы должны называтьVARCHAR
его «8-битным типом данных», даже если речь идет о версиях, предшествующих SQL Server 2019. Эта терминология верна для всех 4 типов кодировок, которые можно использовать сVARCHAR
:Только
TEXT
тип данных (устарел начиная с SQL Server 2005, поэтому не используйте его) является «не-Unicode», но это лишь техническая составляющая, и ссылка на него как «8-битный тип данных» является точной.NVARCHAR
,NCHAR
ИNTEXT
могут быть отнесены к «UTF-16» или «16-битового типа данных». Я полагаю, что Oracle использует терминологию «только для Unicode»NVARCHAR
, но это не исключает возможности использования UTF-8 (также кодировки Unicode), который не будет работать, поэтому, вероятно, лучше придерживаться первые два варианта.Подробнее о новых кодировках UTF-8 читайте в моем сообщении:
Собственная поддержка UTF-8 в SQL Server 2019: Спаситель или Лжепророк?
PS Я медленно работаю над обновлением документации по SQL Server, чтобы отразить эти изменения.
PPS Microsoft уже обновила некоторые страницы с информацией UTF-8, включая документацию по char и varchar, упомянутую в этом вопросе. Он больше не содержит фразу "не-Unicode". Но это только к вашему сведению; это не меняет вопроса, поскольку речь идет о кодировках не в Юникоде, содержащих символы, которые по ошибке считались единственными в Юникоде.
источник
Вопрос содержит центральное неправильное представление о том, что такое Юникод. Набор символов Unicode, наряду с его кодировками, такими как UTF-8 и UTF-16, является одним из многих способов представления текста в компьютере, и его целью является замена всех других наборов символов и кодировок. Если «данные не в Юникоде» означают «символы, отсутствующие в Юникоде», то ни один из текстов, которые я использовал в этом ответе, не может быть сохранен в этом типе, потому что все буквы латинского алфавита и обычные знаки препинания, используемые в повседневном английском языке, включен в Юникод.
Текстовые представления можно широко представить в двух частях: набор символов, отображающий различные символы (буквы, цифры, символы и т. Д.) На числа в справочной таблице; и кодирование, представляющее эти числа в виде шаблонов битов (на диске, по сетевому соединению и т. д.). Здесь нас больше всего интересует первая часть: какие символы перечислены на диаграммах для определенного набора символов.
Так как Unicode стремится иметь числа (которые он называет «кодовыми точками») для каждого символа в мире, ссылки, такие как Википедия, часто будут ссылаться на позицию Unicode символа как стандартную часть справочной информации. Однако это не означает, что другие наборы символов также не имеют сопоставления для того же символа.
Один из самых старых и самых простых наборов символов (и кодировок), все еще используемых, является ASCII, который имеет отображения для 128 различных символов (от 0 до 127), потому что он использует 7 битов для кодирования каждого символа. Поскольку это исключает множество акцентированных символов и общих символов, более поздние кодировки используют 8 битов и отображают те же самые первые 128 символов, добавляя к набору символов, заполняя позиции от 128 до 255. Среди них следует отметить стандартные ISO 8859-1 и ISO 8859- 15 , и специфическая для Microsoft кодовая страница Windows 1252 .
Таким образом, чтобы вернуться к MS SQL Server: «строка Unicode», как хранится в одном
nchar
,nvarchar
илиntext
столбце, может представлять все символы , отображенные в наборе символов Unicode, поскольку он использует Unicode , кодирующим для хранения данных. А «строка не-Unicode», которые хранятся вchar
,varchar
илиtext
столбце, может представлять только символы , отображенные в какой - либо другой кодировке . Все, что вы можете сохранить в столбце не в Юникоде, также может храниться в столбце в Юникоде, но не наоборот.Чтобы точно знать, какие символы вы можете хранить, вам нужно знать используемое «сопоставление», которое диктует то, что Microsoft называет «кодовой страницей», как описано на этой справочной странице Microsoft . Вероятно, в вашем случае вы используете очень распространенную кодовую страницу 1252, о которой я упоминал ранее.
Упомянутые вами символы существуют как в Юникоде, так и в Кодовой странице 1252:
источник