Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
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-поля для хранения значительных массивов данных, мы в любом случае будем использовать "ручную"
Фактически нам понадобится написать только два основных обработчика для событий: 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 используется в примере для того, чтобы не включать режим редактирования записи при обычной навигации.
Рекомендуется иметь под руками полный текст примера, который доступен на сайтеВ книге мы указываем только те части примера, которые имеют непосредственное и наибольшее значение для работ с 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.
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);