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

на главную

Жанры

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

Востриков С М

Шрифт:

CategoriesDataSet.FieldByName('Name').AsString + '"?',

mtConfirmation,

[mbYes, mbNo], 0) = mrYes then

CategoriesDataSet.Delete;

end;

Правильный способ использования auto-increment полей в FIBPIus

В текущем состоянии наш запрос уже является редактируемым, мы можем вставлять новые записи, удалять записи существующие, а также редактировать значения полей Тем не менее пользователь должен самостоятельно указывать значение ключевого поля "Id", чтобы каждая запись была уникальной. Разумеется, мы можем переложить заботу о генерации уникальных значений на базу данных, написав соответствующий триггер, который при вставке новой записи будет автоматически получать

новое уникальное значение из некоторого 1енерагора. Такой способ гарантирует уникальность значений, но не гарантирует правильность работы клиентского приложения.

Особенность использования генераторов при написании корректно работающих приложений на FIBPlus состоит в том, что мы должны получать новое значение генератора в приложении до того, как выполним запрос на вставку записи. Зачем это нужно? Дело в том, что, как уже было сказано, после выполнения любого модифицирующего запроса (кроме удаления) CategoriesDataSet автоматически выполняет запрос из RefreshSQL, подставляя в качестве условия текущие значения параметров. В нашем случае для подстановки надо использовать значение первичного ключа (поле "Id"). Если мы не получим его заранее, а будем генерировать его, используя триггер, то мы не сможем подставить значение параметра : "OLD_Id" в запрос RefreshSQL, а значит, не сможем перечитать измененную запись. Таким образом, если какие-то поля записи были изменены триггерами базы данных, то мы не увидим этих изменений, пока не переоткроем весь запрос целиком Если же мы сначала получим новое значение генератора, а потом вставим это значение наравне с остальными параметрами, то затем мы сможем использовать это же значение, чтобы "перечитать" текущую запись, и будем "в курсе" актуальных значений полей без излишних переоткрываний!

TpFIBDataSet позволяет автоматически получать и вставлять значения первичного ключа, используя генератор. Для этого нам необходимо заполнить некоторые дополнительные ключи в свойстве AutoUpdateOptions (рис. 2.24).

Нужно указать название генератора Categories_Id_GEN. Свойство WhenGetGenID может принимать три возможных значения:

wgOnNewRecord - получать значение генератора сразу после подготовки буфера для новой записи;

wgBeforePost - получать значение генератора непосредственно перед отправкой новой записи на сервер;

wgNever- не использовать механизм генерации ключевых значений.

В нашем примере мы укажем значение wgOnNewRecord, чтобы сразу видеть в CategoriesGrid те значения поля "Id", которые будут получены с сервера. Теперь мы можем запустить наше приложение и отредактировать какие-либо существующие записи и даже вставить новые записи (рис. 2.25).

Рис 2.24. Использование AutoUpdateOptions для генерации уникальных значений первичного ключа

Рис 2.25. Внешний вид "живого" запроса

Из рисунка видно, что было автоматически получено значение для поля "Id" равное 66

Разделенные транзакции: уникальная возможность избежать Deadlock. Режим AutoCommit

CategoriesDataSet позволяет автоматически подтверждать сделанные изменения, если задать свойство AutoCommit в True. Теперь после вызова метода Post компонент CategoriesDataSet будет автоматически вызывать CategonesTransaction CommitRetainmg, сохраняя сделанные пользователем изменения и не закрывая при этом сам запрос. Такой подход уже снижает вероятность Deadlock,

который возможен при наличии длинных незакрытых транзакций, в контекст которых производились изменения данных.

Тем не менее, FIBPlus предлагает другую возможность, которая сводит вероятность возникновения Deadlock практически к нулю. TpFIBDataSet может работать одновременно в контексте двух транзакций. Одна длинная транзакция, в контексте которой данные только читаются, и другая короткая транзакция, в контексте которой выполняются все модифицирующие запросы.

Переименуем CategoriesTransaction в CategoriesReadTransaction и добавим еще один компонент CategoriesWriteTransaction. После этого зададим свойство UpdateTransaction у CategoriesDataSet в CategoriesWriteTransaction. Таким образом, теперь CategoriesDataSet подключен сразу к двум компонентам TpFTBTransaction (рис. 2.26).

Рис 2.26. Разделение читающей и пишущей транзакций

После вызова метода Post компонент CategoriesDataSet будет вызывать метод Commit у компонента CategoriesWriteTransaction. Однако, учитывая, что данные читаются в контексте совсем другой транзакции (CategoriesReadTransaction), это не вызовет закрытия всего CategoriesDataSet. To есть, используя FIBPlus, мы имеем настоящий режим AutoCommit, который уменьшает вероятность Deadlock и не мешает "видеть" нам актуальные значения всех записей. При использовании BDE в режиме AutoCommit вы не могли бы узнать реальные значения записей, пока не переоткроете запрос.

Кроме того, как уже упоминалось, для InterBase до версии 6.5 слишком частый вызов CommitRetaining мог привести к значительному "захвату" ресурсов сервером. При использовании механизма разделенных транзакций вы можете использовать режим AutoCommit без потерь производительности сервера для любых версий InterBase.

Механизм master-detail. Специальные опции TpFIBDatabase и TpFIBDataSet

Мы имеем возможность редактировать данные о категориях товаров и можем переходить к вопросам, связанным с построением связки master-detail. Для этого мы положим на форму дополнительные компоненты:

GoodsSource: TDataSource;

GoodsGrid: TDBGrid;

GoodsDataSet: TpFIBDataSet;

GoodsReadTransaction: TpFIBTransaction;

GoodsWriteTransaction: TpFIBTransaction;

AddGoodsButton: TButton;

EditGoodsButton: TButton;

DeleteGoodsButton: TButton;

"Свяжем" их так же, как и предыдущую группу компонентов, и напишем SelectSQL для GoodsDataSet:

SELECT * FROM "Goods"

WHERE "IdCategory" = :"Id"

Очевидно, что мы хотим выбрать при помощи detail-запроса только те товары, которые относятся к текущей категории. Значение параметра : "Id" должно браться из поля "Id" таблицы "Categories". Чтобы это происходило автоматически, необходимо задать свойство GoodsDataSet.DataSource равным CategoriesSource. Теперь сгенерируем модифицирующие запросы для GoodsDataSet так же, как мы делали это раньше для CategoriesDataSet.

После автоматической генерации мы должны внести некоторые изменения в полученные запросы. Рассмотрим, в частности, запрос для InsertSQL:

INSERT INTO "Goods"(

"Id",

"Name",

"Price",

"IdCategory" )

VALUES(

:"Id",

:"Name",

:"Price",

:"IdCategory"

)

Очевидно, что при добавлении нового товара, мы должны задать параметр : "IdCategory" текущим значением поля "Id" из таблицы "Categories". FIBPlus позволяет делать это автоматически при помощи префикса "MAS_", о котором мы уже упоминали выше:

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

На изломе чувств

Юнина Наталья
Любовные романы:
современные любовные романы
6.83
рейтинг книги
На изломе чувств

Подаренная чёрному дракону

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.07
рейтинг книги
Подаренная чёрному дракону

Совок 9

Агарев Вадим
9. Совок
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Совок 9

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Без шансов

Семенов Павел
2. Пробуждение Системы
Фантастика:
боевая фантастика
рпг
постапокалипсис
5.00
рейтинг книги
Без шансов

Система Возвышения. Второй Том. Часть 1

Раздоров Николай
2. Система Возвышения
Фантастика:
фэнтези
7.92
рейтинг книги
Система Возвышения. Второй Том. Часть 1

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Возвращение

Кораблев Родион
5. Другая сторона
Фантастика:
боевая фантастика
6.23
рейтинг книги
Возвращение

Баоларг

Кораблев Родион
12. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Баоларг

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Измена. Испорченная свадьба

Данич Дина
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Измена. Испорченная свадьба

70 Рублей

Кожевников Павел
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
6.00
рейтинг книги
70 Рублей