Firebird кодировка utf 8 или windows 1251
О работе с русскими буквами в InterBase/Firebird
Кузьменко Дмитрий, 1997, последнее обновление – 26.06.2006.
Установка
После установки 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
Работа через BDE
Работа через компоненты прямого доступа или API
Скрипты и ISQL
Uppercase русских букв
Например, если нужно сделать поиск по 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».
Русские буквы в хранимых процедурах, триггерах и 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, в противном случае кодировки работать не будут (вообще, даже не имея в виду создаваемые самостоятельно кодировки).
Вот и все. Если вам известно еще что-нибудь, относящееся к этой теме, напишите.
Кодовые страницы Firebird и InterBase
Работа с кодовыми страницами Firebird и InterBase
В IBProvider, начиная с версии 3.0.0.6327, реализован принципиально новый механизм работы с кодовыми страницами. В новом драйвере доступно 49 кодовых страниц Firebird и InterBase. При помощи таблиц и алгоритмов перекодировки, текстовые колонки, BLOB-поля и массивы конвертируются провайдером в формат UCS2 (двухбайтный юникод), c которым работает Firebird и InterBase. При этом учитывается кодовая страница подключения к базе данных.
Наряду с текстовыми кодовыми страницами, IBProvider обеспечивает поддержку кодовой страницы бинарных данных — OCTETS.
Схема работы с кодовыми страницами представлена на картинке:
1. Кодовая страница базы данных и кодировка текстовой колонки в InterBase и Firebird.
При создании базы указывается кодовая страница текстовых данных ПО УМОЛЧАНИЮ. Выбранная кодовая страница будет использоваться для всех текстовых данных, хранящихся в БД. При необходимости, можно указать кодировку для отдельных колонок, массивов или BLOB-полей, которая может отличаться от кодовой страницы базы данных.
Если кодировка текстовой колонки задана, то будет использоваться она, а кодовая страница БД будет проигнорирована.
2. Кодовая страница NONE
Если кодовая страницы базы данных не задана и кодовая страница текстовой колонки не определена, то будет использована кодировка NONE.
Для работы с этой кодировкой в IBProvider определено свойство ctype_none, позволяющее задать кодовую страницу для конвертирования текстовых данных в кодировке NONE.
Если свойство ctype_none не задано, то по умолчанию для NONE будет использоваться перекодировщик ASCII:
На рисунке под цифрой 2 показано преобразование текстовых типов Firebird и InterBase в соответствующие типы OLE DB и ADO.
3. Кодовая страница OCTETS и бинарные данные
Кодировка OCTETS предназначена для хранения в текстовых колонках бинарных данных. При обнаружении данной кодовой страницы IBProvider не будет использовать процессор кодировок, а типы данных OLE DB и ADO будут выставлены в соответствующие бинарные эквиваленты CHAR, VARCHAR и BLOB (см. обозначение на рисунке под цифрой 3).
4-6. Текстовые кодовые страницы
Для кодовых страниц, отличных от NONE и OCTETS используется процессор кодировок. Его упрощенная схема изображена на рисунке под цифрами 4, 5 и 6.
Кодировка хранения — кодовая страница текстовой колонки или базы данных.
Кодировка подключения — определяется свойством инициализаии ctype. Если оно задано, то данные считываются и записываются в этой кодировке, а кодировка хранения игнорируется.
Клиентская кодировка — кодовая страница текстовых данных, с которой работает клиент. Клиентская кодировка задается свойством ctype_user. К примеру, данные в БД, могут храниться в кодировке WIN1251, а к клиенту поступать в UTF-8. При записи текстовых данных в БД, производится обратное преобразование в кодировку хранения или в кодировку подключения.
Если ctype=NONE, то сервер игнорирует кодовую страницу подключения и использует кодировку хранения.
Если ctype_user=NONE, то провайдер игнорирует кодовую страницу клиента и предоставляет данные пользователю в кодировке хранения или, если ctype!=NONE, в кодировке подключения.
Для кодовых страниц NONE и OCTETS свойства ctype_user и ctype игнорируются.
Динамические клиентские кодировки (кодовые страницы клиента).
Допустимыми значениями ctype_user являются любое имя кодовой страницы, поддерживаемой провайдером и специальные имена динамически определяемых кодовых страниц — «ACP» и «OCP»
ACP — провайдер вызывает GetACP() и конвертирует «ACP» в «WINDOWS-xxx», где «xxx» идентификатор системной кодовой страницы ANSI.
OCP — провайдер вызывает GetOEMCP() и конвертирует «OEM» в «DOS-xxx», где «xxx» идентификатор системной кодовой страницы OEM.
Если не удалось конвертировать имя кодовой страницы или она не поддерживается сервером — провайдер генерирует ошибку.
7. Режим Unicode
В провайдере определено свойство unicode_mode, которое определяет формат публикации текстовых данных.
Если unicode_mode = true, то используются типы данных Unicode DBTYPE_WSTR: WChar, VarWChar и LongVarWChar.
Если unicode_mode = false, то используются простые типы DBTYPE_STR: Char, VarChar и LongVarChar.
Размер текстовых колонок в Firebird 2.x
IBProvider контролирует размер текстовых колонок при работе с серверами Firebird 2 в режиме Unicode. Если длина загруженных данных превысит размер текстовой колонки, то будет сгенерировано исключение. Чтобы избежать проверки размера колонки, можно подключиться в обычном режиме с указанием Unicode_mode=false.
Псевдонимы кодовых страниц Firebird и InterBase
IBProvider позволяет указать кодовую страницу по её названию, по серверному псевдониму, а так же с использованием имен-псевдонимов, встроенных в провайдер. К примеру, кодовая страница WIN1251, может быть определена по своему названию WIN1251, по серверному псевдониму WIN_1251, а так же через псевдонимы IBProvider: WIN-1251 и WINDOWS-1251.
Обработка пустых имен кодовых страниц
Пустые значения свойств ctype, ctype_user и ctype_none замеяются на NONE.
Поддерживаемые кодировки IBProvider Professional v3
ID | Кодировка | Максимум байт на 1 символ | Collation | Поддержкиваемые языки | Псевдонимы |
2 | ASCII | 1 | ASCII | English | ASCII7, USASCII |
56 | BIG_5 | 2 | BIG_5 | Chinese, Vietnamese, Korean | BIG5, DOS_950, WIN_950 |
50 | CYRL | 1 | CYRL | Russian | — |
50 | — | — | DB_RUS | Dbase Russian | — |
50 | — | — | PDOX_CYRL | Paradox Russian | — |
10 | DOS437 | 1 | DOS437 | English—USA | DOS_437 |
10 | — | — | DB_DEU437 | DBase German | — |
10 | — | — | DB_ESP437 | DBase Spanish | — |
10 | — | — | DB_FRA437 | DBase French | — |
10 | — | — | DB_FIN437 | DBase Finnish | — |
10 | — | — | DB_ITA437 | DBase Italian | — |
10 | — | — | DB_NLD437 | DBase Dutch | — |
10 | — | — | DB_SVE437 | DBase Swedish | — |
10 | — | — | DB_UK437 | DBase English—UK | — |
10 | — | — | DB_US437 | DBase English—USA | — |
10 | — | — | PDOX_ASCII | Paradox ASCII code page | — |
10 | — | — | PDOX_SWEDFIN | Paradox Swedish/Finnish code pages | — |
10 | — | — | PDOX_INTL | Paradox International English code page | — |
9 | DOS737 | 1 | DOS737 | Greek | DOS_737 |
15 | DOS775 | 1 | DOS775 | Baltic | DOS_775 |
11 | DOS850 | 1 | DOS850 | Latin I (no Euro symbol) | DOS_850 |
11 | — | — | DB_DEU850 | German | — |
11 | — | — | DB_ESP850 | Spanish | — |
11 | — | — | DB_FRA850 | French | — |
11 | — | — | DB_FRC850 | French—Canada | — |
11 | — | — | DB_ITA850 | Italian | — |
11 | — | — | DB_NLD850 | Dutch | — |
11 | — | — | DB_PTB850 | Portuguese—Brazil | — |
11 | — | — | DB_SVE850 | Swedish | — |
11 | — | — | DB_UK850 | English—UK | — |
11 | — | — | DB_US850 | English—USA | — |
45 | DOS852 | 1 | DOS852 | Latin II | DOS_852 |
45 | — | — | DB_CSY | DBase Czech | — |
45 | — | — | DB_PLK | DBase Polish | — |
45 | — | — | DB_SLO | DBase Slovakian | — |
45 | — | — | PDOX_PLK | Paradox Polish | — |
45 | — | — | PDOX_HUN | Paradox Hungarian | — |
45 | — | — | PDOX_SLO | Paradox Slovakian | — |
45 | — | — | PDOX_CSY | Paradox Czech | — |
46 | DOS857 | 1 | DOS857 | Turkish | DOS_857 |
46 | — | — | DB_TRK | DBase Turkish | — |
16 | DOS858 | 1 | DOS858 | Latin I + Euro symbol | DOS_858 |
13 | DOS860 | 1 | DOS860 | Portuguese | DOS_860 |
13 | — | — | DB_PTG860 | DBase Portuguese | — |
47 | DOS861 | 1 | DOS861 | Icelandic | DOS_861 |
47 | — | — | PDOX_ISL | Paradox Icelandic | — |
17 | DOS862 | 1 | DOS862 | Hebrew | DOS_862 |
14 | DOS863 | 1 | DOS863 | French—Canada | DOS_863 |
14 | — | — | DB_FRC863 | DBase French—Canada | — |
18 | DOS864 | 1 | DOS864 | Arabic | DOS_864 |
12 | DOS865 | 1 | DOS865 | Nordic | DOS_865 |
12 | — | — | DB_DAN865 | DBase Danish | — |
12 | — | — | DB_NOR865 | DBase Norwegian | — |
12 | — | — | PDOX_NORDAN4 | Paradox Norwegian & Danish | — |
48 | DOS866 | 1 | DOS866 | Russian | DOS_866 |
49 | DOS869 | 1 | DOS869 | Modern Greek | DOS_869 |
6 | EUCJ_0208 | 2 | EUCJ_0208 | EUC Japanese | EUCJ |
57 | GB_2312 | 2 | GB_2312 | Simplified Chinese (Hong Kong, PRC) | DOS_936, GB2312, WIN_936 |
21 | ISO8859_1 | 1 | ISO8859_1 | Latin 1 | ANSI, ISO88591, LATIN1 |
21 | — | — | FR_CA | French—Canada | — |
21 | — | — | DA_DA | Danish | — |
21 | — | — | DE_DE | German | — |
21 | — | — | ES_ES | Spanish | — |
21 | — | — | FI_FI | Finnish | — |
21 | — | — | FR_FR | French | — |
21 | — | — | IS_IS | Icelandic | — |
21 | — | — | IT_IT | Italian | — |
21 | — | — | NO_NO | Norwegian | — |
21 | — | — | DU_NL | Dutch | — |
21 | — | — | PT_PT | Portuguese | — |
21 | — | — | SV_SV | Swedish | — |
21 | — | — | EN_UK | English—UK | — |
21 | — | — | EN_US | English—USA | — |
22 | ISO8859_2 | 1 | ISO8859_2 | Latin 2—Central European (Croatian, Czech, Hungarian, Polish, Romanian,Serbian, Slovakian, Slovenian) | ISO-8859-2, ISO88592, LATIN2 |
22 | — | — | CS_CZ | Czech | — |
22 | — | — | ISO_HUN | Hungarian | — |
23 | ISO8859_3 | 1 | ISO8859_3 | Latin3—Southern European (Maltese, Esperanto) | ISO-8859-3, ISO88593, LATIN3 |
34 | ISO8859_4 | 1 | ISO8859_4 | Latin 4—Northern European (Estonian, Latvian, Lithuanian, Greenlandic, Lappish) | ISO-8859-4, ISO88594, LATIN4 |
35 | ISO8859_5 | 1 | ISO8859_5 | Cyrillic (Russian) | ISO-8859-5, ISO88595 |
36 | ISO8859_6 | 1 | ISO8859_6 | Arabic | ISO-8859-6, ISO88596 |
37 | ISO8859_7 | 1 | ISO8859_7 | Greek | ISO-8859-7, ISO88597 |
38 | ISO8859_8 | 1 | ISO8859_8 | Hebrew | ISO-8859-8, ISO88598 |
39 | ISO8859_9 | 1 | ISO8859_9 | Latin 5 | ISO-8859-9, ISO88599, LATIN5 |
40 | ISO8859_13 | 1 | ISO8859_13 | Latin 7—Baltic Rim | ISO-8859-13, ISO885913, LATIN7 |
44 | KSC_5601 | 2 | KSC_5601 | Korean (Unified Hangeul) | DOS_949, KSC5601, WIN_949 |
44 | — | — | KSC_DICTIONARY | Korean—dictionary order collation | — |
19 | NEXT | 1 | NEXT | NeXTSTEP encoding | — |
19 | — | — | NXT_US | English—USA | — |
19 | — | — | NXT_FRA | French | — |
19 | — | — | NXT_ITA | Italian | — |
19 | — | — | NXT_ESP | Spanish | — |
19 | — | — | NXT_DEU | German | — |
0 | NONE | 1 | NONE | Codepage-neutral. Uppercasing limited to ASCII codes 97—122 | — |
1 | OCTETS | 1 | OCTETS | Binary character | BINARY |
5 | SJIS_0208 | 2 | SJIS_0208 | Japanese | SJIS |
3 | UNICODE_FSS | 3 | UNICODE_FSS | UNICODE | SQL_TEXT, UTF-8, UTF8, UTF_FSS |
51 | WIN1250 | 1 | WIN1250 | ANSI—Central European | WIN_1250 |
51 | — | — | PXW_PLK | Polish | — |
51 | — | — | PXW_HUN | Hungarian | — |
51 | — | — | PXW_CSY | Czech | — |
51 | — | — | PXW_HUNDC | Hungarian—dictionary sort | — |
51 | — | — | PXW_SLOV | Slovakian | — |
52 | WIN1251 | 1 | WIN1251 | ANSI—Cyrillic | WIN_1251 |
52 | — | — | WIN1251_UA | Ukrainian | — |
52 | — | — | PXW_CYRL | Paradox Cyrillic (Russian) | — |
53 | WIN1252 | 1 | WIN1252 | ANSI—Latin I | WIN_1252 |
53 | — | — | PXW_SWEDFIN | Swedish & Finnish | — |
53 | — | — | PXW_NORDAN4 | Norwegian & Danish | — |
53 | — | — | PXW_INTL | English—International | — |
53 | — | — | PXW_INTL850 | Paradox Multi-lingual Latin I | — |
53 | — | — | PXW_SPAN | Paradox Spanish | — |
54 | WIN1253 | 1 | WIN1253 | ANSI Greek | WIN_1253 |
54 | — | — | PXW_GREEK | Paradox Greek | — |
55 | WIN1254 | 1 | WIN1254 | ANSI Turkish | WIN_1254 |
55 | — | — | PXW_TURK | Paradox Turkish | — |
58 | WIN1255 | 1 | WIN1255 | ANSI Hebrew | WIN_1255 |
59 | WIN1256 | 1 | WIN1256 | ANSI Arabic | WIN_1256 |
60 | WIN1257 | 1 | WIN1257 | ANSI Baltic | WIN_1257 | 61 | WIN1258 | 1 | WIN1258 | ANSI Vietnamese | WIN_1258 |
Поддержка внешних библиотек перекодирования данных
Помимо встроенных таблиц и алгоритмов перекодирования данных, IBProvider v3 может использовать внешнюю библиотеку с конверторами текстовых данных — ICU. Для этого нужно указать в строке подключения параметр icu_library=icuuc30.dll. У клиента должна быть библиотека с алгоритмами конвертора icuuc30.dll и ресурная — icudt30.dll. Библиотеки можно взять из поставки Firebird SQL Server.
Обратите внимание, что при использовании IBProvider 32bit нужно использовать 32-x битные ICU-библиотеки. При использовании IBProvider 64bit — 64-x битные ICU библиотеки. Использование ICU библиотеки из поставки Firebird 2.1 добавляет поддержку таких кодовых страниц как GBK и CP943C.
Полезные ссылки
Теги статьи: Firebird, InterBase, Firebird codepages, collations, InterBase charsets, Firebird encoding, Firebird oledb provider, UCS2 format, ODBC Firebird driver, character sets, ODBC InterBase driver
Поддерживаемые кодировки: ASCII, BIG_5, CYRL, DOS437, DOS737, DOS775, DOS850, DOS852, DOS857, DOS858, DOS860, DOS861, DOS862, DOS863, DOS866, DOS869, EUCJ_0208, GB_2312, ISO8859_1, ISO8859_2, ISO8859_3, ISO8859_4, ISO8859_5, ISO8859_6, ISO8859_7, ISO8859_8, ISO8859_9, ISO8859_13, KOI8R, KOI8U, KSC_5601, NEXT,NONE, SJIS_0208, TIS620, UNICODE_FSS, UTF8, WIN1250, WIN1251, WIN1252, WIN1253, WIN1254, WIN1255, WIN1256, WIN1257, WIN1258, OCTETS, GBK, CP943C