link2130 link2131 link2132 link2133 link2134 link2135 link2136 link2137 link2138 link2139 link2140 link2141 link2142 link2143 link2144 link2145 link2146 link2147 link2148 link2149 link2150 link2151 link2152 link2153 link2154 link2155 link2156 link2157 link2158 link2159 link2160 link2161 link2162 link2163 link2164 link2165 link2166 link2167 link2168 link2169 link2170 link2171 link2172 link2173 link2174 link2175 link2176 link2177 link2178 link2179 link2180 link2181 link2182 link2183 link2184 link2185 link2186 link2187 link2188 link2189 link2190 link2191 link2192 link2193 link2194 link2195 link2196 link2197 link2198 link2199 link2200 link2201 link2202 link2203 link2204 link2205 link2206 link2207 link2208 link2209 link2210 link2211 link2212 link2213 link2214 link2215 link2216 link2217 link2218 link2219 link2220 link2221 link2222 link2223 link2224 link2225 link2226 link2227 link2228 link2229 link2230 link2231 link2232 link2233 link2234 link2235 link2236 link2237 link2238 link2239 link2240 link2241 link2242 link2243 link2244 link2245 link2246 link2247 link2248 link2249 link2250 link2251 link2252 link2253 link2254 link2255 link2256 link2257 link2258 link2259 link2260 link2261 link2262 link2263 link2264 link2265 link2266 link2267 link2268 link2269 link2270 link2271

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