Компонент 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 могут содержать более сложные запросы, нежели сгенерированные автоматически в его редакторе свойств, в соответствии с логикой содержащего его приложения.