Размер шрифта:
О работе с русскими буквами в InterBase/Firebird
Play

О работе с русскими буквами в InterBase/Firebird

После установки InterBase или Firebird в основном каталоге должен быть подкаталог intl, в котором находятся файлы gdsintl.dll (InterBase) или fbintl.dll (Firebird). Если вы не используете инсталлятор, а устанавливаете файлы "поверх" (обновляете) или так как это описано в документе, убедитесь, что распаковка архива (zip) производилась с подкаталогами, то есть после распаковки присутствует каталог intl и в нем есть перечисленные выше файлы.

В файлах gdsintl.dll или fbintl.dll находится ряд кодировок, в том числе и нужная нам WIN1251. Если подкаталога intl или этих файлов нет, то при попытке работы с кодировкой WIN1251 будет выдана ошибка с текстом "text subtype52 not located" (или похожая).

Создание базы данных

Для русского языка есть кодировка WIN1251. Также есть устаревшая кодировка CYRL, которая крайне не рекомендуется к использованию.

При создании базы данных необходимо указать кодировку WIN1251 (если вы хотите использовать таблицу русских символов. Для других языков используются другие кодовые страницы). Это приведет к тому, что кодировка WIN1251 будет использована как умолчательная при создании строковых столбцов или переменных в таблицах, view, процедурах, триггерах и т.п. То есть, когда вы указали WIN1251 при создании БД, эта кодировка заносится в столбец RDB$CHARACTER_SET_NAME системной таблицы RDB$DATABASE. И именно отсюда подставляется как умолчательная кодировка для строковых столбцов и переменных.

Если вы не укажете кодировку при создании БД, то в rdb$character_set_name будет указано NONE. То есть все строковые столбцы и переменные, для которых не указана кодировка, будут иметь кодировку NONE, то есть символы будут рассматриваться как "без кодировки". В этом случае можно указывать кодировку строковых столбцо при создании таблиц, процедур и триггеров, однако это достаточно утомительно.

Если вы ошиблись при создании БД, и не указали кодировку, а вам нужна WIN1251 по умолчанию – как можно быстрее извлеките скрипт БД вместе с данными (например в IBExpert), и создайте БД из этого скрипта, указав DEFAULT CHARACTER SET WIN1251 (см. Language Reference, оператор CREATE DATABASE).

Подсоединение к БД

После того, как вы создали базу данных в WIN1251, необходимо помнить, что для использования этого набора символов нужно его указывать при подключении к базе данных (то есть, в момент подсоединения, как параметр, а не потом, после соединения). То же самое относится и к скриптам – чарсет данных в скрипте (set names win1251) должен быть указан до оператора CONNECT.

Набор символов при коннекте указывается, как правило, в параметрах соединения – ODBC, OLEDB, IBX, dbExpress, BDE и так далее – у них у всех есть параметр, указывающий кодировку при соединении.

У инструментов разработчика – IBExpert, IBConsole и т. п. – в параметрах коннекта также есть возможность указать кодировку WIN1251. И она также должна быть указана до того, как вы подсоединитесь к БД, созданной в кодировке WIN1251.

KOI8R
  1. База данных создана в Win1251. При коннекте указывается набор символов KOI8R. Сервер автоматически перекодирует данные из KOI8R в WIN1251 при передаче с клиента на сервер, и наоборот при передаче с сервера на клиента.
  2. База данных создана в KOI8R. То же самое, что и в пункте 1, только в обратную сторону.
Работа через BDE Работа через компоненты прямого доступа или API Скрипты и ISQL Uppercase русских букв
  1. SELECT * FROM TESTCHAR ORDER BY NAME1
  2. SELECT * FROM TESTCHAR ORDER BY NAME2
  3. SELECT * FROM TESTCHAR ORDER BY NAME1 COLLATE PXW_CYRL

Например, если нужно сделать поиск по uppercase-значению, даже когда поле было создано без collate – SELECT * FROM TESTCHAR WHERE UPPER(NAME1 COLLATE PXW_CYRL) = 'А'

Естественно, что для поля NAME2 такая конструкция не понадобится, и совершенно нормально отработает запрос SELECT * FROM TESTCHAR WHERE UPPER(NAME2) = 'А'

Как сменить COLLATE на работающей базе данных

То же самое относится и к ORDER BY COLLATE PXW_CYRL. Таким образом, все изложенное ниже стоит использовать только в крайнем случае, когда никакие другие стандартные методы не работают. Помните, что прямое редактирование системных таблиц – опасная операция, которая, как минимум, не должна выполняться на рабочем сервере.

Для этого вам понадобится отредактировать системную таблицу RDB$RELATION_FIELDS. Первые два столбца этой таблицы – RDB$FIELD_NAME и RDB$RELATTION_NAME, т.е. имя поля и имя таблицы соответственно. Найдите запись, у которой эти поля имеют нужное вам значение – например, MYFIELD и MYTABLE.

Последний столбец таблицы RDB$RELATION_FIELDS называется RDB$COLLATION_ID. В нем записан 0, если поле имеет только CHARACTER SET WIN1251, и 1 – если поле было создано с CHARACTER SET WIN1251 COLLATE PXW_CYRL.

Поэтому просто поменяйте 0 на 1, но только там, где RDB$COLLATION_ID не имеет значения "пусто".

Теперь, чтобы существующие в таблице записи получили новый COLLATE, нужно сделать

Иначе UPPER будет работать только для вновь создаваемых записей, но не для старых – это вызвано тем, что InterBase хранит информацию о типах полей в blob таблицы RDB$FORMATS, что позволяет менять тип поля, длину, и например COLLATE прямо "на ходу".

Ну и чтобы проверить, правильно-ли работает UPPER, можно выдать запрос

ODBC-драйвер

Для нормальной работы нужен ODBC-драйвер Firebird, EasySoft или DataDirect (IB2007). Они (сейчас уже практически и любые другие, в т. ч. бесплатные) позволяют установить на уровне настроек нужную кодировку, например WIN1251.

Драйвер InterSolv, позволявший установить WIN1251, поставлявшийся в IB 5.5 и 5.6 более не поддерживается и не выпускается.

Если вы работаете с драйвером, который не поддерживает установку кодировки при коннекте, то тогда у всех SQL-запросов придется указывать кодировку символов вручную. Например,

InterClient

// Параметры соединения с базой Properties connInfo = new Properties();

connInfo.put("user", username); connInfo.put("password", password); connInfo.put("charSet", "Cp1251");

// Устанавливаем соединение Connection db = DriverManager.getConnection(dataurl, connInfo);

Однако не забудьте при создании БД и таблиц указать кодировку символов. Для русского языка можно использовать значения "UNICODE_FSS" или "WIN1251".

  • Использовать interclient-core.jar вместо interclient.jar. При этом русских ресурсов просто не будет, и автоматом подхватятся английские.
  • Перекомпилировать файлы в нормальный Unicode. Разбор class-файлов – дело неблагодарное, поэтому лучше воспользоваться JAD-ом. К сожалению JAD, если встречает символы из набора ISO-8859-1, выводит их в 8-ричной кодировке, так что воспользоваться стандартным перекодировщиком native2ascii не удастся – придётся написать свой (программа Decode). Если Вам не хочется заморачиваться с этими проблемами – можете просто взять готовый файл с ресурсами (пропатченый jar с драйвером – interclient.jar, отдельные классы ресурсов – interclient-rus.jar).
Русские буквы в хранимых процедурах, триггерах и exceptions
  • делать это из WISQL, перед подсоединением к БД установив Character set on WIN1251;
  • перед извлечением метаданных в WISQL (Extract Metadata for database), опять же ДО подсоединения к БД нужно установить Character set on UNICODE_FSS;
  • если это возможно, избавиться от строковых констант с русскими буквами в теле триггера или процедуры. Для процедуры, например, можно передавать строку с русскими буквами как параметр – это в дальнейшем может избавить вас и от переписывания этой процедуры;
  • в SQL Explorer при попытке просмотра таких процедур, триггеров и exceptions будет возникать exception о "неверном преобразовании символов". Это решается созданием отдельного алиаса с пустым LANGDRIVER специально для работы с метаданными. Т.е. в алиасе с Pdox ansi Cyrillic вы работаете с данными, а в алиасе без языкового драйвера – с "русскими" exceptions, комментариями и текстом в триггерах и процедурах.
Не надо

Из-за ошибки в GBAK (вплоть до IB 6.0 включительно) не рекомендуется использовать в качестве списка допустимых значений для строковых полей русские буквы при описании структуры таблицы (default value list, например, flag char(3) default 'да'). Лучше перенести эту часть в триггер, если такая проверка действительно необходима на сервере. Если-же все-таки это случилось, восстановить базу данных удастся только при установленном параметре GBAK Do not restore validity conditions (в противном случае БД не восстановится, см. Verbose Output).

В Firebird версии 0.9.5.156 и выше этот баг устранен, однако чтобы он не возникал, требуется создание базы данных именно в этой версии. Backup/Restore для исправления бага недостаточно.

Еще один вариант решения проблемы с русскими default – это создание их в следующей форме:

Подключение своих наборов символов

1.0.0.500 эта ошибка устранена, и кодировки можно подключать. Однако при этом под Windows надо внимательно следить за версией файла GDSINTL.DLL (под Unix – gdsintl.so) – она должна точно совпадать с версией Firebird, в противном случае кодировки работать не будут (вообще, даже не имея в виду создаваемые самостоятельно кодировки).

Вот и все. Если вам известно еще что-нибудь, относящееся к этой теме, напишите.

📎📎📎📎📎📎📎📎📎📎