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 преобразуется в многобайтовые, и некоторые символы не могут быть представлены в этой кодовой странице, и они заменяются знаками вопроса ?,

Другие вопросы по тегам