Книга: Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Как сделать запрос редактируемым? Автоматическая генерация модифицирующих запросов в design-time и run-time
Как сделать запрос редактируемым? Автоматическая генерация модифицирующих запросов в design-time и run-time
Если вы попробуете исправить какие-то значения в CategoriesGrid, то увидите, что в текущем состоянии мы имеем iead-only-запрос Для того чтобы наш запрос стал редактируемым, или "живым", нам надо написать несколько дополнительных запросов, которые будут автоматически выполнятся компонентом CategonesDataSet при редактировании данных в CategoriesGrid. Необходимо заполнить свойства (рис. 2.21).
Рис 2.21. Свойства CategonesDataSet с запросами для чтения и модификации данных
FIBPlus включает специальный design-time-редактор для редактирования и генерации модифицирующих запросов. Вы можете вызвать "Generator SQLs" из контекстного меню, если нажмете правой кнопкой мыши на компоненте CategonesDataSet (рис. 2.22)
Для генерации модифицирующих запросов необходимо сначала указать основную таблицу в списке Если в запросе участвует только одна таблица, то она будет выбрана в списке автоматически После этого необходимо нажать кнопку Get Table Fields для заполнения списков "Key Fields" и "Update Fields '. В первом списке нужно выделить те поля, которые будут вставлены в условие WHERE во всех модифицирующих запросах. В списке "Update Fields" необходимо выделить те поля, которые мы хотим редактировать. По умолчанию выделены все поля таблицы "Categories" Теперь достаточно нажать кнопку Generate SQLs и получить автоматически все модифицирующие запросы, которые вы можете увидеть на закладке SQLs Например, мы получим следующий запрос для свойства InsertSQL
INSERT INTO "Categories"(
"Id" ,
" Name" ,
"GoodsCount"
VALUES(
:"Id",
:"Name",
:"GoodsCount"
Puc 2.22. Редактор компонента TpFIBDataSet, предназначенный для генерации модифицирующих запросов
Обратите внимание также на запрос для свойства RefreshSQL:
select * from "Categories"
WHERE
"Categories"."Id" = :"OLD_Id"
Это такой же выбирающий запрос, как и запрос в свойстве SelectSQL, но возвращать он должен только одну запись - текущую Теперь, после создания всех запросов, когда пользователь будет редактировать запись в CategoriesGrid, CategonesDataSet автоматически заполнит значения параметров : "Id", . "Name" и т д., теми значениями полей, которые наберет пользователь. После выполнения метода Post (который, в частности, вызывается при нажатии клавиши Enter в CategonesGnd) CategoriesDataSet выполнит соответствующий модифицирующий запрос После редактирования записи будет выполнен запрос из свойства UpdateSQL, при вставке новой записи - из InsertSQL, а при удалении записи - из DeleteSQL После выполнения любого модифицирующего запроса (кроме удаления) CategoriesDataSet автоматически выполняет запрос из RefreshSQL, подставляя в качестве условия текущие значения параметров. Это позволяет "узнать" значения всех полей текущей записи, если они были изменены при помощи триггеров базы данных.
Несколько слов о специальных префиксах для параметров, которые используются в FIBPlus.
Префикс "OLD_" фактически означает текущее значение одноименного поля или же предыдущее значение поля Термин "предыдущее значение" имеет смысл в запросе на удаление. Во всех остальных случаях, когда нужны актуальные значения полей, можно обходиться без данного префикса.
Префикс "NEW_" означает новое значение поля и фактически имеет смысл только в запросах на изменение и вставку. Однако новые значения полей в этих ситуациях также являются и текущими, а значит, префикс "NEW_" можно опускать
Существует также специальный префикс "MAS_", но мы доберемся до него несколько позже.
Поскольку мы сгенерировали все необходимые модифицирующие запросы, то уже можем запустить наше приложение, добавить пару категорий, изменить их названия и даже целиком удалить их.
Тем не менее генерация модифицирующих запросов в design-time не всегда удобна FIBPIus позволяет разработчику автоматически генерировать нужные запросы во время работы приложения, основываясь на запросе из свойства SelectSQL Для этого нужно использовать свойство AutoUpdateOptions (рис 223).
Рис 2.23. Комплексное свойство AutoUpdateOptions
Необходимо "включить" ключ "AutoReWriteSqls", указать ключевое поле, которое будет использовано в условиях WHERE (в нашем случае, это поле "Id") и указать название модифицируемой таблицы ("Categories"), поскольку в реальности запросы могут быть многотабличными. Теперь свойства InsertSQL, DeleteSQL, UpdateSQL и RefreshSQL будут генерироваться автоматически при открытии CategonesDataSet. To есть фактически мы имеем генератор запросов в run-time, что бывает очень удобно.
Есть еще один момент, связанный с генерацией модифицирующих запросов Например, если мы редактируем только название категории, то после нажатия на Entei на сервер будет отправлен запрос, в котором изменены два поля и Name и GoodsCount Фактически же мы изменяли только одно поле - "Name".В итоге если запись таблицы содержит значительный объем данных (например, длинные строковые поля), то при малейшем исправлении даже одного поля на сервер будут "уходить" все данные. При многопользовательской работе это создаст дополнительный лишний трафик Данной ситуации можно избежать но для этого необходимо, чтобы приложение выполняло 6oлee эффективные изменяющие запросы, например запрос:
UPDATE "Categories" SET
"Name" = ."Name"
WHERE
"Id" = :"OLD_Id"
в котором, как вы видите, участвует только то поле, значение которого действительно было изменено. Такая возможность существует, если мы включим ключ UpdateOnlyModifiedFields (разумеется, этот ключ действует, только если мы используем режим генерации запросов в run-time). В случае редактирования только поля "Name" компонент CategoriesDataSet автоматически сгенерирует запрос, приведенный выше, и будет генерировать каждый раз новые запросы в зависимости от того, какие поля изменялись.
Поскольку теперь наш CategoriesDataSet стал модифицируемым, то мы можем написать обработчики событий OnClick у трех кнопок справа от CategoriesGrid:
procedure TMainForm AddCatButtonClick(Sender TObject);
begin
CategoriesDataSet Append;
end;
procedure TMainForm.EditCatButtonClick(Sender: TObject);
begin
CategoriesDataSet Edit;
end;
procedure TMainForm.DeleteCatButtonClick(Sender: TObject);
begin
if MessageDlg('Вы уверены, что хотите удалить категорию "' +
CategoriesDataSet.FieldByName('Name').AsString + '"?',
mtConfirmation,
[mbYes, mbNo], 0) = mrYes then
CategoriesDataSet.Delete;
end;
- Подключение к базе данных, выполнение простых запросов
- Управление транзакциями
- Использование стандартных визуальных db-компонентов совместно с FIBPIus
- Как сделать запрос редактируемым? Автоматическая генерация модифицирующих запросов в design-time и run-time
- Правильный способ использования auto-increment полей в FIBPIus
- Разделенные транзакции: уникальная возможность избежать Deadlock. Режим AutoCommit
- Улучшенный оптимизатор запросов
- Ограничение времени ожидания для транзакций (Lock timeout)
- Асинхронный сервер и отмена выполняющихся запросов
- Как сделать, чтобы компьютер выключался
- DEADLOCK TIMEOUT
- CONNECTION TIMEOUT
- Timestamp request
- 1. Оператор Select – базовый оператор языка структурированных запросов
- 2. Унарные операции на языке структурированных запросов
- 3. Бинарные операции на языке структурированных запросов
- 4. Использование подзапросов
- Chapter 2 Building and Deploying a Run-Time Image