Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри
Шрифт:
Интервал:
Закладка:
! ! !
СОВЕТ. При проектировании столбцов всегда рассматривайте возможные требования с точки зрения использования набора символов, индексирования и ключа. Всегда держите "черновую" таблицу в разрабатываемой базе данных для тестирования ограничений индексов и ключей.
. ! .
Хранение столбцов BLOB, которые не являются индексируемыми, никак не ограничивается использованием набора символов.
Набор символов по умолчанию для базы данныхЕсли вы не указываете набор символов по умолчанию для базы данных в объявлении CREATE DATABASE, то набор символов по умолчанию устанавливается в NONE. Набор символов NONE не предполагает никакого набора символов для текстовых столбцов, сохраняя данные точно в том виде, в каком они были введены. Если клиентское соединение не указывает набора символов, то данные также будут отыскиваться точно так, как они были введены. Алфавитно-цифровое упорядочение ограничено упорядочением кодов ASCII, а преобразование верхний/нижний регистр поддерживается только в кодах U.S.ASCII 65-90 и 97-102 соответственно.
Указывайте допустимый код набора символов в предложении DEFAULT CHARACTER SET:
CREATE DATABASE '/data/adatabase.fdb'
. . .
DEFAULT CHARACTER SET WIN1251;
Более подробную информацию об операторе CREATE DATABASE см. в главе 12.
Переопределение набора символов на уровне столбцаАтрибут набора символов может быть добавлен к индивидуальному определению домена, столбца таблицы или переменной PSQL типа CHAR, VARCHAR или BLOB SUB_TYPE 1 для перекрытия набора символов по умолчанию базы данных.
Например, следующий фрагмент скрипта создает базу данных с набором символов по умолчанию ISO8859_1 и таблицу, содержащую различные версии языка похожих данных в отдельных столбцах:
CREATE DATABASE '/data/authors.fdb' DEFAULT CHARACTER SET ISO8859_1;
CREATE TABLE COUNTRY_INTL(
CNTRYCODE BIGINT NOT NULL,
NOM_FR VARCHAR(30) NOT NULL,
/* использует набор символов по умолчанию */
NOM_EN VARCHAR(30), /* использует набор символов по умолчанию */
NOM_RU VARCHAR(30) CHARACTER SET WINI251,
NOM_JP VARCHAR(30) CHARACTER SET SJIS_0208
Другой фрагмент того же скрипта создает домен для хранения данных BLOB В наборе символов кириллицы:
CREATE DOMAIN MEMO_RU AS BLOB SUB_TYPE 1
CHARACTER SET WIN1251;
Позже в этом скрипте мы создаем таблицу, которая хранит некоторый текст в кириллице:
CREATE TABLE NOTES_RU (
DOC_ID BIGINT NOT NOLL,
NOTES MEMO_RU
);
Следующий фрагмент определяет хранимую процедуру, которая преобразует входную строку в другой набор символов перед сохранением ее в таблице:
CREATE PROCEDURE CONVERT_NOTES (
INPUT_TEXT VARCHAR(300) ) AS
DECLARE VARIABLE CONV_STRING WARCHAR(300)
CHARACTER SET WIN1251;
BEGIN
IF (INPUT JTEXT IS NOT NULL) THEN
BEGIN
CONV_STRING = _WIN1251 ' ' || : INPUT_TEXT;
/* использует INTRODUCER */
INSERT INTO NOTES_RU (DOC_ID, NOTES)
VALUES (GEN_ID (ANYGEN, 1) , :CONV_STRING) ;
END
END ^
Создание доменов объясняется в главе 13. Полный синтаксис оператора CREATE TABLE описан в главе 15. Объявление переменных в PSQL см. в главе 30.
Переопределение набора символов на уровне оператораНабор символов для текстовых значений в операторе интерпретируется в соответствии с набором символов соединения в процессе выполнения (а не в соответствии с набором символов, определенным для столбца при его создании), если только вы не зададите маркер набора символов (или "представитель") для указания другого набора символов.
INTRODUCER - маркер набора символовМаркер набора символов - также известный как INTRODUCER- состоит из имени набора символов, перед которым стоит символ подчеркивания. Он требуется для "представления" входной строки, когда приложение клиента соединено с базой данных с использованием набора символов, отличного оттого, который определен для столбца в базе данных.
Установите маркер слева от отмечаемого текстового значения. Например, маркером для ввода в UMCODE_FSS поле является _UNICODE_FSS:
INSERT INTO EMPLOYEE(Emp_ID, Emp_Name)
values(1234, _UNICODE_ESS 'Smith, John Joseph');
! ! !
СОВЕТ. Для ясности вы можете вставить пробел между маркером и строкой без какого-либо влияния на способ синтаксического анализа вводимого данного.
. ! .
Строковый литералСтроковый литерал в условии проверки или поиска, например в предложении WHERE, интерпретируется в соответствии с набором символов клиентского соединения в момент проверки условия. Маркер потребуется, когда отыскиваемый столбец базы данных имеет набор символов, отличный от того, который был указан в клиентском соединении:
... WHERE name = _ISO8859_1 'joe';
! ! !
СОВЕТ. Когда вы разрабатываете приложение со смешанными наборами символов, то удобно использовать маркеры, особенно если ваше приложение будет работать со многими базами данных и/или будет распространяться интернационально.
. ! .
ТранслитерацияПреобразование символов из одного набора символов Firebird в другой - например, конвертирование из DOS437 в ISO8859_1 - является транслитерацией. Транслитерация в Firebird сохраняет точность символов: по определению она не подставляет никакого "заменителя" для входного символа, который не представлен в выходном наборе символов. Назначением такого ограничения является гарантия того, что возможна транслитерация одного и того же текста из одного набора символов в другой в любом направлении без потери символов в процессе транслитерации.
Ошибки транслитерацииFirebird выдает сообщение об ошибке, если символ во входном наборе не имеет точного представления в выходном наборе.
Пример, где может появиться ошибка транслитерации: когда приложение передает данные некоторого неопределенного набора символов в столбец, определенный с NONE, и позже пытается выбрать эти данные и поместить в другой столбец, который был определен с отличающимся набором символов. Хотя вы думаете, что это должно работать, потому что образы символов, похоже, принадлежат набору символов столбца назначения, транслитерация будет ошибочной, поскольку символ не представлен в наборе символов столбца назначения.
Исправление ошибок транслитерацииКак вы можете работать с группой символьных данных, которые вы сохранили с использованием неверного набора символов? "Трюк" заключается в использовании набора символов OCTETS в качестве "промежуточного аэродрома" между ошибочным и правильным кодированием. Поскольку OCTETS является специальным набором символов, который, не глядя, сохраняет то, что вы ему подсовываете (без транслитерации), он является идеальным для того, чтобы сделать символьные коды нейтральными в отношении кодовой страницы.
Предположим, ваша проблемная таблица имеет столбец COL ORIGINAL, который вы случайно создали с набором символов NONE, когда имели в виду CHARACTER SET WIN1251. Вы загрузили в этот столбец данные на русском языке, но каждый раз, когда вы пытаетесь получить из него данные, вы получаете противную ошибку транслитерации.
Вот что вам нужно сделать:
ALTER TABLE TABLEA
ADD COL_WIN1251 VARCHAR(30) CHARACTER SET WIN1251;
COMMIT;
UPDATE TABLEA
SET COL_WIN1251 = CAST(COL_ORIGINAL AS CHAR(30) CHARACTER SET OCTETS);
Теперь у вас есть временный столбец, созданный для хранения русских текстов, он хранит все из ваших "потерянных" текстов из неиспользуемого столбца COL ORIGINAL. Вы можете удалить столбец COL_ORIGINAL, а затем новый столбец COL_ORIGINAL С корректным набором символов. Просто скопируйте данные из временного столбца, и после подтверждения транзакции удалите временный столбец:
ALTER TABLE TABLEA
DROP COL_ORIGINAL;
COMMIT;
ALTER TABLE TABLEA
ADD COL_ORIGINAL VARCHAR(30) CHARACTER SET WIN1251;
COMMIT;
UPDATE TABLEA
SET СOL_ORIGINAL = COL_WIN1251;
COMMIT;
/* Было бы разумным сейчас посмотреть ваши данные! */
ALTER TABLE TABLEA
DROP COL_WIN1251;
COMMIT;
Набор символов для клиентского соединения
Когда клиентское приложение, например, isql, соединяется с базой данных, в протоколе соединения присутствует часть, которая информирует сервер о требуемом наборе символов. Набором символов соединения является нейтральный набор символов NONE, если не указано другое с использованием:
* SET NAMES во встроенном приложении или в isql;
* параметра isc_dpb_ic_ctype в блоке параметров базы данных (DPB) для API- функции isc_attach_database(). Классы RAD соединения с базой данных для Delphi, Java и других обычно представляют этот параметр как свойство.
Клиентское приложение задает набор символов до его соединения с базой данных. Например, следующая команда isql определяет, что isql использует набор символов ISO88591. По команде происходит соединение с базой данных autord.fdb из нашего предыдущего примера:
SET NAMES WIN1251;
CONNECT 'lserver:/data/authors.fdb' USER 'ALICE' PASSWORD 'XINEOHP';
Специальные наборы символов
Основное правило для наборов символов то, что каждый байт (пара или тройка байтов в случае многобайтовых наборов) специально определен по стандарту его реализации. Существует четыре особых исключения - NONE, OCTETS, ASCII и UNICODE FSS. В табл. 11.1 показаны специальные свойства этих наборов.