Категории
Самые читаемые
RUSBOOK.SU » Компьютеры и Интернет » Программирование » Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 40 41 42 43 44 45 46 47 48 ... 112
Перейти на страницу:

А потом, используя, например, компоненты 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,

JOB.LANGUAGE_REQ

FROM

JOB JOB

WHERE

(

JOB.JOB_CODE = ?OLD_JOB_CODE

and JOB.JOB_GRADE = ?OLD_JOB_GRADE

and JOB.JOB_COUNTRY = ?OLD_JOB_COUNTRY

)

Поле LANGUAGE_REQ является массивом (LANGUAGE_REQ VARCHAR(15) [1:5]) и, как видно из запросов, обрабатывается целиком, а не поэлементно. С одной стороны это удобно, но не позволяет использовать для редактирования таких полей специализированные визуальные компоненты типа TDBGrid. Если мы используем array-поля для хранения значительных массивов данных, мы в любом случае будем использовать "ручную" обработку данных, не прибегая к помощи визуальных компонент. Однако для наглядности примера мы позволим редактировать элементы массива в компонентах TEdit.

Фактически нам понадобится написать только два основных обработчика для событий: BeforePost и OnPostError

procedure TForml.ArrayDataSetBeforePost(DataSet: TDataSet);

begin

with ArrayDataSet do begin

SetArrayValue(FieldByName('LANGUAGE_REQ'),

VarArrayOf([

Editl.Text,

Edit2.Text,

Edit3.Text,

Edit4.Text,

Edits.Text

]) ) ;

end;

end;

procedure TForml.ArrayDataSetPostError(DataSet: TDataSet;

E: EDatabaseError; var Action: TDataAction);

begin

Action := daAbort;

MessageDlg('Error!', mtError, [mbOk], 0);

ArrayDataSet.Refresh;

end;

Метод SetArrayValue позволяет задать все элементы поля в виде массива. Важным моментом является обработчик ошибки ArrayDataSetPostError В случае неудачной операции Update или Insert необходимо восстанавливать внутренний идентификатор массива у редактируемой записи. Это правило диктуется функциями InterBase API, и мы должны их придерживаться. Для восстановления идентификатора необходимо получить значения полей текущей записи заново, что и делается при помощи явного вызова метода Refresh.

Для автоматического заполнения визуальных компонентов значениями элементов массива мы можем написать обработчик события AfterScroll:

procedure TForml.ArrayDataSetAfterScroll(DataSet: TDataSet);

var v: Variant;

begin

with ArrayDataSet do try

FInShowArrays := true;

v := ArrayFieldValue(FieldByName('LANGUAGE_REQ'));

Editl.Text := VarToStr(v[l]);

Edit2.Text := VarToStr(v[2]);

Edit3.Text := VarToStr(v[3]);

Edit4.Text := VarToStr(v[4]);

EditS.Text := VarToStr(v[5]);

finally

FInShowArrays:=false;

end;

end;

Флаг FInShowArrays используется в примере для того, чтобы не включать режим редактирования записи при обычной навигации.

Рекомендуется иметь под руками полный текст примера, который доступен на сайте http://www.fibplus.net. В книге мы указываем только те части примера, которые имеют непосредственное и наибольшее значение для работ с array-полями. Однако без полного текста некоторые части исходного текста могут показаться не до конца наглядными.

Данный способ работы с array-полями нельзя применять в режиме CachedUpdates.

Второй способ работы с array-полями позволяет использовать их в "живых" запросах и редактировать при помощи стандартных визуальных компонентов (рис. 2.62).

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

SelectSQL:

SELECT

JOB.JOB_CODE,

JOB.JOB_GRADE,

JOB.JOB_COUNTRY,

JOB.JOB_TITLE,

JOB.LANGUAGE_REQ[1] LQ1,

JOB.LANGUAGE_REQ[2] LQ2

FROM

JOB JOB

ORDER BY 1,2,3

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

UpdateSQL:

UPDATE JOB SET

JOB_TITLE = -?JOB_TITLE,

JOB JOB_GRADE=?JOB_GRADE,

JOB.JOB_COUNTRY=?JOB_COUNTRY,

LANGUAGE_REQ = ''LQ

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,

LANGUAGE_REQ

)

VALUES(

?JOB_CODE,

?JOB_GRADE,

?JOB_COUNTRY,

?JOB_TITLE,

?LQ

)

DeleteSQL:

DELETE FROM JOB

WHERE

JOB_CODE = ?OLD_JOB_CODE

and JOB_GRADE = ?OLD_JOB_GRADE

and JOB_COUNTRY = ?OLD_JOB_COUNTRY

RefieshSQL:

SELECT

JOB.JOB_CODE,

JOB.JOB_GRADE,

JOB.JOB_COUNTRY,

JOB.JOB_TITLE,

JOB.LANGUAGE_REQ[1] LQ1,

JOB.LANGUAGE_REQ[2] LQ2

FROM

JOB JOB

WHERE

(

JOB.JOB_CODE = ?OLD_JOB_CODE

and JOB. JOB_GRADE = ?OLD_JOB_GRADE

and JOB.JOB_COUNTRY = ?OLD_JOB_COUNTRY

)

На этот раз мы выбираем только два элемента из нашего поля-массива. Обратите внимание' несмотря на то что в выбирающем запросе мы явным образом выделяем два элемента массива, а в модифицирующих запросах мы обновляем поле целиком На самом деле, это, конечно, не совсем так, однако данный синтаксис наиболее удобен и близок к естественному SQL-запросу несмотря на то что во внутренней реализации FIBPlus использует специальные функции работы с массивами Обратим внимание на компонент QryAirField TpFIBUpdateObject. Именно он позволит нам правильно сформировать значение параметра "LQ" в модифицирующих запросах Разумеется, для этой цели вполне бы подошел и простой TpFIBQuery, однако удобство TpFIBUpdateObject заключается в первую очередь в том, что он выполняет запрос автоматически и сам подставляет туда нужные значения параметров в зависимости от значений TpFIBDataSet. Вот запрос, который выполняет QryArrField SELECT

JOB LANGUAGE_REQ,

JOB JOB_CODE

FROM

JOB JOB

WHERE

JOB JOB_CODE=?OLD_JOB_CODE and

JOB.JOB_GRADE=?OLD_JOB_GRADE and

JOB.JOB_COUNTRY=?OLD_JOB_COUNTRY

Обратим внимание на свойства QryArrField (рис 2 63)

Рис 2.63. Свойство компонента QryArrField

Обработчик QiyAnField AtteiExecute

procedure TForm2 QryArrFieldAfterExecute(Sender: TObject);

var v Variant,

begin

v = QryArrField Fields[0] GetArrayValues,

with ArrayDataSet do begin

v[l] = FieldByName('LQ1') AsString,

1 ... 40 41 42 43 44 45 46 47 48 ... 112
Перейти на страницу:
На этой странице вы можете бесплатно скачать Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil - А Ковязин торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит