Проблема с кодировкой на SQL Server - PullRequest
3 голосов
/ 25 октября 2011

Я работаю с базой данных SQL Server;Кодировка экземпляра базы данных: «SQL_Latin1_General_CP1_CI_AS».

Следующий код:

UPDATE ...
SET field = CHAR(136)
WHERE...

вставляет в поле следующий символ: ˆ

Но!В кодовой таблице Latin1 127-159 кодов просто не определены!Как получается, что он вставляет этот символ?

И что еще более странно, когда я читаю это значение поля в строковую переменную в C # и преобразовываю его в символ, я получаю код 710 вместо 136.

Я пытался использовать преобразование кодировки:

var latin1Encoding = Encoding.GetEncoding("iso-8859-1");
var test = latin1Encoding.GetBytes(field); // field is a string read from db

Но в этом случае я получаю код 94, который является ^ (выглядит похоже, но это не то же самое, и мне нужно точно то же самое).

Ответы [ 2 ]

4 голосов
/ 25 октября 2011

Но! В кодовой таблице Latin1 127-159 кодов просто не определены!

В ISO-8859-1 определяется символ 136, но это редко используемый и в значительной степени бессмысленный управляющий символ.

Но SQL_Latin1_General_CP1_CI_AS, несмотря на название «Latin1», не является ISO-8859-1. Это западноевропейская кодовая страница ANSI, 1252, которая аналогична ISO-8859-1, но содержит несколько различных символов в диапазоне 128–159.

Символ 136 на кодовой странице 1252 - U + 02C6 ПИСЬМО МОДИФИКАТОРА ПИСЬМА КРУГА, ˆ; десятичная кодовая точка 710.

в этом случае я получаю код 94, который является ^

Да, вы запрашиваете преобразование в ISO-8859-1, которое не включает в себя символ U + 02C6, поэтому вы получаете «наиболее подходящий запасной вариант», который выглядит немного похожим на этот тот, который вы хотели. Это обычно плохо; многие из отобранных резервов весьма сомнительны. Вы можете изменить это поведение, используя EncoderFallback , например, чтобы вместо этого выдать исключение.

0 голосов
/ 25 октября 2011

Хорошо, здесь происходит несколько преобразований.

  1. При использовании Char(136) число представляет собой код ASCII , но так как число 136 находится за пределами стандартного ASCIIустановить символ, который вы получите, определяется как Windows-1252 .Этим символом является окружность.
  2. В дополнение к определению кодировки столбцов, отличных от Юникода, параметры сортировки также устанавливают некоторые правила для перевода между символами, не относящимися к Юникоду, и символами Юникода при попытке сохранить символ, не являющийся юникодом, вполе Юникода.Если преобразование не определено, вы, скорее всего, получите знак?, Но в этом случае вы получите символ с кодовой точкой Юникода U + 02C6.Важно понимать, что сопоставление устанавливает эквивалентность между символами, потому что было решено, что они похожи / эквивалентны.Это не имеет ничего общего с фактическими значениями.
  3. Наконец, вы использовали кодировку iso-8859-1, чтобы получить числовой код окружности в этой кодировке, равный 94. ​​
...