Относно работата с български знаци в InterBase

Не се плашете от обема на този текст! Всъщност тук са изброени абсолютно всички теми, свързани с "русификацията" на Borland InterBase и Firebird. Може да имате нужда само от някои, но първо прочетете целия документ и след това използвайте този, от който се нуждаете.

Въпреки че IB 5 и 6 не съдържат тази грешка, в някои случаи операцията по възстановяване на базата данни ще доведе до грешка „text subtype52 not located“ (или подобна).

Освен това, почти всичко, което ще бъде заявено, може да бъде прочетено както в IB32.HLP, така и в Borland InterBase Language Reference документация, раздел Набори от символи и поръчки за сортиране (и не само там).

Създаване на база данни

Сега, след като преинсталирахте Borland InterBase, е време да създадете базата данни. Има два начина да получите възможност за работа с български букви в базата данни: по обичайния начин и без използване на кодировки.

Обичайният начин: Работейки на всяка платформа, трябва да посочите допълнителен параметър DEFAULT CHARACTER SET WIN1251, когато създавате база данни. Ако създавате база данни в WISQL, след това въведете тази фраза в полето Database Options memo и ако направите същото в командния ред на ISQL, използвайте пълния синтаксис CREATE DATABASE "C:/MYDIR/MYDATABASE.GDB" USER "SYSDBA" PASSWORD "masterkey" DEFAULT CHARACTER SET WIN1251; За BDE използвайте настройките, посочени в "Operation" раздел чрез BDE", който може да бъде прочетен по-долу.

забележка: еквивалентът на набор от символи WIN1251 е CYRL кодиране, но не се препоръчва използването му, т.к. не поддържа UPPER.

Без използване на кодировки: когато създавате база данни, НЕ посочвайте DEFAULT CHARATER SET нито за базата данни, нито за полета със знаци. В този случай BDE трябва да има параметъраLANGDRIVER: страница SYSTEM - ascii ansi, DRIVERS - празна, ALIAS - празна. В този случай знаците могат да се записват в базата данни във всяко кодиране.

Начинът за отказ на кодиране е по-прост, той ви позволява да работите с различни набори от символи в една връзка (например за мрежата), но не може да осигури правилното сортиране на различни набори от символи - трябва внимателно да проверите всичко, преди да използвате този подход. Например функцията UPPER и поръчките за сортиране няма да работят - вместо това ще трябва да използвате функции от модула CASEUDF.

Останалата част от този документ се отнася само до официалния начин за работа с български знаци в IB

! Не трябва да се опитвате да именувате таблици, полета или други обекти от база данни с български букви. Това не е в съответствие със стандарта, точно както при именуване на типове или променливи в езиците за програмиране Pascal или C. Като цяло това важи и за Interbase 6/Firebird, където в диалект 3 можете да посочите имена на обекти, затворени в двойни кавички.

Ако сте създали таблица и искате да добавите няколко записа там директно от WISQL, трябва да прекъснете връзката с базата данни и да се свържете отново, след като зададете същия WIN1251 в „WISQL/Сесия/Разширени настройки/Включен набор от знаци“.

Работете чрез BDE

! Списъкът с Borland InterBase кодировки включва още един български език - CYRL (866). Въпреки това, Borland не е пуснал никакви инструменти за работа с IB от DOS от дълго време, така че използването на 866 кодиране при работа в Windows би било странно.

Работете чрез други компоненти и API

Няма значение кой набор от компоненти се използва тук - IBObjects, FreeIBComponents, FIBPlus или IBX. Необходимо е да въведете реда в параметрите на компонента, отговорен за връзката (XXDatabase)

Когато става въпрос за инструментиза да работят с IB, които работят без BDE, те трябва да поддържат указване на необходимото кодиране ПРЕДИ да се свържат с базата данни. Например IBConsole придоби тази възможност от версия 319.

Скриптове и ISQL

Всъщност всичко е същото. Тези. кодирането на знаци трябва да бъде зададено преди свързване или създаване на база данни. Буквално - в началото на скрипта напишете:

Същата команда се издава интерактивно преди свързване към базата данни чрез помощната програма за команден ред ISQL.

Главни български букви

CREATE TABLE TESTCHAR( ID INTEGER NOT NULL PRIMARY KEY, NAME1 CHAR(30), NAME2 CHAR(30) COLLATE PXW_CYRL )

И въведете следните данни в тази таблица (поне с помощта на SQL Explorer):

1АА
2бб
3ININ
4АА
5bb
6VV
Сега изпълнете три заявки и вижте в какъв ред се връщат записите

1) ИЗБЕРЕТЕ * ОТ TESTCHAR ORDER BY NAME1 2) SELECT * FROM TESTCHAR ORDER BY NAME2 3) SELECT * FROM TESTCHAR ORDER BY NAME1 COLLATE PXW_CYRL

Обърнете внимание, че втората и третата заявка доведоха до същия ред на записите в резултата. Наистина, на всяко място и във всяка ситуация можете да добавите спецификатора COLLATE PXW_CYRL, ако този спецификатор не е бил указан за полето за низ при създаването на таблицата.

Например, ако искате да търсите по стойност с главни букви, дори когато полето е създадено без сортиране - SELECT * FROM TESTCHAR WHERE UPPER(NAME1 COLLATE PXW_CYRL) = 'A'

Естествено, за полето NAME2 такава конструкция не е необходима и заявката SELECT * ще работи съвсем нормално.FROM TESTCHAR WHERE UPPER(NAME2) = 'A'

Забележка: ако имате индекс в полето NAME2, тогава използването на която и да е функция (UPPER или свързани UDF) ще доведе до невъзможност на оптимизатора да използва индекса, за да ускори заявката. В този случай заявката SELECT * FROM TESTCHAR WHERE NAME2 = 'A' ще бъде оптимизирана (търсене по индекс), а заявката SELECT * FROM TESTCHAR WHERE UPPER(NAME2) = 'A' ще обходи всички записи в таблицата. Ако имате много записи в такава таблица и само една клауза WHERE, съдържаща UPPER, тогава можете да добавите допълнително поле към таблицата с DEFAULT UPPER(SOURCEFIELD). В този случай новите стойности се добавят само към SOURCEFIELD и търсенето се извършва в полето, съдържащо подготвения UPPER.

Забележка: указването на COLLATE PXW_CYRL кара IB да счита такива полета за съхраняване на знаци в 3-байтово кодиране и не позволява създаването на индекс върху такова поле, ако дължината му надвишава 84 (252/3=84) знака. В този случай е по-добре да изоставите стандартния UPPER и да използвате свой собствен UDF за превод на регистър. Пример за функциите UpCase и LoCase с изходния код в Delphi и готовия DLL можете да намерите тук - caseudf.zip (10K). Като цяло, дали да посочите или не COLLATE PXW_CYRL зависи от вас да решите сами. Основно изборът се определя от необходимостта от специфично сортиране на главни и малки български букви, което се предоставя от COLLATE PXW_CYRL (вижте по-горе заявките с подреждане по).

Как да промените COLLATE на работеща база данни

Забележка: трябва да запомните, че в най-простия случай такава задача се решава чрез написване SELECT * FROM MYTABLE WHERE UPPER(MYFIELD COLLATE PXW_CYRL) = 'VASYA'

Същото важи и за 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, трябва да направите

АКТУАЛИЗИРАНЕ НА МОЯТА ТАБЛИЦА SET MYFIELD=MYFIELD

в противен случай UPPER ще работи само за новосъздадени записи, но не и за стари - това се дължи на факта, че InterBase съхранява информация за типовете полета в blob на таблицата RDB$FORMATS, което ви позволява да промените типа на полето, дължината и например COLLATE директно "в движение".

Е, за да проверите дали UPPER работи правилно, можете да подадете заявка

ИЗБЕРЕТЕ ГОРНО (МОЕТО ПОЛЕ) ОТ МОЯТАБЛИЦА

Ако искате да промените „с един замах“ COLLATE за всички полета на вашата база данни, можете да изпълните заявката

АКТУАЛИЗИРАНЕ НА RDB$RELATION_FIELDS SET RDB$COLLATION_ > WHERE (RDB$FIELD_NAME НЕ СЪДЪРЖА '$') И (RDB$SYSTEM_FLAG = 0) И (RDB$COLLATION_ >

След това, разбира се, ще трябва да се направи актуализация за всяка таблица, където искате да работите с UPPER за низови полета. Ако има индекси на променените низови полета, тогава тези индекси трябва да бъдат изтрити и създадени отново, т.к. подреждане по ще използва стойността на ключа за сортиране, а не стойността на полето в таблицата.

забележка: модифицирането на системни таблици е нормална операция, ако знаете точно какво искате да направите и сте прочели раздела Системни таблици на InterBase Language Reference. InterBase може да променя структурата на таблиците, типовете полета и т.н. операции, но за тях няма съответни SQL команди - те просто не са дефинирани в стандарта.

ODBC драйвер

Работата с български символи през ODBC драйвера от IB версии 4.2, 5.0 и 5.1.1 ще бъде проблематична. Този драйвер НЕ ви позволява да зададете кодирането на получените и предадените знаци. Ако ODBC драйверът работи добре за четене (както самостоятелно, така и чрез BDE), тогава за писане трябва да формирате заявка ръчно и да добавите конкретна индикация за използвания набор от знаци. Например, за същата таблица TESTCHAR вмъкването на записи ще трябва да бъде написано с помощта на UpdateSQL: INSERT INTO TESTCHAR VALUES (:ID, _win1251 :NAME1, _win1251 :NAME2)

Нека ви напомня, че драйверът версия 3.0, доставен с IB 5.5/5.6, работи коректно с български символи и WIN1251 кодиране на базата данни.

Български букви в запомнени процедури, тригери и изключения

Поради грешка в GBAK (до и включително IB 6.0), не се препоръчва използването на български букви като списък с валидни стойности за низови полета при описание на структура на таблица (списък със стойности по подразбиране). По-добре е да преместите тази част в тригер, ако наистина е необходима такава проверка на сървъра. Ако това се случи, базата данни може да бъде възстановена само ако е зададена опцията GBAK Не възстановявай условията за валидност (в противен случай базата данни няма да бъде възстановена, вижте Подробен изход).

Във версия 0.9.5.156 на Firebird и по-нова тази грешка е коригирана, но за да я избегнете, трябва да създадете база данни в тази версия.Архивирането/Възстановяването не е достатъчно, за да коригира грешката.

Друг начин за решаване на проблема с българските настройки по подразбиране е да ги създадете в следната форма:

създаване на таблица bug_bugbase ( s varchar(20) набор от знаци win1251 collate win1251 по подразбиране _win1251 'XXXX' not null);

Това ще инструктира уникално идентифициране на набора от знаци за знаците, посочени по подразбиране.