Компонент TUpdateSQL

TUpdateSQL предназначен для модификации данных на сервере с помощью заранее подготовленных SQL-предложений. Он позволяет определить различные операторы SQL для удаления, вставки и модификации записи, в том числе отличные от простых операторов DELETE, INSERT, APPEND. Эти операторы SQL содержатся в свойствах DeleteSQL, InsertSQL, ModifySQL соответственно.

Имя компонента TUpdateSQL может быть значением свойства UpdateObject какого-либо компонента TDataSet (например, TTable или TQuery). Если в этом случае используется кэширование данных, то в процессе выполнения транзакции, инициированной применением метода ApplyUpdates компонента TDataSet при попытке вставки, удаления или изменения записи генерируется SQL-запрос, содержащийся в свойстве InsertSQL, DeleteSQL или ModifySQL соответственно. Эти свойства можно редактировать, выбрав пункт UpdateSQL editor из контекстного меню компонента TUpdateSQL. Если же кэширование не используется, соответствующие SQL-запросы генерируются при выполнении метода Post компонента TDataSet.

Отметим, что эти три свойства поддерживают специальное расширение SQL, обеспечивающее возможность использования в запросах значений полей, существовавших до начала выполнения транзакции, переносящей на сервер данные из кэша (обычно это требуется при создании предложения WHERE в SQL-запросах). Такие значения полей обозначаются следующим образом: префикс "OLD_" + <имя поля>.

На этапе выполнения в процессе сохранения какой-либо записи на сервере компонент TUpdateSQL выбирает один из трех описанных в его свойствах запросов в соответствии со значением свойства UpdateKind компонента TDataSet, пересылает параметры запроса на сервер и выполняет запрос с целью фиксации на сервере данного обновления.

Для управления каждым отдельным обновлением внутри транзакции, переносящей данные из кэша на сервер, можно использовать событие OnApplyUpdate соответствующего компонента TDataSet, а также параметры UpdateKind (тип обновления) и UpdateAction, которому должно быть присвоено значение uaApplied, если обновление было успешным. Если установить значение этого параметра равным uaSkip, данная запись в кэше будет проигнорирована и не перенесена на сервер.

Для изучения поведения TUpdateSQL внесем изменения в уже созданное приложение, заменив компонент Table1 на компонент TQuery и добавив на форму один компонент TUpdateSQL и компонент TCheckBox. Свойства этих компонентов изменим следующим образом (табл.2):

Таблица 2

Компонент Свойство Значение
Query1 Active true
CachedUpdates true
UpdateObject UpdateSQL1
SQL Select * from clients
DataSource1 DataSet Query1
CheckBox1 Caption Использовать кэширование
UpdateSQL1 ModifySQL
update CLIENTS
set LAST_NAME = :LAST_NAME,
FIRST_NAME = :FIRST_NAME,
ACCT_NBR = :ACCT_NBR
where
LAST_NAME = :OLD_LAST_NAME and
FIRST_NAME = :OLD_FIRST_NAME and
ACCT_NBR = :OLD_ACCT_NBR
DeleteSQL
delete from CLIENTS
where
LAST_NAME = :OLD_LAST_NAME and
FIRST_NAME = :OLD_FIRST_NAME and
ACCT_NBR = :OLD_ACCT_NBR
InsertSQL
insert into CLIENTS
(LAST_NAME, FIRST_NAME, ACCT_NBR)
values
(:LAST_NAME, :FIRST_NAME, :ACCT_NBR)

Cтандартные SQL-запросы для добавления, удаления и изменения записи наиболее удобно создавать с помощью UpdateSQL editor, выбранного из контекстного меню компонента UpdateSQL1 (рис. 10)

Рис.10. UpdateSQL editor

Добавим в запрос вычисляемое поле STATUS для отображения состояния записи в кэше, уберем часть полей из списка отображаемых колонок DBGrid1, внесем изменения в существующие обработчики событий и добавим несколько новых (для события OnCalcField компонента Query1 и для события OnClick компонента CheckBox1):

 //---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include
"appl1.h"
//---------------------------------------------------------------------------
#pragma link
"Grids"
#pragma resource
"*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall
TForm1::TForm1(TComponent* Owner) :
TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall
TForm1::Button1Click(TObject *Sender)
{
Query1->ApplyUpdates();
}
//---------------------------------------------------------------------------
void __fastcall
TForm1::Button3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall
TForm1::Button2Click(TObject *Sender)
{
Query1->CancelUpdates();
}
//---------------------------------------------------------------------------
void __fastcall
TForm1::Query1CalcFields(TDataSet *DataSet)
{
AnsiString
UpdStr[] = {"Не
изменялась",
"Изменена",
"Добавлена",
"Удалена"};
if
(Query1->CachedUpdates)
Query1STATUS->Value=UpdStr[Query1->UpdateStatus()];
}
//---------------------------------------------------------------------------
void __fastcall
TForm1::CheckBox1Click(TObject *Sender)
{
Query1->CachedUpdates=CheckBox1->Checked;
}
//---------------------------------------------------------------------------

Если перед запуском приложения запустить утилиту SQL Monitor, то можно пронаблюдать, как генерируются запросы, содержащиеся в свойствах компонента UpdateSQL1, при использовании кэширования и без него, а также как отображается состояние конкретной записи при использовании кэширования (рис.11):

Рис.11. Приложение с использованием UpdateSQL

Отметим, что свойства DeleteSQL, InsertSQL, ModifySQL компонента TUpdateSQL могут содержать более сложные запросы, нежели сгенерированные автоматически в его редакторе свойств, в соответствии с логикой содержащего его приложения.