Не удалось определить правильную кодировку символов

Мне нужно извлечь данные из некоторых старых файлов базы данных interbase, созданных с помощью InterBase 4.2.1. Я использую встроенную версию Firebird (версия 2.5.1) и .NetProvider (версия 2.7.0). Я никогда раньше не работал с межбазой Firebird (но у меня есть некоторый опыт работы с SQL SERVER и SQLite), и после двухдневного путешествия по сети и экспериментов я так и не нашел решения.

Таблицы в базе данных содержат данные на английском языке, а также данные на иврите. Каким бы оптимистичным я ни был, я начал с создания строки подключения с использованием UTF8:

FbConnectionStringBuilder builder = new FbConnectionStringBuilder();
builder.Database = m_DatabaseName;
builder.ServerType = FbServerType.Embedded;
builder.Charset = FbCharset.Utf8.ToString();

Но это дало мне следующее исключение:

bad parameters on attach or create database
CHARACTER SET Utf8 is not defined

Я правильно использовал fbintl.dll. (см. файлы в каталоге моего приложения и подкаталогах ниже). Я даже использовал ProcessMonitor, чтобы проверить, загружена ли fbintl.dll.

fbembed.dll
firebird.log
firebird.msg
FirebirdSql.Data.FirebirdClient.dll
ib_util.dll
icudt30.dll
icuin30.dll
icuuc30.dll
MyApplication.exe
Microsoft.VC80.CRT.manifest
msvcp80.dll
msvcr80.dll
intl\fbintl.conf
intl\fbintl.dll
udf\fbudf.dll
udf\ib_udf.dll

Итак, я попытался перечислить FbCharset и попытаться подключиться к каждому набору символов, более половины из них выдавали одно и то же исключение, а когда я подключался к другим и запрашивал одно из полей иврита (используя IDataReader.GetString()), я всегда получал один и тот же мусор. в результате. Кажется, не имеет значения, какой набор символов я указываю в строке подключения, результат всегда один и тот же, даже если я вообще не указываю какой-либо набор символов.

Затем я запросил наборы символов, определенные в базе данных SELECT RDB$CHARACTER_SET_NAME FROM RDB$CHARACTER_SETS, и перечислил их, пытаясь соединиться с каждым из них, некоторые выдавали исключение, другие давали тот же результат, что и раньше.

Я понятия не имею, с каким набором символов была создана база данных, но я проверил наборы символов каждого поля в базе данных, и все текстовые поля имеют свои наборы символов, установленные на «НЕТ».

SELECT r.RDB$RELATION_NAME, r.RDB$FIELD_NAME, f.RDB$FIELD_NAME, cset.RDB$CHARACTER_SET_NAME
FROM RDB$RELATION_FIELDS r
LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME
LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID
ORDER BY r.RDB$RELATION_NAME ASC, r.RDB$FIELD_POSITION ASC

Но я заметил, что в некоторых текстовых полях системных таблиц в качестве набора символов используется UNICODE_FSS. Я уже пробовал этот набор символов в строке подключения, но все еще получаю мусор для запрошенных текстовых полей.

Моя последняя попытка состояла в том, чтобы получить байты (используя IDataReader.GetBytes()) и самостоятельно закодировать строку, но это дает мне исключение приведения (Unable to cast object of type 'System.String' to type 'System.Byte[]'.)

У кого-нибудь есть идеи о том, как читать эти данные? Мне не нужно постоянно конвертировать базы данных, так как они больше не будут использоваться после извлечения данных.

РЕДАКТИРОВАТЬ: кстати, есть ли какие-нибудь бесплатные облегченные программы просмотра баз данных interbase/firebird, я не могу найти хороших (сопоставимых с SQLiteSpy) ?

Марк


person Marc    schedule 15.02.2012    source источник
comment
Попробуйте преобразовать базу данных в формат FB 2.5 с помощью утилиты gsbelarus.com/gs/fdbconvert FDBConvert.   -  person Andrej Kirejeŭ    schedule 15.02.2012
comment
Спасибо, я только что попробовал, выдало ошибку неизвестного типа сервера. Я забыл упомянуть, что также пробовал утилиту FBClone (code.google.com/p/fbclone, версия 2.1.4), и это тоже не сработало, поскольку в моей базе данных, похоже, нет RDB$FIELDS.RDB$FIELD_PRECISION. Я думаю, что межбазовая версия, используемая для создания этих баз данных, слишком старая для этих утилит.   -  person Marc    schedule 15.02.2012
comment
Если вам интересно, у меня есть установка IB 4.2. Я думаю, что лучшим подходом было бы обновить базу данных через последовательность резервного копирования-восстановления до версии FB 1.0, а затем преобразовать ее в 2.5 с помощью утилиты FDBConvert.   -  person Andrej Kirejeŭ    schedule 15.02.2012
comment
У меня есть установка 4.2.1, но я не собираюсь устанавливать такое старое программное обеспечение (оно вообще работает на win7 x64?) И я не знаю имя пользователя/пароль, используемые для создания БД (не требуется для встроенных). И можете ли вы импортировать БД во встроенный FB1.0 или мне нужно также установить сервер? (тот же вопрос, работает ли он на win7, т.к. вижу предупреждение Vista на сайте) Кроме того, мне нужно конвертировать много этих баз, я не жду всех этих ручных действий. Нет ли способа прочитать поля varchar как байты, чтобы я мог преобразовать их в С#?   -  person Marc    schedule 15.02.2012
comment
Попробуйте подключиться к базе данных с помощью IBExpert. Имеет функцию экспорта данных. Если это не поможет, боюсь, вам придется пройти цикл обновления базы данных. то есть сделайте резервную копию на сервере IB 4.2.1, а затем восстановите с помощью FB 1.0.   -  person Andrej Kirejeŭ    schedule 15.02.2012


Ответы (1)


Я нашел решение.

Исходная база данных была написана на окнах с кодовой страницей 1255. Теперь, когда я читаю данные, С# генерирует строку юникода, используя кодировку по умолчанию (которая не 1255). Поэтому я просто декодирую строку в байты, используя кодировку по умолчанию, а затем конвертирую байты в строку, используя правильную кодировку.

Encoding encoding = Encoding.GetEncoding(1255);
...
if (!datareader.IsDBNull(i))
{
    string value = dataReader.GetString(i);
    if (value.Length > 0)
    {
        byte[] bytes = Encoding.Default.GetBytes(value);
        value = encoding.GetString(bytes);
    }
    // store value
 }

Это решение отлично работает для меня, но я до сих пор не понимаю, почему я не могу указать «WIN1255» в качестве кодировки в моей строке подключения, не получая исключение bad parameters on attach or create database - CHARACTER SET WIN1255 is not defined? (Я даже пробовал кодировку "WINDOWS1255", но потом получаю исключение Invalid character set specified).

person Marc    schedule 16.02.2012