LEN и DATALENGTH VARCHAR и NVARCHAR
После прочтения "В чем разница между char, nchar, varchar и nvarchar в SQL Server?" У меня возник вопрос.
Я использую MS SQL Server 2008 R2
DECLARE @T TABLE
(
C1 VARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS,
C2 NVARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS
)
INSERT INTO @T VALUES (N'中华人民共和国',N'中华人民共和国')
SELECT LEN(C1) AS [LEN(C1)],
DATALENGTH(C1) AS [DATALENGTH(C1)],
LEN(C2) AS [LEN(C2)],
DATALENGTH(C2) AS [DATALENGTH(C2)]
FROM @T
Возвращает
LEN(C1) DATALENGTH(C1) LEN(C2) DATALENGTH(C2)
----------- -------------- ----------- --------------
7 12 7 14
Почему второй DATALENGTH(C1) равен 12?
1 ответ
В вашем INSERT
вы конвертируете текст из юникода в китайскую кодовую страницу для C1
, Скорее всего, этот процесс изменяет текст и что-то может быть потеряно.
Вот SQL Fiddle.
Вы можете видеть, что второй персонаж 华
хранится как 3F
в varchar
, Вы также можете увидеть, что последний персонаж 国
также хранится как 3F
в varchar
, 3F
это код для ?
, Когда Windows пытается преобразовать текст из Unicode в кодовую страницу, и определенный символ не может быть представлен в данной кодовой странице, функция преобразования (наиболее вероятно, WideCharToMultiByte
) ставит ?
для таких персонажей.
Еще один пример. Последний, но один персонаж 和
кодируется как A94D
в varchar
а также 8C54
в nvarchar
, Если вы посмотрите на карту символов, она покажет следующие коды (юникод и кодовая страница):
Смотрите также:
Что это значит, когда мой текст отображается как вопросительные знаки?
https://www.microsoft.com/middleeast/msdn/Questionmark.aspx
Каждый раз, когда необходимо отобразить данные Unicode, они могут быть внутренне преобразованы из Unicode с помощью API WideCharToMultiByte. Каждый раз, когда символ не может быть представлен на текущей кодовой странице, он будет заменен знаком вопроса (?).
Это именно то, что происходит, когда вы храните Unicode-литерал N'中华人民共和国'
в varchar
колонка. Текст Unicode преобразуется в многобайтовые, и некоторые символы не могут быть представлены в этой кодовой странице, и они заменяются знаками вопроса ?
,