О работе с русскими буквами в 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- База данных создана в Win1251. При коннекте указывается набор символов KOI8R. Сервер автоматически перекодирует данные из KOI8R в WIN1251 при передаче с клиента на сервер, и наоборот при передаче с сервера на клиента.
- База данных создана в KOI8R. То же самое, что и в пункте 1, только в обратную сторону.
- SELECT * FROM TESTCHAR ORDER BY NAME1
- SELECT * FROM TESTCHAR ORDER BY NAME2
- 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).
- делать это из 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, в противном случае кодировки работать не будут (вообще, даже не имея в виду создаваемые самостоятельно кодировки).
Вот и все. Если вам известно еще что-нибудь, относящееся к этой теме, напишите.