Проблемы с использованием / отображением специальных символов из базы данных Oracle в приложении .Net
-
10-07-2019 - |
Вопрос
У меня есть приложение C # .Net, которое получает доступ к данным из коммерческого приложения, поддерживаемого Oracle 10 db. Несколько полей в базе данных коммерческого приложения (объявленные как varchar2 (n)) содержат специальные символы. «Умная цитата» апостроф, например. Коммерческое клиентское приложение отображает эти символы правильно, но мое приложение отображает их в виде перевернутого знака вопроса. Набор символов Oracle - "WE8ISO8859P1".
Мое приложение считывает коммерческую базу данных с использованием System.Data.OracleClient.OracleDataAdapter, преобразованной в таблицу с помощью DataSet.Tables. Таблички преобразуются в объекты, а соответствующие поля сохраняются в виде строк. Р>
Если я проверю (в отладчике) данные в наборе данных сразу после их чтения из БД, и специальные символы уже отображаются неправильно. Я не могу понять, как проверить данные в виде шестнадцатеричных байтов, чтобы увидеть, что там на самом деле, и я не уверен, что мне нужно искать.
Я также отметил, что Жаба отображает символы в виде перевернутых знаков вопроса. Р>
Один аспект нашего приложения записывает эти записи в отдельную таблицу в нашей собственной базе данных; когда это происходит, специальные символы изменяются и впоследствии отображаются в виде полей вместо перевернутых вопросительных знаков.
Я могу предоставить дополнительную информацию, если это необходимо. Спасибо за любую помощь!
Решение 2
Постскриптум для всех, кто просматривает эту тему:
Богдан очень помог мне в ответе на "ответ" (такой, как она есть), но, как он указывает, у вас могут не быть идентичные обстоятельства.
<Ол>Мы связались с командой, ответственной за использование коммерческого программного обеспечения. Они копировали / вставляли из Word и Excel, и именно так вставлялись специальные символы. Р>
Возникла проблема при переводе символа между удаленной базой данных и нашей базой данных. База данных хоста использует набор символов WE8ISO8859P1, где наша использует WE8MSWIN1252. Из-за проблем корпоративного уровня, изменение любого набора символов сейчас невозможно.
Я использовал SYS.UTL_RAW.CAST_TO_RAW (имя поля), чтобы преобразовать исходное поле для поиска «BF» (шестнадцатеричный код для перевернутого знака вопроса в нашем наборе символов). Это, по крайней мере, позволило мне определить проблемную запись и характер. ОДНАКО многие различные специальные символы в удаленных записях будут / могут быть переведены в BF. Например, дефисы Word не являются простыми «тире» символы, а также переводятся в перевернутый знак вопроса. Р>
dump (fieldname) каким-то образом преобразуется в десятичные коды символов ДО перевода, кроме случаев, когда я использовал SYS.UTL_RAW.CAST_TO_RAW в том же запросе. Это вызвало удивительные головные боли. Сам по себе dump () может быть полезен для идентификации конкретных предварительно переведенных символов из исходной базы данных.
Лучшим решением было бы использовать один и тот же набор символов на обоих БД. Поскольку это невозможно для нас, мы вручную заменили все вхождения специального символа в исходной (удаленной) базе данных на не специальные эквиваленты (обычный апостроф или дефис). Однако, поскольку коммерческое программное обеспечение не исправляет или не помечает специальные символы, мы можем столкнуться с этой проблемой в будущем. Таким образом, наше приложение обновлений отсканирует инвертированный вопросительный знак и отправит владельцу системы уведомление с идентификатором неверной записи. Это, как и многие другие корпоративные ситуации, придется делать. ; -) р>
Еще раз спасибо, Богдан!
Другие советы
Некоторые символы в наборе символов WE8ISO8859P1 имеют двоичное представление, отличное от того же символа в UTF8. Р>
Я предлагаю 2 возможных способа
1) Попробуйте использовать собственные поставщики данных Oracle для .NET (ODP.NET). Возможно, есть ошибка / функция в библиотеке Microsoft System.Data.OracleClient, что этот адаптер не поддерживает автоматическое преобразование WE8ISO8859P1 в Unicode. Вот ссылка на ODP.NET
Я надеюсь, что в ODP будет поддержка этой кодировки (но сказать правду, я никогда не проверял это, это всего лишь предложение)
2) Обходной путь: в наборе данных вы должны создать двоичное поле (сопоставленное с полем исходной таблицы) и поле String (не сопоставленное с базой данных). Когда вы загружаете данные в набор данных, выполняйте итерацию для каждой строки и выполняйте преобразование из двоичного массива в строку.
Код должен быть примерно таким
Encoding e = Encoding.GetEncoding("iso-8859-1");
foreach(DataRow row in dataset.Tables["MyTable"])
{
if (!row.IsNull("MyByteArrayField"))
row["MyStringField"] = e.GetString((row["MyByteArrayField"] as byte[]));
}