Чтение онлайн

на главную - закладки

Жанры

Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil

Востриков С М

Шрифт:

except

MessageDlg('Can''t restore connect',

mtlnformation, [mbOk], 0

);

Exit;

end

end;

if not Transaction.Active then Transaction StartTransaction;

ApplyUpdToBase;

Transaction.CoimutRetaining;

CommitUpdToCach;

except

if Transaction.Active then Transaction.RollBack;

end;

end;

На практике вы можете автоматически вызывать процедуру применения данных сразу из обработчика AfterRestoreConnect. В самой процедуре следует обратить внимание на методы ApplyUpdToBase и CommitUpdToCach. В отличие от стандартного метода ApplyUpdates, наследованного от TDataSet, который "не

замечает" скрытые в результате локальной фильтрации записи (более подробно этот вопрос будет рассмотрен в разделе "Локальная фильтрация"), методы ApplyUpdToBase и CommitUpdToCach позволяют обойти эту ошибку VCL

Эмуляция Boolean-полей

Вы уже знаете, что InterBase не поддерживает логического типа данных. Чем бы это ни было вызвано, нам остается только огорчиться этим фактом, поскольку на практике логический тип очень удобен. Разработчики, использующие InterBase, вынуждены заменять его другими типами, вводя ограничение на множество допустимых значений. Как правило, в базе данных создается соответствующий домен одного из двух видов.

CREATE DOMAIN TBOOLEAN_CHAR AS CHAR(1)

DEFAULT 'F' NOT NULL

CHECK (VALUE IN ('F', 'T'))

CREATE DOMAIN TBOOLEAN_INT AS INTEGER

DEFAULT 0 NOT NULL

CHECK (VALUE IN (0, 1))

При использовании любой библиотеки компонент для доступа к InterBase оба способа совершенно равноценны, поскольку для полей, созданных с такими доменами, в приложении все равно не создаются Boolean-поля. То есть если мы добавим некоторое логическое поле к нашей таблице:

ALTER TABLE "Categories" ADD IS_ACTIVE TBOOLEAN_INT

NOT NULL

А потом, используя, например, компоненты IBX, сделаем выборку при помощи компонента TIBDataSet:

SELECT "Categories"."Name", "Categories".IS_ACTIVE

FROM "Categories"

то в результате компонент создаст два внутренних компонента для полей:

* TIBStringField для поля "Name" и

* TmtergerField для поля "IS_ACTIVE"

Последнее совершенно верно, поскольку формально поле "IS_ACTIVE" не является логическим. Таким образом, все визуальные компоненты типа TDBGnd и его расширенные аналоги от сторонних производителей не будут обрабатывать данное поле так, как нам бы хотелось. Например, если даже компонент умеет рисовать "галочки" для Boolean-полей, значения которых равно True, то поскольку он будет "видеть" всего лишь целочисленное поле, то и выводить он будет "0" и "1" Разумеется, если мы напишем соответствующие обработчики событий, то сможем добиться более или менее сносного отображения логических величин для поля TIntergerField, однако FIBPlus предоставляет гораздо более простое и качественное решение

Фактически оно состоит только в том, что нам необходимо добавить ключ poUseBooleanField в свойстве PrepareOptions (рис. 2.60).

Рис 2.60. Использование PrepareOptions для эмуляции Boolean—полей

После этого поля, созданные на основе целочисленного домена, в названии которого присутствует слово "boolean", будут считать логическими, и для них будут создаваться экземпляры TFIBBooleanField.

Данный класс является прямым потомком класса TBooleanField и является полноценным логическим полем Любые визуальные компоненты для отображения данных будут работать с такими полями как с логическими, т. е. используя свойство AsBoolean. Вам же не придется писать для этого никакой дополнительный код.

Поддержка array-полей. Пример использования TpFIBUpdateObject и TDataSetContainer

InterBase с самых ранних версий позволял описывать в таблицах многомерные поля-массивы, делая хранение специализированных данных максимально удобным. Вы наверняка согласитесь, что матриц) проще всего хранить и обрабатывать в виде матрицы, а не раскладывать ее по отдельным полям и даже таблицам из-за ограничений реляционной модели Тем не менее поскольку array- поля не поддерживаются стандартом SQL, то и работа с такими полями на уровне SQL-запросов крайне затруднена. Фактически вы можете использовать массивы только поэлементно и только в операциях чтения Чтобы изменить значения array-поля, необходимо использовать специальные команды InterBase API. FIBPlus позволяет обойтись без подобных сложностей, взяв на себя всю рутину, связанную с array-полями

Мы продемонстрируем, как работать с array-полями при помощи FIBPlus на примере DemoArray5, входящем в стандартную поставку FIBPlus. Пример демонстрирует два варианта использования array-полей Первый способ позволяет редактировать array-поле при помощи специальных методов ArrayFieldValue и SetAiiayValue и работать с таким полем как с единой структурой (рис 2 6П

Рис 2.61. Внешний вид формы примера DemoArrayS Первый вариант использования array—полей

Рассмотрим запросы, заданные в соответствующих свойствах ArrayDataSet:

SeleetSQL

SELECT

JOB JOB_CODE,

JOB.JOB_GRADE,

JOB.JOB_COUNTRY,

JOB.JOB_TITLE,

JOB MIN_SALARY,

JOB.MAX_SALARY,

JOB.JOB_REQUIREMENT,

JOB.LANGUAGE_REQ

FROM

JOB JOB

ORDER BY 1,2,3

UpdateSQL:

UPDATE JOB SET

JOB_CODE = ?JOB_CODE,

JOB_GRADE = ?JOB_GRADE,

JOB_COUNTRY = ?JOB_COUNTRY,

JOB_TITLE = ?JOB_TITLE,

MIN_SALARY = ?MIN_SALARY,

MAX_SALARY = ?MAX_SALARY,

JOB_REQUIREMENT = ?JOB_REQUIREMENT,

JOB.LANGUAGE_REQ= ?LANGUAGE_REQ WHERE

JOB_CODE = ?OLD_JOB_CODE

and JOB_GRADE = ?OLD_JOB_GRADE

and JOB_COUNTRY = ?OLD_JOB_COUNTRY

InsertSQL

INSERT INTO JOB(

JOB_CODE,

JOB_GRADE,

JOB_COUNTRY,

JOB_TITLE,

MIN_SALARY,

MAX_SALARY,

JOB_REQUIREMENT,

JOB.LANGUAGE_REQ

)

VALUES(

?JOB_CODE,

?JOB_GRADE,

?JOB_COUNTRY,

?JOB_TITLE,

?MIN_SALARY,

?MAX_SALARY,

?JOB_REQUIREMENT,

?LANGUAGE_REQ

)

DeleteSQL:

DELETE FROM JOB

WHERE

J03_CODE = ? OLD_JOB_CODE

and JOB_GRADE = ?OLD_JOB_GRADE

and JOB_COUNTRY = ?OLD_JOB_COUNTRY

RefreshSQL:

SELECT

JOB.JOB_CODE,

JOB.JOB_GRADE,

JOB.JOB_COUNTRY,

JOB.JOB_TITLE,

JOB.MIN_SALARY,

JOB.MAX_SALARY,

JOB.JOB_REQUIREMENT,

Поделиться:
Популярные книги

Измена. Тайный наследник

Лаврова Алиса
1. Тайный наследник
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Тайный наследник

Инквизитор Тьмы

Шмаков Алексей Семенович
1. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Ротмистр Гордеев 3

Дашко Дмитрий
3. Ротмистр Гордеев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев 3

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Идеальный мир для Лекаря 28

Сапфир Олег
28. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 28

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Выстрел на Большой Морской

Свечин Николай
4. Сыщик Его Величества
Детективы:
исторические детективы
полицейские детективы
8.64
рейтинг книги
Выстрел на Большой Морской

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII