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

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

Жанры

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

Востриков С М

Шрифт:

var v Variant,

begin

v = QryArrField Fields[0] GetArrayValues,

with ArrayDataSet do begin

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

v[2] = FieldByName( LQ2 ) AsString,

QryArrField Fields[0] SetArrayValue(v);

QUpdate Params ByName[ LQ ] AsQuad :=

QryArrField.Fields[0] AsQuad;

end;

QryArrField Close;

end;

Теперь все становится совершенно очевидным Поскотьку свойство QiyAnField KindUpdate равно ukModify, то QiyArrField выполняет запрос при изменении записи в AnayDataSet а поскольку свойство QiyArrField ExecuteOider равно eoBeforeDefault, то запрос (QiyArrField SQL) выполняется до

того, как AirayDataSet выполнит свой собственный UpdateSQL В обработчике QryArrField AfterExecute мы всего лишь получаем заново все текущие элементы массива из базы данных, подменяем два из них новыми значениями, которые указал пользователь, и задаем значение параметра для ArrayDataSet.UpdateSQL Это означает что при выполнении ArrayDataSet.UpdateSQL формально будут обновлены все пять элементов массива но фактически изменены значения тотько двух элементов, которые изменил пользователь в TDBGrid.

Как видите работа с массивами достаточно проста поскотьку все основные сложности решают компоненты FIBPlus Хотелось бы также рассмотреть еще один специализированный компонент, входящий в FIBPlus Пример DemoArray демонстрирует работу с TDataSetContamei, использованным для синхронизации значений двух TpFIBDataSet, редактирующих наше апау-поле (рис 2 64)

Рис 2.64. Использование TDatabetContamer

Компонент DataSetContamerl помещен вместе с Database и Transaction на DataModule в нашем приложении Оба компонента AnayDataSet из разных форм нашего приложения ссылаются на DataSetContamerl при помощи свойства Contamei (рис 2 65)

Рис 2.65. Подключение компонентов TpFIBDataSet к DataSetContamerl

Компонент TDataSetContamei позволяет централизованно обрабатывать события от разных компонентов TpFIBDataSet, а также (расширяя, таким образом, список стандартных событий) посылать им сообщения, при получении которых они могут производить какие-то дополнительные действия. В нашем примере DataSetContainerl имеет обработчики двух событий OnDataSetEvent и OnUserEvent

procedure TDataModule2.DataSetsContainerlDataSetEvent(DataSet:

TDataSet;

Event: TKindDataSetEvent);

var Info: string;

begin

if Event = deAfterPost then

if DataSet.Owner.Name = 'Forml' then

DataSetsContainerl.NotifyDataSets(DataSet,

'Form2.ArrayDataSet', 'JOB_TABLE_CHANGED', Info)

else

if DataSet.Owner.Name = 'Form2' then

DataSetsContainerl.NotifyDataSets(DataSet,

'Form1.ArrayDataSet', 'JOB_TABLE_CHANGED', Info);

end;

procedure TDataModule2.DataSetsContainerlUserEvent(Sender:

TObject;

Receiver: TDataSet; const EventName: String; var Info:

String) ;

begin

if EventName = 'JOB_TABLE_CHANGED' then begin

with TpFIBDataSet(Sender) do

if (not CachedUpdates) and

(not TpFIBDataSet(Receiver).CachedUpdates) then

if

TpFIBDataSet(Receiver).Locate('JOB_CODE;JOB_GRADE;JOB_COUNTRY', varArrayOf([

FieldByNamet'JOB_CODE').AsString,

FieldByName('JOB_GRADE').AsString,

FieldByName('JOB_COUNTRY').AsString

]), []) then TpFIBDataSet(Receiver) Refresh

end;

end;

Смысл

действий сводится к следующему: после изменения записи в одном из наших компонентов ArrayDataSet происходит событие AfterPost. Поскольку DataSetContainerl перехватывает все события у подчиненных компонентов, то срабатывает обработчик OnDataSetEvent. Параметр Event равен deAfterPost, а параметр DataSet ссылается на тот компонент, в котором произошло изменение записи. При помощи вызова метода NotifyDataSets DataSetContainerl посылает сообщение оставшемуся компоненту ArrayDataSet о том, что произошло изменение записи. Поскольку оба компонента на самом деле редактируют одну и ту же таблицу, то желательно синхронизировать изменения. Синхронизация происходит в обработчике события OnUserEvent, то есть при получении "извещения" об изменении какого-либо из ArrayDataSet.

Если получено сообщение "JOB_TABLE_CHANGED" и ни в одном из наших двух ArrayDataSet не включен режим CachedUpdates (в этом случае Refresh просто ничего не даст), то мы позиционируемся на соответствующую запись и вызываем для нее метод Refresh, обновив, таким образом, запись в одном ArrayDataSet после того, как она была изменена в другом ArrayDataSet.

Данная технология является совершенно уникальной: использование DataSetContainer позволяет делать чрезвычайно гибкие и в то же время прозрачные схемы обработки и синхронизации данных в нескольких компонентах TpFIBDataSet.

Работа с BLOB-полями

Достаточно часто желательно хранить в базе данных разнообразные неструктурированные данные: изображения, OLE-объекты, звук и т. д. Специально для этих целей существует специальный тип данных - BLOB Продемонстрируем использование BLOB-полей на примере простого приложения (см. рис. 2.66), использующего следующую таблицу:

CREATE TABLE BIOLIFE (

ID INTEGER NOT NULL,

CATEGORY VARCKAR (15) character set WIN1251 collate

WIN1251,

COMMON_NAME VARCHAR (30) character set WIN1251 collate

WIN1251,

SPECIES_NAME VARCHAR (40) character set WIN1251 collate

WIN1251,

LENGTH_CM_ DOUBLE PRECISION,

LENGTH_IN DOUBLE PRECISION,

NOTES BLOB sub_type 1 segment size 80,

GRAPHIC BLOB sub_type 0 segment size 80);

Для вывода изображений, сохраненных в поле GRAPHIC, мы будем использовать стандартный компонент DBIMagel: TDBImage. Очевидно также, что запросы при работе с BLOB-полями ничем не отличаются от запросов со стандартными типами полей:

SelectSQL:

SELECT * FROM BIOLIFE

UpdateSQL:

UPDATE BIOLIFE Set

ID=?NEW_ID,

CATEGORY=?NEW_CATEGORY,

COMMON_NAME=?NEW_COMMON_NAME,

SPECIES_NAME=?NEW_SPECIES_NAME,

LENGTH__CM_=?NEW_LENGTH_CM_,

LENGTH_IN=?NEW_LENGTH_IN,

NOTES=?NEW_NOTES,

GRAPHIC=?NEW_GRAPHIC

WHERE ID=?OLD_ID

Рис 2.66. Внешний вид формы приложения для работы с BLOB-полями

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

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

На границе империй. Том 10. Часть 2

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Законы Рода. Том 3

Flow Ascold
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Бастард Императора. Том 8

Орлов Андрей Юрьевич
8. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 8

Первый среди равных. Книга III

Бор Жорж
3. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
6.00
рейтинг книги
Первый среди равных. Книга III

Восход. Солнцев. Книга I

Скабер Артемий
1. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга I

На границе империй. Том 7. Часть 5

INDIGO
11. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 7. Часть 5

Real-Rpg. Еретик

Жгулёв Пётр Николаевич
2. Real-Rpg
Фантастика:
фэнтези
8.19
рейтинг книги
Real-Rpg. Еретик

Отмороженный 3.0

Гарцевич Евгений Александрович
3. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 3.0

Газлайтер. Том 3

Володин Григорий
3. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 3

СД. Том 13

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

Хорошая девочка

Кистяева Марина
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Хорошая девочка

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл