Odlo╛enΘ aktualizace umo╛≥ujφ zφskßvat data z databßze,
ulo╛it a editovat je lokßln∞ a potom aplikovat odlo╛enΘ aplikace na databßzi
najednou. Kdy╛ odlo╛enΘ aktualizace jsou povoleny, pak aktualizace datovΘ
mno╛iny (jako je odesφlßnφ zm∞n a ru╣enφ zßznam∙) jsou ulo╛eny v internφ
vyrovnßvacφ pam∞ti mφsto p°φmΘho zßpisu do p°ipojenΘ tabulky datovΘ mno╛iny.
Kdy╛ zm∞ny jsou kompletnφ, pak na╣e aplikace volß metodu, kterß zapφ╣e
odlo╛enΘ aktualizace do databßze a vyprßzdnφ vyrovnßvacφ pam∞╗.
Tato kapitola popisuje jak pou╛φvat odlo╛enΘ aktualizace.
Je zde takΘ popsßna komponenta TUpdateSQL, kterß m∙╛e b²t pou╛ita
spoleΦn∞ s odlo╛en²mi aktualizacemi k aktualizaci libovolnΘ datovΘ mno╛iny,
a to obzvlß╣t∞ datov²ch mno╛in, kterΘ nejsou normßln∞ aktualizovatelnΘ.
Kapitola se sklßdß z t∞chto sekcφ:
UrΦenφ, kdy pou╛φvat odlo╛enΘ
aktualizace
Odlo╛enΘ aktualizace jsou hlavn∞ urΦeny k omezenφ datovΘho
p°φstupu na vzdßlen² databßzov² server z d∙vodu:
-
Minimalizace Φasu transakcφ
-
Minimalizacφ provozu v sφti
I kdy╛ odlo╛enΘ aktualizace mohou minimalizovat Φas transakcφ
a drasticky redukovat sφ╗ov² provoz, nejsou vhodnΘ pro v╣echny aplikace
databßzov²ch klient∙, kterΘ pracujφ se vzdßlen²mi servery. Jsou t°i oblasti
p°edpoklad∙, kterΘ urΦujφ zda odlo╛enΘ aktualizace pou╛φvat:
-
Odlo╛enß data jsou lokßlnφ v na╣φ aplikaci a nejsou pod °φzenφm
transakcφ. V ru╣nΘm prost°edφ Klient/server to mß pro na╣i aplikaci dva
d∙sledky:
-
Ostatnφ aplikace mohou zp°φstup≥ovat a m∞nit aktußlnφ data
na serveru zatφmco nß╣ u╛ivatel edituje lokßlnφ kopii dat.
-
Ostatnφ aplikace nemohou vid∞t ╛ßdnΘ datovΘ zm∞ny provedenΘ
na╣φ aplikacφ, dokud neaplikujeme v╣echny zm∞ny.
-
Ve vzßjemn²ch vztazφch Master-detail, sprßva odlo╛en²ch aktualizacφ
m∙╛e b²t choulostivß.
-
K aplikovßnφ odlo╛en²ch aktualizacφ na datov²ch mno╛inßch
zalo╛en²ch na dotazech urΦen²ch pouze pro Φtenφ pou╛ijeme aktualizaΦnφ
objekty.
Komponenty datovΘho p°φstupu poskytujφ metody odlo╛en²ch
aktualizacφ a metody °φzenφ transakcφ, kterΘ m∙╛eme pou╛φt v k≤du na╣φ
aplikace k °e╣enφ t∞chto situacφ, ale musφme pamatovat na v╣echny mo╛nΘ
scΘnß°e, kterΘ se mohou vyskytnout v na╣em pracovnφm prost°edφ.
Pou╛φvßnφ odlo╛en²ch aktualizacφ
Tato sekce poskytuje zßkladnφ seznßmenφ s pou╛φvßnφm odlo╛en²ch
aktualizacφ v aplikaci. Pokud jsme zatφm odlo╛enΘ aktualizace nepou╛φvali,
pak tento popis m∙╛eme pou╛φt jako nßvod pro implementaci odlo╛en²ch aktualizacφ
v na╣i aplikaci.
K pou╛itφ odlo╛en²ch aktualizacφ, v na╣i aplikaci musφ
prob∞hnout toto:
-
Povolφme odlo╛enΘ aktualizace. Povolenφm odlo╛en²ch aktualizacφ
zp∙sobφme, ╛e transakce Φtou pouze data se serveru podle pot°eby pro ·Φely
zobrazenφ a pak konΦφ. Lokßlnφ kopie dat jsou ulo╛eny v pam∞ti pro zobrazovßnφ
a editaci.
-
Zobrazujeme a editujeme lokßlnφ kopie zßznam∙, vklßdßme novΘ
zßznamy a ru╣φme existujφcφ zßznamy. P∙vodnφ kopie ka╛dΘho zßznamu i v╣echny
jeho editace jsou ulo╛eny v pam∞ti.
-
Zφskßvßme dal╣φ zßznamy podle pot°eby. Jak u╛ivatel prochßzφ
zßznamy, jsou zφskßvßny dal╣φ zßznamy. Ka╛dΘ zφskßvßnφ prob∞hne v kontextu
jinΘ Φtecφ transakce. Aplikace m∙╛e p°φpadn∞ zφskat v╣echny zßznamy najednou
mφsto zφskßvßnφ po mal²ch dßvkßch zßznam∙.
-
PokraΦujeme v zobrazovßnφ a editaci lokßlnφ kopie zßznam∙,
dokud v╣echny po╛adovanΘ zm∞ny nejsou provedeny.
-
Aplikujeme lokßln∞ odlo╛enΘ zm∞ny do databßze nebo zm∞ny
zru╣φme. Pro ka╛d² zßznam zapisovan² do databßze je generovßna udßlost
OnUpdateRecord.
Pokud p°i zßpisu jistΘho zßznamu do databßze vznikne chyba, pak je generovßna
udßlost OnUpdateError, kterß umo╛≥uje aplikaci chybu opravit, a
pokraΦovat v aktualizaci. Kdy╛ aktualizace jsou kompletnφ, pak v╣echny
·sp∞╣n∞ aplikovanΘ aktualizace jsou uvoln∞ny z lokßlnφ odklßdacφ pam∞ti.
Pokud mφsto aplikace aktualizacφ, aplikace aktualizace zru╣φ,
pak lokßlnφ kopie zßznam∙ a v╣echny zm∞ny jsou uvoln∞ny bez zßpisu zm∞n
do databßze.
Na popis t∞chto operacφ se podφvejte do:
Povolovßnφ
a zakazovßnφ odlo╛en²ch aktualizacφ
Odlo╛enΘ aktualizace jsou povolovßny a zakazovßny vlastnostφ
CachedUpdates
komponet TTable, TQuery a TStoredProc. Implicitn∞
CachedUpdates
je false, co╛ znamenß, ╛e pro datovou mno╛inu odlo╛enΘ aktualizace
nejsou povoleny.
Poznßmka: KlientskΘ datovΘ mno╛iny v╛dy odklßdajφ
aktualizace. Tedy nemajφ vlastnost CachedUpdates nebo╗ odlo╛enΘ
aktualizace nelze pro klientskou datovou mno╛inu zakßzat.
K pou╛φvßnφ odlo╛en²ch aktualizacφ nastavφme CachedUpdates
na
true a to p°i nßvrhu (prost°ednictvφm Inspektora objektu) nebo
za b∞hu. Pokud je nastaveno CachedUpdates na true, pak je
generovßna udßlost
OnUpdateRecord. Vφce informacφ o udßlosti OnUpdateRecord
je uvedeno ve Vytvß°enφ
obsluhy udßlosti OnUpdateRecord.
Nap°. nßsledujφcφ k≤d povoluje za b∞hu odlo╛enΘ aktualizace
pro datovou mno╛inu:
CustomersTable->CachedUpdates = true;
Kdy╛ jsou odlo╛enΘ aktualizace povoleny, pak kopie v╣ech
zßznam∙ pot°ebn²ch pro zobrazovacφ a editaΦnφ ·Φely jsou odlo╛eny v lokßlnφ
pam∞ti. U╛ivatel vidφ a edituje tuto lokßlnφ kopii dat. Zm∞ny, vklßdßnφ
a ru╣enφ jsou takΘ odklßdßny do pam∞ti. Toto je shroma╛∩ovßno v pam∞ti,
dokud lokßlnφ zm∞ny nejsou aplikovßny do databßze. Pokud zm∞n∞nΘ zßznamy
jsou ·sp∞╣n∞ aplikovßny do databßze, pak zßznamy t∞chto zm∞n jsou uvoln∞ny
z odklßdacφ pam∞ti.
Poznßmka: Aplikovßnφm odlo╛en²ch aktualizacφ
nezakß╛eme budoucφ odlo╛enΘ aktualizace; jsou zm∞ny pouze zapsßny do databßze
a vyprßzdn∞na odklßdacφ pam∞╗.
K zßkazu odlo╛en²ch aktualizacφ pro datovou mno╛inu nastavφme
CachedUpdates
na false. Pokud zakß╛eme odlo╛enΘ aplikace, kdy╛ mßme je╣t∞ n∞jakΘ
neaplikovanΘ zm∞ny, pak tyto zm∞ny jsou ztraceny bez varovßnφ. Na╣e aplikace
m∙╛e testovat vlastnost UpdatePending k zji╣t∞nφ zda existujφ nevy°φzenΘ
aktualizace p°ed zßkazem odlo╛en²ch aktualizacφ. Nap°.
if (CustomersTable->UpdatesPending)
if (Application->MessageBox("Discard
pending updates?",
"Unposted changes",
MB_YES | MB_NO) == IDYES)
CustomersTable->CachedUpdates
= false;
Zφskßvßnφ zßznam∙
Implicitn∞, kdy╛ povolφme odlo╛enΘ aktualizace, pak datovΘ
mno╛iny podporujφcφ BDE automaticky zφskßvajφ data z databßze, kdy╛ jsou
pot°eba. DatovΘ mno╛iny zφskßvajφ pot°ebnΘ zßznamy k zobrazenφ. V pr∙b∞hu
zpracovßnφ m∙╛eme mnohokrßt zφskßvat zßznamy. Pokud na╣e aplikace mß specißlnφ
po╛adavek, pak m∙╛e v╣echny zßznamy zφskat najednou. K zφskßnφ v╣ech zßznam∙
volßme metodu FetchAll datovΘ mno╛iny. FetchAll vytvß°φ v
pam∞ti lokßlnφ kopii v╣ech zßznam∙ z datovΘ mno╛iny. Pokud datovß mno╛ina
obsahuje mnoho zßznam∙ nebo zßznamy s velk²mi polo╛kami BLOB, pak FetchAll
nem∙╛eme pou╛φt.
KlientskΘ datovΘ mno╛iny pou╛φvajφ vlastnost PacketRecords
k indikovßnφ poΦtu zßznam∙, kterΘ byly zφskßny. Pokud nastavφme vlastnost
FetchOnDemand
na true, pak klientskß datovß mno╛ina automaticky zpracovßvß zφskßvßnφ
dat v p°φpad∞ pot°eby. Jinak, musφme volat metodu
GetNextPacket
k zφskßnφ zßznam∙ z datovΘho serveru.
Aplikovßnφ odlo╛en²ch aktualizacφ
Kdy╛ datovß mno╛ina je v re╛imu odlo╛en²ch aktualizacφ, pak
zm∞ny dat nejsou zapisovßny do databßze dokud na╣e aplikace explicitn∞
nevolß metodu, kterß tyto zm∞ny aplikuje. Normßln∞, aplikace aplikuje aktualizace
v reakci na akci u╛ivatele, jako je stisk tlaΦφtka nebo volba v nabφdce.
D∙le╛itΘ: K aplikovßnφ aktualizacφ na mno╛inu
zßznam∙ zφskan²ch dotazem SQL, kter² nevracφ ╛ivou v²sledkovou mno╛inu,
musφme pou╛φt objekt
TUpdateSQL specifikujφcφ jak provΘst aktualizace.
Pro aktualizaci spojenφ (dotazu na dvou nebo vφce tabulkßch), musφme poskytnout
jeden objekt
TUpdateSQL pro ka╛dou pou╛itou tabulku a musφme pou╛φt
obsluhu udßlosti
OnUpdateRecord k donucenφ t∞chto objekt∙ provΘst
aktualizaci.
Aplikovßnφ aktualizacφ je dvoufßzov² proces, kter² probφhß
v kontextu °φzenφ transakcφ komponenty databßze k umo╛n∞nφ aplikace zotavovat
se z chyb.
Kdy╛ aplikujeme aktualizace pod °φzenφm transakcφ databßze,
pak nastanou nßsledujφcφ udßlosti:
-
Je zahßjena databßzovß transakce.
-
Odlo╛enΘ aktualizace jsou zapsßny do databßze (fßze 1). Obsluha
udßlosti
OnUpdateRecord je vyvolßna (pokud existuje) pro ka╛d² zßznam
zapisovan² do databßze. Pokud p°i aplikovßnφ zßznam∙ do databßze vznikne
chyba, pak je generovßna udßlost
OnUpdateError.
Pokud zßpis do databßze je ne·sp∞╣n²:
-
DatabßzovΘ zm∞ny jsou zru╣eny a transakce je ukonΦena.
-
Odlo╛enΘ aktualizace nejsou zapsßny, z∙stßvajφ v internφ
odklßdacφ pam∞ti.
Pokud zßpis do databßze je ·sp∞╣n²:
-
DatabßzovΘ zm∞ny jsou zapsßny a transakce je ukonΦena.
-
Odlo╛enΘ aktualizace jsou zapsßny a internφ odklßdacφ pam∞╗
je vyprßzdn∞na (fßze 2).
Dvoufßzovß mo╛nost aplikovßnφ odlo╛en²ch aktualizacφ umo╛≥uje
efektivnφ zotavenφ z chyb, a to obzvlß╣t∞ p°i aktualizovßnφ vφce datov²ch
mno╛in (nap°. datov²ch mno╛in spojen²ch do vztahu Master-detail).
Jsou dva zp∙soby aplikovßnφ aktualizacφ. Pro aplikovßnφ
aktualizacφ pro specifikovanou mno╛inu datov²ch mno╛in p°i°azen²ch ke komponent∞
databßze, volßme metodu ApplyUpdates komponenty databßze. K aplikovßnφ
aktualizacφ pro jednu datovou mno╛inu volßme metody ApplyUpdates
a Commit datovΘ mno╛iny.
Aplikovßnφ odlo╛en²ch
aktualizacφ metodou komponenty databßze
Normßln∞, aplikace odklßdß aktualizace na ·rovni datovΘ mno╛iny.
NicmΘn∞, n∞kdy je d∙le╛itΘ aplikovat aktualizace na vφce svßzan²ch datov²ch
mno╛inßch v kontextu jedinΘ transakce. Nap°. kdy╛ pracujeme s formou Master-detail,
pak m∙╛eme po╛adovat zapsat zm∞ny do obou tabulek spoleΦn∞.
K aplikovßnφ odlo╛en²ch aktualizacφ na jednu nebo vφce
datov²ch mno╛in v kontextu databßzovΘho p°ipojenφ, volßme metodu ApplyUpdates
komponenty databßze. Nßsledujφcφ k≤d aplikuje aktualizace datovΘ mno╛iny
CustomersQuery
v reakci na stisknutφ tlaΦφtka:
void __fastcall TForm1::ApplyButtonClick(TObject
*Sender)
{
// pro lokßlnφ databßze jako jsou
Paradox, dBASE a FoxPro
// nastavφme TransIsolation na DirtyRead
if(!Database1->IsSQLBased &&Database1->TransIsolation
!= tiDirtyRead)
Database1->TransIsolation
= tiDirtyRead;
Database1->ApplyUpdates(&CustomersQuery,0);
}
V²╣e uvedenß sekvence spou╣tφ transakci a zapisuje odlo╛enΘ
aktualizace do databßze. V p°φpad∞ ·sp∞chu transakce odlo╛enΘ aktualizace
jsou zapsßny do databßze. V p°φpad∞ ne·sp∞chu, transakce je zru╣ena a stav
odlo╛en²ch aktualizacφ se nem∞nφ. V tomto druhΘm p°φpad∞, na╣e aplikace
m∙╛e zpracovat chyby odlo╛en²ch aktualizacφ pomocφ udßlosti OnUpdateError
datovΘ mno╛iny. Viz Zpracovßnφ
chyb odlo╛en²ch aktualizacφ.
Hlavnφ v²hodou volßnφ metody ApplyUpdates komponenty
databßze je to, ╛e m∙╛eme aktualizovat libovoln² poΦet komponent datov²ch
mno╛in, kterΘ jsou p°i°azeny k databßzi. Dva parametry metody ApplyUpdates
pro databßzi jsou pole TDBDataSet a index poslednφ datovΘ mno╛iny
v poli. K aplikovßnφ aktualizacφ na vφce ne╛ jednu datovou mno╛inu vytvo°φme
lokßlnφ pole ukazatel∙ na datovΘ mno╛iny. Nap°. nßsledujφcφ k≤d aplikuje
aktualizace pro dv∞ tabulky pou╛itΘ ve vztahu Master-detail:
TDBDataSet* ds[] = {MasterTable, DetailTable};
if(!Database1->IsSQLBased &&Database1->TransIsolation
!= tiDirtyRead)
Database1->TransIsolation = tiDirtyRead;
Database1->ApplyUpdates(ds,1);
Vφce informacφ o aplikovßnφ tabulek Master-detail viz
Aplikovßnφ
aktualizacφ pro tabulky Master-detail.
Aplikovßnφ odlo╛en²ch
aktualizacφ metodami komponenty datovΘ mno╛iny
M∙╛eme aplikovat aktualizace pro jednotlivΘ datovΘ mno╛iny
p°φmo metodami
ApplyUpdates a CommitUpdates datovΘ mno╛iny.
Ka╛dß z t∞chto metod zaobaluje jednu fßzi aktualizaΦnφho procesu:
-
ApplyUpdates zapisuje odlo╛enΘ aktualizace do databßze
(fßze 1).
-
CommitUpdates vyprazd≥uje internφ odklßdacφ pam∞╗,
kdy╛ zßpis do databßze byl ·sp∞╣n² (faze 2).
Aplikovßnφ aktualizacφ na ·rovni datov²ch mno╛in, dßvß °φzenφ
nad po°adφm, ve kterΘm aktualizace jsou aplikovßny na individußlnφ datovΘ
mno╛iny. Po°adφ aktualizacφ je obzvlß╣t∞ kritickΘ p°i zpracovßvßnφ vzßjemn²ch
vztah∙ Master-detail. K zaji╣t∞nφ sprßvnΘho po°adφ aktualizace t∞chto tabulek,
musφme aplikovat aktualizace na ·rovni datov²ch mno╛in. Vφce informacφ
viz Aplikovßnφ
aktualizacφ pro tabulky Master-detail.
Nßsledujφcφ k≤d ukazuje jak aplikovat aktualizace v transakci
pro datovou mno╛inu CustomerQuery, kterß byla v²╣e pou╛ita v ukßzce
aktualizace pomocφ metody databßze:
void __fastcall TForm1::ApplyButtonClick(TObject
*Sender)
{
Database1->StartTransaction();
try
{
if(!Database1->IsSQLBased
&&Database1->TransIsolation != tiDirtyRead)
Database1->TransIsolation
= tiDirtyRead;
CustomerQuery->ApplyUpdates();
// pokus o zßpis aktualizacφ do databßze
Database1->Commit(); //
·sp∞ch, zm∞ny zapsßny
}
catch (...)
{
Database1->Rollback();
// ne·sp∞ch, zru╣enφ zm∞n
throw; // op∞tovnΘ generovßnφ
v²jimky k zabrßn∞nφ volßnφ CommitUpdates
}
CustomerQuery->CommitUpdates(); //
·sp∞ch, vyprßzdn∞nφ odklßdacφ pam∞ti
}
Pokud b∞hem volßnφ ApplyUpdates vznikne v²jimka,
pak databßzovß transakce je zru╣ena. Tφm zajistφme, ╛e databßzovΘ tabulky
nejsou zm∞n∞ny. P°φkaz throw mimo blok try ... catch op∞tovn∞
generuje v²jimku a zabrßnφ volßnφ CommitUpdates. Proto╛e CommitUpdates
nenφ volßna, internφ odklßdacφ pam∞╗ nenφ vyprßzdn∞na a m∙╛eme tedy zpracovat
chyby a pokusit se o aktualizaci znova.
Aplikovßnφ
aktualizacφ pro tabulky Master-detail
Kdy╛ aplikujeme aktualizace pro tabulky Master-detail, pak
je d∙le╛itΘ po°adφ, ve kterΘm datovΘ mno╛iny aktualizujeme. Obecn∞ v╛dy
aktualizujeme tabulku Master p°ed tabulkou Detail, mimo p°φpadu ru╣enφ
zßznam∙. Ve slo╛it∞j╣φch vzßjemn²ch vztazφch, kde detailnφ tabulka jednoho
vztahu je tabulkou Master pro jinou detailnφ tabulku, pou╛φvßme stejnß
pravidla.
Tabulky Master-detail m∙╛eme aktualizovat na ·rovni databßze
nebo datov²ch mno╛in. Pro ·Φely °φzenφ, aplikujeme aktualizace na ·rovni
datov²ch mno╛in. Nßsledujφcφ p°φklad ukazuje jak² k≤d pou╛φt k aplikovßnφ
aktualizacφ na dv∞ tabulky Master a Detail, kterΘ jsou ve
vzßjemnΘm vztahu Master-detail:
Database1->StartTransaction();
try
{
Master->ApplyUpdates();
Detail->ApplyUpdates();
Database1->Commit();
}
catch(...)
{
Database1->Rollback();
throw;
}
Master->CommitUpdates();
Detail->CommitUpdates();
Pokud v pr∙b∞hu aplikovßnφ aktualizacφ vznikne chyba,
pak tento k≤d zachovß odlo╛enΘ aktualizace i p°ipojenß data v databßzi
ve stejnΘm stavu, jako byl p°ed volßnφm ApplyUpdates.
Pokud v²jimka vznikne v pr∙b∞hu volßnφ Master->ApplyUpdates,
pak je zpracovßna podobn∞ jako v samostatnΘ datovΘ mno╛in∞ popsanΘ v²╣e.
P°edpoklßdejme ale, ╛e volßnφ Master->ApplyUpdates je ·sp∞╣nΘ, a
nßsledujφcφ volßnφ Detail->ApplyUpdates chybuje. V tomto p°φpad∞
zm∞ny jsou ji╛ aplikovßny na tabulku Master, ale nestaly se zatφm
trval²mi, proto╛e volßnφ Master->Commit bylo p°eskoΦeno. Volßnφm
Database1->Rollback je dßle (pokud nastala chyba) databßze vrßcena do stavu
p°ed zahßjenφm aktualizacφ.
Zru╣enφ nevy°φzen²ch
odlo╛en²ch aktualizacφ
Nevy°φzenΘ odlo╛enΘ aktualizace jsou aktualizaΦnφ zßznamy,
kterΘ jsou odeslßny do odklßdacφ pam∞ti, ale nejsou aplikovßny na databßzi.
Jsou t°i zp∙soby zru╣enφ nevy°φzen²ch odlo╛en²ch aktualizacφ:
Zru╣enφ
nevy°φzen²ch aktualizacφ a zßkaz dal╣φch odlo╛en²ch aktualizacφ
K zru╣enφ dal╣φho odklßdßnφ aktualizacφ a zru╣enφ v╣ech nevy°φzen²ch
aktualizacφ bez jejich aplikovßnφ, nastavφme vlastnost CachedUpdates
na false. Kdy╛ CachedUpdates je nastaveno na false,
pak je automaticky vyvolßna metoda CancelUpdates.
Z odlo╛en²ch aktualizacφ, zru╣enΘ zßznamy jsou obnoveny,
modifikovanΘ zßznamy jsou vrßceny na p∙vodnφ hodnoty a nov∞ vlo╛enΘ zßznamy
jsou zru╣eny.
Poznßmka: Tato mo╛nost nenφ dostupnß pro klientskΘ
datovΘ mno╛iny.
Zru╣enφ nevy°φzen²ch
odlo╛en²ch aktualizacφ
CancelUpdates vyprazd≥uje odklßdacφ pam∞╗ v╣ech nevy°φzen²ch
aktualizacφ a obnovuje datovou mno╛inu do stavu ve kterΘm byla p°i otev°enφ,
v dob∞ kdy odlo╛enΘ aktualizace byly povoleny nebo aktualizace naposled
·sp∞╣n∞ aktualizovßny. Nap°. nßsledujφcφ p°φkaz ru╣φ aktualizace pro CustomersTable:
CustomersTable->CancelUpdates();
Z odlo╛en²ch aktualizacφ, zru╣enΘ zßznamy jsou obnoveny,
modifikovanΘ zßznamy jsou vrßceny na p∙vodnφ hodnoty a nov∞ vlo╛enΘ zßznamy
jsou zru╣eny.
Poznßmka: Volßnφ CancelUpdates nezakazuje
odlo╛enΘ aktualizace. Jsou pouze zru╣eny nevy°φzenΘ aktualizace.
Zru╣enφ aktualizacφ
pro souΦasn² zßznam
RevertRecord obnovuje souΦasn² zßznam v datovΘ mno╛in∞
na stav ve kterΘm byl p°i otev°enφ, v dob∞ kdy odlo╛enΘ aktualizace byly
povoleny nebo aktualizace naposled ·sp∞╣n∞ aktualizovßny. V∞t╣inou je pou╛φvßna
v obsluze udßlosti OnUpdateError k oprav∞ chybov²ch situacφ. Nap°.
CustomersTable->RevertRecord();
Odvolßnφ odlo╛en²ch zm∞n na jednom zßznamu neovliv≥uje
ostatnφ zßznamy. Pouze pokud jsou odlo╛eny aktualizace jedinΘho zßznamu
a zm∞ny jsou odvolßny pomocφ RevertRecord, pak vlastnost UpdatesPending
pro komponentu datovΘ mno╛iny je automaticky zm∞n∞na z true na false.
Pokud zßznam nenφ modifikovßn, pak toto volßnφ nemß ╛ßdn²
efekt. Vφce informacφ o vytvß°enφ obsluhy OnUpdateError, viz Vytvß°enφ
obsluhy udßlostφ OnUpdateError.
Odvolßnφ odlo╛en²ch zru╣enφ
zßznam∙
Odvolßnφ zru╣enφ odlo╛en²ch zßznam∙ vy╛aduje jinΘ k≤dovßnφ,
proto╛e zru╣en² zßznam je odeslßn do odklßdacφ pam∞ti a nem∙╛e se ji╛ stßti
souΦasn²m zßznamem a nenφ dßle v datovΘ mno╛in∞. V n∞kter²ch situacφch
jej ale m∙╛eme chtφt obnovit. Pomocφ vlastnosti UpdateRecordTypes
ud∞lßme zru╣enΘ zßznamy viditeln²mi a potom volßme RevertRecord.
Nßsleduje k≤d obnovujφcφ v╣echny zru╣enΘ zßznamy v tabulce:
void __fastcall UndeleteAll(TBDEDataSet *DataSet)
{
DataSet->UpdateRecordTypes.Clear();
DataSet->UpdateRecordTypes<<rtDeleted;
//zobrazenφ pouze zru╣en²ch zßznam∙
try
{
DataSet->First();
//p°echod na prvnφ zru╣en² zßznam
while (!DataSet->Eof)
DataSet->RevertRecord();
//obnovovßnφ a╛ do poslednφho zßznamu
}
catch(...)
{ //obnovenφ zobrazovßnφ pouze modifikovan²ch,
vlo╛en²ch a nemodifikovan²ch zßznam∙
DataSet->UpdateRecordTypes.Clear();
DataSet->UpdateRecordTypes
<< rtModified << rtInserted << rtUnmodified;
throw;
}
DataSet->UpdateRecordTypes.Clear();
DataSet->UpdateRecordTypes <<
rtModified << rtInserted << rtUnmodified;
}
Specifikovßnφ
viditeln²ch zßznam∙ v odklßdacφ pam∞ti
Vlastnost UpdateRecordTypes urΦuje, kterΘ typy zßznam∙
odlo╛en²ch v pam∞ti jsou viditelnΘ, kdy╛ jsou povoleny odlo╛enΘ aktualizace.
UpdateRecordTypes
pracuje na odlo╛en²ch zßznamech stejn²m zp∙sobem jako filtr pracuje na
tabulkßch. Vlastnost UpdateRecordTypes je mno╛ina a m∙╛e obsahovat
libovolnou kombinaci nßsledujφcφch hodnot:
Hodnota |
V²znam |
rtModified |
ModifikovanΘ zßznamy |
rtInserted |
Vlo╛enΘ zßznamy |
rtDeleted |
Zru╣enΘ zßznamy |
rtUnmodified |
NemodifikovanΘ zßznamy |
Implicitnφ hodnota pro UpdateRecordTypes zahrnuje
pouze rtModified,
rtInserted a rtUnmodified (zru╣enΘ
zßznamy - rtDeleted - nejsou zobrazovßny).
Vlastnost UpdateRecordTypes je hlavn∞ u╛iteΦnß
v obsluze udßlosti
OnUpdateError pro zp°φstupn∞nφ zru╣en²ch zßznam∙.
Tato vlastnost je takΘ u╛iteΦnß, kdy╛ chceme pro u╛ivatele zobrazit pouze
podmno╛inu odlo╛en²ch zßznam∙ (nap°. nov∞ vlo╛en²ch zßznam∙).
Nap°. m∙╛eme mφt Φty°i voliΦe (RadioButton1 a╛
RadioButton4)
s texty V╣echny, ModifikovanΘ, Vlo╛enΘ a Zru╣enΘ.
T∞mto voliΦ∙m p°i°adφme stejnou obsluhu udßlosti OnClick ve kterΘ
zm∞nou vlastnosti UpdateRecordTypes zajistφme zobrazenφ pouze po╛adovanΘho
typu zßznamu.
Vφce informacφ o vytvß°enφ obsluhy OnUpdateError,
viz Vytvß°enφ obsluhy
udßlostφ OnUpdateError.
Testovßnφ stavu aktualizace
Kdy╛ jsou pro na╣i aplikaci povoleny odlo╛enΘ aktualizace,
pak m∙╛eme testovat zda jsou nevy°e╣enΘ odlo╛enΘ aktualizace, testovßnφm
vlastnosti UpdateStatus pro zßznam. Testovßnφ stavu aktualizace
se Φasto pou╛φvß v obsluhßch udßlostφ
OnUpdateRecord a OnUpdateError.
Vφce informacφ o vytvß°enφ obsluhy OnUpdateError, viz Vytvß°enφ
obsluhy udßlostφ OnUpdateError. Vφce informacφ o vytvß°enφ a
pou╛φvßnφ udßlosti OnUpdateRecord viz Vytvß°enφ
obsluhy udßlosti OnUpdateRecord.
Jak prochßzφme mno╛inou nevy°φzen²ch zm∞n, UpdateStatus
se m∞nφ k urΦenφ stavu aktualizace souΦasnΘho zßznamu. UpdateStatus
vracφ pro souΦasn² zßznam jednu z nßsledujφcφch hodnot:
Hodnota |
V²znam |
usUnmodified |
Zßznam je nezm∞n∞n |
usModified |
Zßznam je zm∞n∞n |
usInserted |
Zßznam je nov² zßznam |
usDeleted |
Zßznam je zru╣en |
Kdy╛ datovß mno╛ina je otev°ena, pak v╣echny zßznamy majφ
aktualizaΦnφ stav usUnmodified. Jak zßznamy jsou vklßdßny, ru╣eny
nebo modifikovßny, pak jejich stav se m∞nφ. Zde je p°φklad vlastnosti UpdateStatus
pou╛itΘ v obsluze udßlosti OnScroll pro datovou mno╛inu. Obsluha
udßlosti zobrazuje aktualizaΦnφ stav v╣ech zßznam∙ na stavovΘm °ßdku.
void __fastcall TForm::CalcFields(TDataSet
*DataSet)
{
if (DataSet->UpdateStatus != usUnmodified)
Table1ModifiedRow->Value
= "*";
else
Table1ModifiedRow->Value
= NULL;
}
Poznßmka: Pokud UpdateStatus zßznamu
je usModified, pak m∙╛eme testovat vlastnost OldValue pro
ka╛dou polo╛ku v datovΘ mno╛in∞ k zji╣t∞nφ jejφ p°edchozφ hodnoty.
Pou╛φvßnφ objekt∙
aktualizace k aktualizovßnφ datov²ch mno╛in
TUpdateSQL je aktualizaΦnφ komponenta, kterß pou╛φvß
p°φkazy SQL k aktualizaci datovΘ mno╛iny. Musφme poskytnout jednu komponentu
TUpdateSQL
pro ka╛dou zp°φstupn∞nou tabulku v dotazu, kter² chceme aktualizovat.
Poznßmka: Pokud pou╛φvßme vφce ne╛ jednu aktualizaΦnφ
komponentu k provßd∞nφ aktualizaΦnφ operace, pak musφme vytvo°it obsluhu
OnUpdateRecord
k provedenφ v╣ech aktualizaΦnφch komponent.
AktualizaΦnφ komponenta obvykle zaobaluje t°i komponenty
TQuery.
Ka╛dß z t∞chto komponent dotazu provßdφ jednu aktualizaΦnφ ·lohu. Jedna
z komponent dotazu poskytuje p°φkaz SQL UPDATE pro modifikaci existujφcφch
zßznam∙; druhß komponenta dotazu poskytuje p°φkaz INSERT k p°idßvßnφ nov²ch
zßznam∙ k tabulce a t°etφ komponenta poskytuje p°φkaz DELETE k odstra≥ovßnφ
zßznam∙ z tabulky.
Kdy╛ umφstφme aktualizaΦnφ komponentu do datovΘho modulu,
pak nevidφme komponenty dotazu, kterΘ zaobaluje. AktualizaΦnφ komponenty
jsou vytvß°eny za b∞hu na zßklad∞ t°ech aktualizaΦnφch vlastnostφ, pro
kterΘ p°edßme p°φkazy SQL:
-
ModifySQL specifikuje p°φkaz UPDATE
-
InsertSQL specifikuje p°φkaz INSERT
-
DeleteSQL specifikuje p°φkaz DELETE
Za b∞hu, kdy╛ aktualizaΦnφ komponenta je pou╛ita k aplikovßnφ
aktualizacφ, pak:
-
Vybereme p°φkaz SQL k provedenφ na zßklad∞ automaticky generovanΘho
parametru
UpdateKind pro aktualizaΦnφ udßlost zßznamu. UpdateKind
specifikuje, zda souΦasn² zßznam je modifikovßn, vlo╛en nebo zru╣en.
-
Poskytneme hodnoty parametr∙ p°φkazu SQL.
-
P°ipravφme a spustφme p°φkaz SQL k provedenφ specifikovanΘ
aktualizace.
V tΘto sekci jsou je╣t∞ popsßny tyto body:
Specifikovßnφ
vlastnosti UpdateObject pro datovou mno╛inu
Jeden nebo vφce aktualizaΦnφch objekt∙ m∙╛e b²t p°i°azeno
k aktualizovanΘ datovΘ mno╛in∞. P°i°azenφ aktualizaΦnφch objekt∙ s aktualizovanou
datovou mno╛inou provedeme nastavenφm vlastnosti UpdateObject komponenty
datovΘ mno╛iny na aktualizaΦnφ objekt nebo nastavφme vlastnost DataSet
aktualizaΦnφho objektu na aktualizovanou datovou mno╛inu. Kterß metoda
je pou╛ita zßvisφ na tom, zda v aktualizovanΘ datovΘ mno╛in∞ je pou╛ita
pouze jedna zßkladnφ tabulka nebo vφce tabulek.
Musφme pou╛φt jednu z t∞chto dvou mo╛nostφ p°i°azovßnφ
aktualizovanΘ datovΘ mno╛iny s aktualizaΦnφm objekt∙m. Bez sprßvnΘho p°i°azenφ,
dynamickΘ pln∞nφ parametr∙ p°φkazu SQL v aktualizaΦnφch objektech nem∙╛e
nastat. Pou╛ijeme jednu p°i°azovacφ metodu nebo druhou, ale nikdy ob∞ najednou.
Zp∙sob p°i°azenφ aktualizaΦnφho objektu k datovΘ mno╛in∞
takΘ urΦuje, jak aktualizaΦnφ objekt je provßd∞n. AktualizaΦnφ objekt m∙╛e
b²t provßd∞n automaticky, bez explicitnφ intervence aplikace nebo m∙╛eme
explicitn∞ po╛ßdat o jeho provedenφ. Pokud p°i°azenφ je provedeno pomocφ
vlastnosti
UpdateObject komponenty datovΘ mno╛iny, pak aktualizaΦnφ
objekt bude automaticky provßd∞n. Kdy╛ p°i°azenφ je provedeno vlastnostφ
DataSet
aktualizaΦnφho objektu, pak aktualizaΦnφ objekt musφme provΘst programov∞.
Nßsledujφcφ body popisujφ proces p°i°azovßnφ aktualizaΦnφch
objekt∙ ke komponentßm datov²ch mno╛in podrobn∞ji a informujφ o tom, kdy
ka╛dß metoda mß b²t pou╛ita a jejφm efektu na provedenφ aktualizace.
Pou╛φvßnφ jednoho
aktualizaΦnφho objektu
Kdy╛ v aktualizovanΘ datovΘ mno╛in∞ je zapot°ebφ aktualizovat
pouze jednu zßkladnφ tabulku, pak p°i°adφme aktualizaΦnφ objekt k datovΘ
mno╛in∞ nastavenφm vlastnosti UpdateObject komponenty datovΘ mno╛iny
na jmΘno aktualizaΦnφho objektu.
AktualizaΦnφ p°φkazy SQL v aktualizaΦnφm objektu jsou
provedeny automaticky, kdy╛ je volßna metoda ApplyUpdates aktualizovanΘ
datovΘ mno╛iny. AktualizaΦnφ objekt je vyvolßn pro ka╛d² zßznam vy╛adujφcφ
aktualizaci. Nevolejte metodu ExecSQL aktualizaΦnφho objektu v obsluze
udßlosti
OnUpdateRecord, nebo╗ v²sledkem by byl druh² pokus o aplikovßnφ
ka╛dΘho aktualizovanΘho zßznamu.
Pokud dodßme obsluhu pro udßlost OnUpdateRecord
datovΘ mno╛iny, pak minimßlnφ akce, kterou musφme provΘst v obsluze je
nastavenφ parametru
UpdateAction obsluhy na uaApplied. M∙╛eme
p°φpadn∞ takΘ provΘst ov∞°enφ p°φpustnosti dat, modifikaci dat nebo operace
podobajφcφ se nastavovßnφm hodnot parametr∙.
Pou╛φvßnφ vφce aktualizaΦnφch
objekt∙
Kdy╛ v aktualizovanΘ datovΘ mno╛in∞ pot°ebujeme aktualizovat
vφce ne╛ jednu zßkladnφ tabulku, pak musφme pou╛φt vφce aktualizaΦnφch
objekt∙ a to v╛dy jeden pro ka╛dou aktualizovanou zßkladnφ tabulku. Proto╛e
UpdateObject
komponenty datovΘ mno╛iny povoluje p°i°adit pouze jeden aktualizaΦnφ objekt
k datovΘ mno╛in∞, musφme ka╛d² aktualizaΦnφ objekt p°i°adit k datovΘ mno╛in∞
nastavenφm vlastnosti DataSet objektu na jmΘno datovΘ mno╛iny. Vlastnost
DataSet
aktualizaΦnφch
objekt∙ nenφ dostupnß p°i nßvrhu v Inspektoru objekt∙. Tuto vlastnost m∙╛eme
nastavit pouze za b∞hu.
AktualizaΦnφ p°φkazy SQL v aktualizaΦnφm objektu nejsou
automaticky provßd∞ny, kdy╛ je volßna metoda ApplyUpdates aktualizovanΘ
datovΘ mno╛iny. K aktualizaci zßznam∙ musφme dodat obsluhu udßlosti OnUpdateRecord
pro komponentu datovΘ mno╛iny a volat v nφ metodu ExecSQL nebo Apply
aktualizaΦnφho objektu. Tφm vyvolßme aktualizaΦnφ objekt pro ka╛d² zßznam
vy╛adujφcφ aktualizaci.
V obsluze pro udßlost OnUpdateRecord datovΘ mno╛iny
musφme provΘst minimßln∞ tyto akce:
-
Volat metodu SetParams aktualizaΦnφho objektu (pokud
pozd∞ji volßme
ExecSQL).
-
ProvΘst aktualizaΦnφ objekt pro souΦasn² zßznam pomocφ ExecSQL
nebo
Apply.
-
Nastavit parametr UpdateAction obsluhy udßlosti na
uaApplied.
M∙╛eme p°φpadn∞ takΘ provΘst ov∞°enφ p°φpustnosti dat, modifikaci
dat nebo jinΘ operace zßvisejφcφ na ka╛dΘm aktualizovanΘm zßznamu.
Poznßmka: Je takΘ mo╛nΘ mφt jeden aktualizaΦnφ
objekt p°i°azen k datovΘ mno╛in∞ pomocφ vlastnosti UpdateObject
komponenty datovΘ mno╛iny a druh² a dal╣φ aktualizaΦnφ objekty p°i°azenΘ
pomocφ jejich vlastnostφ
DataSet. Prvnφ aktualizaΦnφ objekt je provßd∞n
automaticky p°i volßnφ metody ApplyUpdates komponenty datovΘ mno╛iny.
Zb²vajφcφ jsou provßd∞ny manußln∞.
Vytvß°enφ
p°φkaz∙ SQL pro aktualizaΦnφ komponenty
K aktualizovßnφ zßznam∙ v p°i°azenΘ datovΘ mno╛in∞, aktualizaΦnφ
objekt pou╛φvß t°i p°φkazy SQL. T°i p°φkazy SQL ru╣φ, vklßdajφ a modifikujφ
odlo╛enΘ zßznamy p°i aktualizaci. P°φkazy jsou obsa╛eny ve vlastnostech
(typu seznamu °et∞zc∙) DeleteSQL, InsertSQL a ModifySQL
aktualizaΦnφho objektu. Jeliko╛ ka╛d² aktualizaΦnφ objekt je pou╛it k aktualizaci
jedinΘ tabulky, p°φkazy aktualizaΦnφho objektu se odkazujφ na stejnou zßkladnφ
tabulku.
Jak jsou aplikovßny aktualizace pro jednotlivΘ zßznamy,
jeden ze t°φ p°φkaz∙ SQL je proveden k aktualizaci zßkladnφ tabulky. Kter²
z p°φkaz∙ SQL je proveden zßvisφ na automaticky generovanΘm parametru UpdateKind
pro ka╛d² aktualizovan² zßznam.
SQL p°φkazy pro aktualizaΦnφ objekty m∙╛eme vytvß°et
p°i nßvrhu nebo za b∞hu. Nßsledujφcφ body popisujφ vytvß°ecφ proces p°φkaz∙
SQL podrobn∞ji.
Vytvß°enφ SQL p°φkaz∙ p°i
nßvrhu
K vytvo°enφ p°φkaz∙ SQL pro aktualizaΦnφ komponentu:
-
Vybereme komponentu TUpdateSQL.
-
Vybereme jmΘno aktualizaΦnφ komponenty z rozbalovacφho seznamu
vlastnosti
UpdateObject komponenty datovΘ mno╛iny v Inspektoru objekt∙.
Tφm zajistφme, ╛e v nßsledujφcφm kroku bude vyvolßn Editor UpdateSQL k
urΦenφ hodnot pro generaΦnφ volby SQL.
-
V mφstnφ nabφdce aktualizaΦnφ komponenty zvolφme UpdateSQL
Editor k vyvolßnφ Editoru UpdateSQL. Editor vytvß°φ p°φkazy SQL pro
vlastnosti
ModifySQL,
InsertSQL a DeleteSQL aktualizaΦnφ
komponenty na zßklad∞ p°ipojenΘ mno╛iny dat a jφ p°edßvan²ch hodnotßch.
Editor UpdateSQL mß dv∞ strßnky. P°i vyvolßnφ editoru
je viditelnß strßnka Options. Kombinovan² ovladaΦ Table Name
pou╛ijeme k v²b∞ru aktualizovanΘ tabulky. Po specifikaci jmΘna tabulky,
seznamy Key Fields a Update Fields jsou zapln∞ny dostupn²mi
sloupci.
Seznam Update Fields obsahuje sloupce, kterΘ mohou
b²t aktualizovßny. Kdy╛ specifikujeme tabulku, pak v╣echny sloupce v seznamu
Update
Fields jsou vybrßny. M∙╛eme podle pot°eby vybφrat i vφce polo╛ek.
Seznam Key Fields je pou╛φvßn pro specifikaci
sloupc∙ pou╛φvan²ch v pr∙b∞hu aktualizace jako klφΦ∙. Pro Paradox, dBASE
a FoxPro, specifikovanΘ sloupce musφ odpovφdat existujφcφmu indexu, ale
toto nenφ po╛adovßno pro SQL databßze. Mφsto nastavovßnφ Key Fields
m∙╛eme stisknout tlaΦφtko
Primary Keys k volb∞ klφΦov²ch polo╛ek
pro aktualizaci na zßklad∞ primßrnφho indexu tabulky. Stiskem Dataset
Defaults se vrßtφme k p∙vodnφmu stavu v²b∞ru: v╣echny polo╛ky vybranΘ
jako klφΦe a v╣echny vybranΘ pro aktualizaci.
OznaΦφme znaΦku Quote Field Names pokud nß╣ server
po╛aduje uzavφrat jmΘna polo╛ek do uvozovek.
Po specifikaci tabulky, vybereme sloupce klφΦe a vybereme
aktualizaΦnφ sloupce a stiskem Generate SQL zahßjφme generovßnφ
p°φkaz∙ SQL pro vlastnosti ModifySQL, InsertSQL a DeleteSQL
pro aktualizaΦnφ komponentu. V mnoha p°φpadech nßm postaΦφ automaticky
generovanΘ p°φkazy SQL.
K zobrazenφ a modifikaci p°φkaz∙ SQL, p°ejdeme na strßnku
SQL. Pokud mßme vygenerovanΘ p°φkazy SQL, pak p°i p°echodu na tuto strßnku,
p°φkaz pro vlastnost ModifySQL je zobrazen v ovladaΦi Memo nazvanΘm
SQL
Text. P°φkaz zde m∙╛eme podle pot°eby editovat.
D∙le╛itΘ: VygenerovanΘ p°φkazy jsou poΦßtkem
pro vytvß°enφ aktualizaΦnφch p°φkaz∙. Tyto p°φkazy m∙╛eme modifikovat.
Nap°. kdy╛ pracujeme s daty kterΘ obsahujφ hodnoty NULL, pak m∙╛eme po╛adovat
modifikovat klauzuli WHERE na
WHERE field IS NULL
namφsto pou╛itφ generovan²ch
prom∞nn²ch polo╛ek. Sami ka╛d² p°φkaz p°φmo otestujeme.
Pomocφ voliΦ∙ Statement Type
se p°epneme na dal╣φ generovanΘ p°φkazy a podle pot°eby je editujeme. K
akceptovßnφ p°φkaz∙ a k jejich p°i°azenφ vlastnostem SQL aktualizaΦnφ komponenty
stiskneme
OK.
Seznßmenφ
se substitucφ parametr∙ v aktualizaΦnφm p°φkazu SQL
AktualizaΦnφ p°φkazy SQL pou╛φvajφ specißlnφ formu substituce
parametr∙, kterß umo╛≥uje nahradit starΘ nebo novΘ hodnoty polo╛ek v aktualizovan²ch
zßznamech. Kdy╛ Editor UpdateSQL generuje svΘ p°φkazy, je urΦeno, kterΘ
hodnoty polo╛ek pou╛ije. Kdy╛ zapisujeme aktualizaΦnφ SQL, pak specifikujeme
hodnoty polo╛ek k pou╛itφ.
Kdy╛ jmΘno parametru se shoduje se jmΘnem sloupce v tabulce,
pak novß hodnota v polo╛ce v odlo╛en²ch aktualizacφch pro zßznam je automaticky
pou╛ita jako hodnota pro parametr. Kdy╛ jmΘno parametru odpovφdß jmΘnu
sloupce p°edchßzenΘ °et∞zcem OLD_, pak pro polo╛ku je pou╛ita starß
hodnota. Nap°. v nßsledujφcφm aktualizaΦnφm p°φkazu SQL, parametr :LastName
je automaticky pln∞n novou hodnotou polo╛ky z odlo╛en²ch aktualizacφch
pro vklßdan² zßznam.
INSERT INTO Names
(LastName, FirstName, Address, City, State,
Zip)
VALUES (:LastName, :FirstName, :Address,
:City, :State, :Zip)
NovΘ hodnoty polo╛ek jsou obvykle pou╛φvßny v p°φkazech
InsertSQL
a ModifySQL. V aktualizaci pro modifikovan² zßznam, novΘ hodnoty
polo╛ky z aktualizaΦnφ odklßdacφ pam∞ti jsou pou╛ity p°φkazem UPDATE k
nahrazenφ starΘ hodnoty polo╛ky v aktualizovanΘ zßkladnφ tabulce.
V p°φpad∞ ru╣enφ zßznam∙, nejsou novΘ hodnoty a tak vlastnost
DeleteSQL
pou╛φvß syntaxi :OLD_FieldName. StarΘ hodnoty polo╛ek jsou takΘ
normßln∞ pou╛ity v klauzuli p°φkazu SQL pro modifikovßnφ nebo ru╣enφ aktualizacφ
k urΦenφ kter² zßznam aktualizovat nebo zru╣it.
V klauzuli WHERE aktualizaΦnφch p°φkaz∙ SQL UPDATE nebo
DELETE p°edßvßme minimßlnφ poΦet parametr∙ k jednoznaΦnΘ identifikaci zßznamu
v zßkladnφ tabulce, kterß je aktualizovßna odlo╛en²mi daty. Nap°. v seznamu
zßkaznφk∙, pou╛itφ pouze p°φjmenφ zßkaznφka nepostaΦuje k jednoznaΦnΘ identifikaci
opravovanΘho zßznamu v zßkladnφ tabulce, nebo╗ m∙╛e existovat n∞kolik zßkaznφk∙
stejnΘho jmΘna. Ale pou╛itφ parametr∙ pro p°φjmenφ a telefonnφ Φφslo m∙╛e
b²t ji╛ postaΦujφcφ kombinace. Je ale mnohem vhodn∞j╣φ pou╛φt polo╛ku typu
Φφslo zßkaznφka.
Sklßdßnφ aktualizaΦnφch
p°φkaz∙ SQL
Komponenta TUpdateSQL mß t°i vlastnosti pro aktualizaΦnφ
p°φkazy SQL: DeleteSQL, InsertSQL a MofifySQL. Jak
nßm ji╛ napovφdajφ jejich jmΘna, tyto SQL p°φkazy ru╣φ, vklßdajφ a modifikujφ
zßznamy v zßkladnφ tabulce.
Vlastnost DeleteSQL obsahuje pouze SQL p°φkaz
DELETE. Aktualizovanß zßkladnφ tabulka musφ b²t uvedena v klauzuli FROM.
A tak p°φkaz SQL pouze zru╣φ v zßkladnφ tabulce zßznam, jeho╛ odpovφdajφcφ
zßznam byl zru╣en v aktualizaΦnφ odklßdacφ pam∞ti, pomocφ klauzule WHERE.
V klauzuli WHERE pou╛ijeme parametr pro jednu nebo vφce polo╛ek k jednoznaΦnΘ
identifikaci zßznamu v zßkladnφ tabulce, kter² odpovφdß zßznamu z odlo╛en²ch
aktualizacφ. Pokud parametr mß stejnΘ jmΘno jako polo╛ka s p°edponou OLD_,
pak parametr automaticky zφskß hodnotu z odpovφdajφcφ polo╛ky ze zßznamu
odlo╛en²ch aktualizacφ. Kdy╛ parametr je pojmenovßn jinak, pak hodnotu
parametru musφme dodat.
DELETE FROM Inventory I
WHERE (I.ItemNo = :OLD_ItemNo)
N∞kterΘ typy tabulek nemusφ b²t schopny nalΘzt zßznam
v zßkladnφ tabulce, kdy╛ polo╛ky pou╛φvajφ k identifikaci zßznamu obsahujφcφ
hodnoty NULL. V t∞chto p°φpadech aktualizace ru╣enφ pro tyto zßznamy chybuje.
K zabrßn∞nφ tomu, p°idßme podmφnku pro tyto polo╛ky s predikßtem IS NULL.
Nap°. kdy╛
FirstName m∙╛e obsahovat NULL:
DELETE FROM Names
WHERE (LastName = :OLD_LastName) AND
((FirstName = :OLD_FirstName) OR (FirstName
IS NULL))
P°φkaz InsertSQL m∙╛e obsahovat pouze SQL p°φkaz
INSERT. Zßkladnφ tabulka pro aktualizaci musφ b²t uvedena v klauzuli INTO.
V klauzuli VALUES p°edßvßme Φßrkami odd∞len² seznam parametr∙. Pokud parametr
je pojmenovßn stejn∞ jako polo╛ka, pak parametr automaticky zφskß danou
hodnotu ze zßznamu odlo╛enΘ aktualizace. Je-li pojmenovßn jinak, pak hodnoty
parametru musφme dodat. Seznam parametr∙ p°edßvß hodnoty pro polo╛ky v
nov∞ vytvß°enΘm zßznamu. Musφ to b²t v╣echny hodnoty parametr∙ jako jsou
polo╛ky uvedeny v p°φkazu.
INSERT INTO Inventory
(ItemNo, Amount)
VALUES (:ItemNo, 0)
P°φkaz ModifySQL m∙╛e obsahovat pouze SQL p°φkaz
UPDATE. Zßkladnφ tabulka k aktualizaci musφ b²t uvedena v klauzuli FROM.
Obsahuje jedno nebo vφce p°i°azenφ hodnot v klauzuli SET. Pokud p°i°azovanΘ
hodnoty v klauzuli SET jsou parametry pojmenovanΘ stejn∞ jako polo╛ky,
pak parametr∙m jsou automaticky dßny hodnoty z polo╛ek stejnΘho jmΘna v
odlo╛enΘm aktualizovanΘm zßznamu. P°i pou╛itφ jin²ch jmen parametr∙, musφme
hodnoty parametru p°edat manußln∞. Jako u p°φkazu DeleteSQL, p°edßme
klauzuli WHERE k jednoznaΦnΘ identifikaci zßznam∙ v zßkladnφ tabulce (jmΘna
polo╛ek p°edchßzenß OLD_). V nßsledujφcφm p°φkazu, parametr :ItemNo
zφskß automaticky hodnotu a :Price ne.
UPDATE Inventory I
SET I.ItemNo = :ItemNo, Amount = :Price
WHERE (I.ItemNo = :OLD_ItemNo)
P°edpoklßdejme p°edchozφ p°φkaz SQL v p°φpad∞ kdy koncov²
u╛ivatel modifikuje existujφcφ zßznam. P∙vodnφ hodnota polo╛ky ItemNo
je 999. V p°ipojenΘ m°φ╛ce u╛ivatel zm∞nφ polo╛ku ItemNo na 123
a Amount na 20. Kdy╛ je vyvolßna metoda ApplyUpdates, pak
tento SQL p°φkaz ovliv≥uje v╣echny zßznamy v zßkladnφ tabulce u kter²ch
polo╛ka ItemNo je 999, pomocφ starΘ hodnoty polo╛ky v parametru
:OLD_ItemNo.
U t∞chto zßznam∙ je zm∞n∞na hodnota polo╛ky ItemNo na 123 (pomocφ
parametru
:ItemNo, hodnotu zφskßme z m°φ╛ky) a Amount na
20.
Zp°φstupn∞nφ vlastnosti
Query
aktualizaΦnφ komponenty
Pomocφ vlastnosti Query aktualizaΦnφ komponenty p°istupujeme
k jednΘ aktualizaΦnφ vlastnosti SQL DeleteSQL, InsertSQL nebo
ModifySQL a to pro nastavovßnφ nebo zm∞nu p°φkazu SQL. Pou╛ijeme hodnotu
konstanty UpdateKind jako index v poli komponent dotaz∙. Vlastnost
Query
je dostupnß pouze za b∞hu.
Nßsledujφcφ p°φkaz pou╛φvß konstantu ukDelete UpdateKind
s vlastnostφ
Query pro zp°φstupn∞nφ vlastnosti DeleteSQL.
Normßln∞ vlastnosti indexovanΘ vlastnostφ Query jsou nastavovßny
p°i nßvrhu pomocφ Editoru UpdateSQL. M∙╛eme k nφm ale p°istupovat za b∞hu,
pokud nepou╛φvajφ sestavovßnφ parametr∙. Nßsledujφcφ p°φklad generuje unikßtnφ
vlastnosti Query pro ka╛d² aktualizovan² °ßdek:
void __fastcallTForm1::EmpAuditUpdateRecord(TDataSet
*DataSet,
TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
{
TUpdateSQL *pUpdate = (TUpdateSQL
*)((TBDEDataSet *)DataSet)->UpdateObject;
switch (UpdateKind)
{
case ukModify:
pUpdate->SQL[UpdateKind]->Text
=
Format("UPDATE EMPTAB SET SALARY = %d WHERE EMPNO = %d",
ARRAYOFCONST((EmpAuditSalary->NewValue->AsInteger,
EmpAuditEmpNo->OldValue->AsInteger)));
break;
case ukInsert:
...
break;
case ukDelete:
...
break;
}
pUpdate->ExecSQL(UpdateKind);
UpdateAction = uaApplied;
}
Poznßmka: Query vracφ hodnotu typu TDataSetUpdateObject.
K chßpßnφ tΘto vrßcenΘ hodnoty jako komponenty TUpdateSQL pou╛ijeme
p°etypovßnφ. Nap°.
((TUpdateSQL *)Query1->UpdateObject)->Query[UpdateKind];
Pou╛φvßnφ vlastnostφ
DeleteSQL, InserSQL a ModifySQL
Vlastnosti DeleteSQL, InsertSQL a ModifySQL
pou╛φvßme k nastavovßnφ aktualizaΦnφch p°φkaz∙ SQL. Tyto vlastnosti jsou
v╣echny seznamy °et∞zc∙. K zadßvßnφ p°φkaz∙ pou╛φvßme metody seznamu °et∞zc∙.
Tyto vlastnosti jsou p°φstupnΘ p°i nßvrhu i za b∞hu.
Provßd∞nφ aktualizaΦnφch
p°φkaz∙
Je n∞kolik metod urΦen²ch k aktualizovßnφ individußlnφch
zßznam∙. Tato volßnφ metod se obvykle pou╛φvajφ v obsluze udßlosti OnUpdateRecord
aktualizaΦnφho objektu pro spou╣t∞nφ aktualizaΦnφho SQL k aplikovßnφ souΦasnΘho
zßznamu odlo╛en²ch aktualizacφ. V r∙zn²ch situacφch pou╛φvßme r∙znΘ metody.
V nßsledujφcφch bodech jsou popsßny tyto metody podrobn∞ji:
Volßnφ metody Apply
Metoda Apply aplikaΦnφ komponenty manußln∞ aplikuje
aktualizace souΦasnΘho zßznamu. Jsou dva kroky vyvolßvajφcφ tento proces:
-
Hodnoty zßznamu jsou spojeny s parametry v p°φslu╣nΘm aktualizaΦnφm
SQL p°φkazu.
-
P°φkaz SQL je proveden.
K aplikovßnφ aktualizacφ pro souΦasn² zßznam v aktualizaΦnφ
odklßdacφ pam∞ti volßme metodu Apply. Apply m∙╛eme pou╛φt
kdy╛ aktualizaΦnφ objekt nenφ p°i°azen k datovΘ mno╛in∞ pomocφ vlastnosti
UpdateObject
komponenty datovΘ mno╛iny, kdy aktualizaΦnφ objekt nenφ automaticky provßd∞n.
Apply
automaticky volß metodu SetParams ke spojenφ star²ch a nov²ch hodnot
polo╛ek ke specißln∞ pojmenovan²m parametr∙m v aktualizaΦnφm p°φkazu SQL.
SetParams
p°i pou╛φvßnφ Apply nevolßme sami. Metoda Apply je Φasto
volßna v obsluze udßlosti OnUpdateRecord datovΘ mno╛iny.
Pokud pou╛ijeme vlastnost UpdateObject komponenty
datovΘ mno╛iny k p°i°azenφ datovΘ mno╛iny a aktualizaΦnφho objektu, pak
tato metoda je volßna automaticky. V obsluze udßlosti OnUpdateRecord
komponenty datovΘ mno╛iny nevolßme Apply, proto╛e v²sledkem by byl
druh² pokus o aplikovßnφ aktualizacφ souΦasnΘho zßznamu.
V obsluze udßlosti OnUpdateRecord, parametr UpdateKind
je pou╛it k urΦenφ, kter² aktualizaΦnφ p°φkaz pou╛φt. P°i vyvolßvßnφ p°ipojenou
datovou mno╛inou, UpdateKind je nastavovßn automaticky. Pokud vyvolßme
metodu v obsluze OnUpdateRecord, pak p°edßme konstantu UpdateKind
jako parametr Apply.
Pokud v pr∙b∞hu provßd∞nφ aktualizace je generovßna v²jimka,
pak provßd∞nφ pokraΦuje udßlostφ OnUpdateError, pokud jejφ obsluha
je definovßna.
Poznßmka: Operace provßd∞nΘ Apply jsou
analogickΘ k metodßm SetParams a ExecSQL popsan²m v nßsledujφcφch
bodech.
Volßnφ metody SetParams
Metoda SetParams pro aktualizaΦnφ komponentu pou╛φvß
specißlnφ pravidla substituce prarametr∙ k vlo╛enφ starΘ a novΘ hodnoty
polo╛ky do aktualizaΦnφho p°φkazu SQL. Normßln∞, SetParams je volßno
automaticky metodou Apply aktualizaΦnφ komponenty. Pokud Apply
volßme p°φmo v udßlosti OnUpdateRecord, pak sami nevolßme SetParams.
Pokud provßdφme aktualizaΦnφ objekt pomocφ jeho metody ExecSQL,
pak volßnφ SetParams p°ipojuje hodnoty k parametr∙m aktualizaΦnφho
p°φkazu.
SetParams nastavuje parametry SQL p°φkazu urΦenΘho
parametrem
UpdateKind. Pouze ty parametry, kterΘ pou╛φvajφ specißlnφ
pojmenovacφ konvence automaticky majφ p°i°azenou hodnotu. Pokud parametr
mß stejnΘ jmΘno jako polo╛ka nebo jako jmΘno polo╛ky p°edchßzenΘ OLD_,
pak parametr zφskß automaticky hodnotu. Pro jinak pojmenovanΘ parametry,
musφme hodnotu p°i°adit manußln∞.
Provßd∞nφ aktualizaΦnφch
p°φkaz∙
Metoda ExecSQL aktualizaΦnφ komponenty manußln∞ aplikuje
aktualizace pro souΦasn² zßnam. P°i vyvolßnφ tohoto procesu jsou dva kroky:
-
Hodnoty pro zßznam jsou spojeny s parametry v odpovφdajφcφm
aktualizaΦnφm p°φkazu SQL.
-
Je proveden p°φkaz SQL.
Metodu ExecSQL volßme k aplikovßnφ aktualizacφ pro
souΦasn² zßznam v aktualizaΦnφ odklßdacφ pam∞ti. ExecSQL pou╛ijeme
pouze, kdy╛ aktualizaΦnφ objekt nenφ p°i°azen k datovΘ mno╛in∞ pomocφ vlastnosti
UpdateObject
komponenty datovΘ mno╛iny, kdy aktualizaΦnφ objekt nenφ provßd∞n automaticky.
ExecSQL
nevolß automaticky metodu SetParams ke spojenφ hodnot k parametr∙m
aktualizaΦnφho p°φkazu SQL; SetParams volßme sami p°ed vyvolßnφm
ExecSQL.
Metoda ExecSQL je Φasto volßna v obsluze udßlosti
OnUpdateRecord.
Pokud pou╛ijeme vlastnost UpdateObject komponenty
datovΘ mno╛iny k p°i°azenφ datovΘ mno╛iny a aktualizaΦnho objektu, pak
tato metoda je volßna automaticky. Nevolßme ExecSQL v obsluze udßlosti
OnUpdateRecord
komponenty datovΘ mno╛iny, nebo╗ v²sledkem by byl druh² pokus o aplikovßnφ
aktualizacφ souΦasnΘho zßznamu.
V obsluze udßlosti OnUpdateRecord, parametr UpdateKind
je pou╛it k urΦenφ kter² aktualizaΦnφ p°φkaz SQL pou╛φt. P°i vyvolßnφ p°i°azenou
datovou mno╛inou, UpdateKind je nastavovßn automaticky. Jestli╛e
vyvolßme metodu v udßlosti OnUpdateRecord, pak p°edßme konstantu
UpdateKind
jako parametr ExecSQL.
Pokud v pr∙b∞hu provßd∞nφ aktualizace je generovßna v²jimka,
pak provßd∞nφ pokraΦuje udßlostφ OnUpdateError, pokud jejφ obsluha
je definovßna.
Pou╛φvßnφ
komponent datov²ch mno╛in k aktualizaci datovΘ mno╛iny
Aplikovßnφ odlo╛en²ch aktualizacφ obvykle vy╛aduje pou╛itφ
jednoho nebo vφce aktualizaΦnφch objekt∙. AktualizaΦnφ p°φkazy SQL pro
tyto objekty aplikujφ datovΘ zm∞ny na zßkladnφ tabulku. Pou╛itφ aktualizaΦnφ
komponenty je nejsnadn∞j╣φ zp∙sob aktualizovßnφ datovΘ mno╛iny, ale nenφ
po╛adovßn. M∙╛eme p°φpadn∞ pou╛φt komponenty datov²ch mno╛in jako TTable
a
TQuery k aplikovßnφ odlo╛en²ch aktualizacφ.
V obsluze udßlosti OnUpdateRecord komponenty datovΘ
mno╛iny, pou╛ijeme vlastnosti a metody jinΘ komponenty datovΘ mno╛iny k
aplikovßnφ odlo╛en²ch aktualizacφ pro ka╛d² zßznam.
Aktualizovßnφ
v²sledkovΘ mno╛iny urΦenΘ pouze pro Φtenφ
I kdy╛ BDE se pokou╣φ poskytnout aktualizovateln² nebo "╛iv²"
v²sledek dotazu, kdy╛ vlastnost RequestLive komponenty dotazu je
true,
jsou n∞kterΘ situace, kdy to provΘst nelze. V t∞chto situacφch, m∙╛eme
manußln∞ aktualizovat datovou mno╛inu takto:
-
P°idßme komponentu TUpdateSQL k datovΘmu modulu v
na╣i aplikaci.
-
Nastavφme vlastnost UpdateObject komponenty datovΘ
mno╛iny na jmΘno komponenty TUpdateSQL v datovΘm modulu.
-
Zadßme aktualizaΦnφ p°φkazy SQL pro v²sledkovou mno╛inu do
vlastnostφ ModifySQL,
InsertSQL nebo DeleteSQL aktualizaΦnφ
komponenty nebo pou╛ijeme Editor UpdateSQL.
-
Uzav°eme datovou mno╛inu.
-
Nastavφme vlastnost CachedUpdates komponenty datovΘ
mno╛iny na true.
-
Datovou mno╛inu op∞t otev°eme.
Poznßmka: V mnoha situacφch m∙╛eme takΘ chtφt pro
datovou mno╛inu zapsat obsluhu udßlosti OnUpdateRecord.
╪φzenφ procesu aktualizace
Kdy╛ je volßna metoda ApplyUpdates komponenty datovΘ
mno╛iny, pak je uΦin∞n pokus o aktualizaci pro v╣echny zßznamy v aktualizaΦnφ
odkladacφ pam∞ti na odpovφdajφcφ zßznamy v zßkladnφ tabulce. Jak aktualizace
pro ka╛dΘ ru╣enφ, vlo╛enφ nebo modifikaci jsou aplikovßny, je generovßna
udßlost
OnUpdateRecord komponenty datovΘ mno╛iny.
Poskytnutφm obsluhy pro udßlost OnUpdateRecord
umo╛nφme provßd∞t akce prßve p°ed provedenφm aktualizace souΦasnΘho zßznamu.
Tyto akce mohou obsahovat kontrolu p°φpustnosti dat, aktualizaci ostatnφch
tabulek nebo spou╣t∞nφ vφce aktualizaΦnφch objekt∙. Obsluha udßlosti OnUpdateRecord
zvy╣uje mo╛nost °φzenφ procesu aktualizace.
V tΘto sekci nalezneme je╣t∞ tyto body:
UrΦenφ,
zda pot°ebujeme °φdit aktualizaΦnφ proces
N∞kdy, kdy╛ pou╛φvßme odlo╛enΘ aktualizace, v╣e co pot°ebujeme
d∞lat je volat ApplyUpdates k aplikovßnφ odlo╛en²ch zm∞n do zßkladnφch
tabulek v databßzi (nap°. kdy╛ mßme v²luΦn² p°φstup k lokßlnφm tabulkßm
Paradoxu nebo dBASE prost°ednictvφm komponenty TTable). V n∞kter²ch
jin²ch p°φpadech m∙╛eme po╛adovat nebo musφme po╛adovat dal╣φ proces k
zaji╣t∞nφ, ╛e aktualizace budou sprßvn∞ aplikovßny. K poskytnutφ tohoto
dal╣φho procesu pou╛ijeme obsluhu udßlosti OnUpdateRecord aktualizovanΘ
komponenty datovΘ mno╛iny.
Nap°. m∙╛eme pou╛φt udßlost OnUpdateRecord k ov∞°enφ
p°φpustnosti dat p°ed jejich aplikovßnφm na tabulku nebo m∙╛eme chtφt pou╛φt
udßlost
OnUpdateRecord k poskytnutφ dal╣φho zpracovßnφ pro zßznamy
v tabulkßch Master-detail p°ed jejich zßpisem do zßkladnφch tabulek.
V mnoha p°φpadech musφme poskytnout dal╣φ zpracovßnφ.
Nap°. pokud p°istupujeme k vφce tabulkßm pomocφ spojenΘho dotazu, pak musφme
poskytnout jeden objekt
TUpdateSQL pro ka╛dou tabulku v dotazu a
musφme pou╛φt OnUpdateRecord k zaji╣t∞nφ, ╛e ka╛d² aktualizaΦnφ
objekt bude proveden k zßpisu zm∞n do tabulek.
Vytvß°enφ obsluhy
udßlosti OnUpdateRecord
Udßlost OnUpdateRecord zpracovßvß p°φpady kdy jedna
aktualizaΦnφ komponenta nem∙╛e b²t pou╛ita k provedenφ po╛adovan²ch aktualizacφ
nebo kdy╛ na╣e aplikace pot°ebuje vφce °φzenφ nad substitucφ specißlnφch
parametr∙. Udßlost OnUpdateRecord je generovßna jednou p°i aplikovßnφ
zm∞n pro ka╛d² modifikovan² zßznam v aktualizaΦnφ odklßdacφ pam∞ti.
K vytvo°enφ obsluhy udßlosti OnUpdateRecord pro
datovou mno╛inu:
-
Vybereme komponentu datovΘ mno╛iny.
-
P°ejdeme na strßnku udßlostφ Inspektora objekt∙.
-
Dvojit∞ klikneme na hodnotu vlastnosti OnUpdateRecord
k vyvolßnφ editoru k≤du.
Nßsleduje kostra k≤du obsluhy udßlosti OnUpdateRecord:
void __fastcallTForm1::DataSetUpdateRecord(TDataSet
*DataSet,
TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
{
// Zde provßdφme aktulizace...
}
Parametr DateSet specifikuje odlo╛enou datovou
mno╛inu s aktualizacemi.
Parametr UpdateKind indikuje typ provßd∞nΘ aktualizace.
Hodnoty pro UpdateKind jsou ukModify, ukInsert a ukDelete.
Kdy╛ pou╛φvßme aktualizaΦnφ komponentu, pak musφme p°edat tento parametr
p°i jejφm provßd∞nφ a parametr spojit s metodou. Nap°. pou╛itφm ukModify
a metodou Apply provßdφme p°φkaz ModifySQL aktualizaΦnφho
objektu. M∙╛eme takΘ pot°ebovat zkoumat tento parametr pokud obsluha provßdφ
n∞jakΘ specißlnφ zpracovßnφ na zßklad∞ typu provßd∞nΘ aktualizace.
Parametr UpdateAction indikuje zda aktualizace
je aplikovßna nebo ne. Hodnoty pro UpdateAction jsou uaFail
(implicitn∞),
uaAbort, uaSkip, uaRetry a uaApplied.
Pokud b∞hem aktualizace nenastane ╛ßdn² problΘm, pak na╣e obsluha by m∞la
p°ed ukonΦenφm nastavit tento parametr na uaApplied. Pokud jist²
zßznam nechceme aplikovat, pak nastavφme hodnotu na uaSkip k ochrßn∞nφ
neaplikovan²ch zm∞n v odklßdacφ pam∞ti.
Pokud nezm∞nφme hodnotu pro UpdateAction, pak
celß aktualizaΦnφ operace pro datovou mno╛inu je zru╣ena.
Mimo t∞chto parametr∙, obvykle pou╛φvßme vlastnosti OldValue
a NewValue polo╛kov²ch komponent p°i°azen²ch k souΦasnΘmu zßznamu.
D∙le╛itΘ: Udßlost OnUpdateRecord, podobn∞
jako obsluhy udßlostφ OnUpdateError a OnCalcFields, nikdy
nesmφ volat ╛ßdnou metodu, kterß m∞nφ (p°esouvß) souΦasn² zßznam v datovΘ
mno╛in∞.
Zpracovßnφ chyb odlo╛en²ch
aktualizacφ
Proto╛e mezi Φasem odlo╛enφ aktualizace zßznamu a jeho aplikovßnφm
uplynul n∞jak² Φas, je mo╛nΘ, ╛e jinΘ aplikace tento zßznam mohly zm∞nit
v databßzi d°φve ne╛ jej aplikace aplikuje. Nemusφ to b²t v╛dy konflik
mezi aktualizacemi u╛ivatel∙, ale p°i aplikovßnφ aktualizovanΘho zßznamu
vznikne chyba. BDE specißln∞ testuje konflikty aktualizacφ a dal╣φ podmφnky
a oznamuje chybu.
Udßlost OnUpdateError komponenty datovΘ mno╛iny
umo╛≥uje chyby zachytit a reagovat na n∞. M∙╛eme vytvo°it pro tuto udßlost,
pokud pou╛φvßme odlo╛enΘ aktualizace. Pokud ji nevytvo°φme a vznikne chyba,
pak celß aktualizaΦnφ operace je ne·sp∞╣nß.
Pozor: Nevolßme ╛ßdnou metodu datovΘ mno╛iny,
kterß m∞nφ souΦasn² zßzmam (jako je Next nebo Prior) v obsluze
udßlosti
OnUpdateError. Pokud to provedeme, pak obsluha udßlosti
p°ejde do nikdy nekonΦφcφho cyklu.
Nßsleduje kostra k≤du obsluhy udßlosti OnUpdateError:
void __fastcallTForm1::DataSetUpdateError(TDataSet
*DataSet,
EDatabaseError *E, TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
{
// Zde reagujeme na chybu...
}
V tΘto sekci jsou uvedeny je╣t∞ tyto body:
Odkazovßnφ
na datovou mno╛inu na kterou aplikujeme aktualizace
DataSet ukazuje na datovou mno╛inu na kterΘ jsou aplikovßny
aktualizace. Ke zpracovßnφ hodnot novΘho a starΘho zßznamu v pr∙b∞hu zpracovßnφ
chyb tento odkaz musφme p°edat.
Indikovßnφ
typu aktualizace, kterß generovala chybu
Udßlost OnUpdateError zφskßvß parametr UpdateKind,
kter² je typu TUpdateKind. Popisuje typ aktualizace, kterß generovala
chybu. Dokud na╣e obsluha chyb nebude provßd∞t specißlnφ akci na zßklad∞
typu aktualizace, pak nß╣ k≤d pravd∞podobn∞ tento parametr nebudeme pou╛φvat.
Nßsledujφcφ tabulka uvßdφ mo╛nΘ hodnoty pro UpdateKind:
Hodnota |
V²znam |
ukModify |
Editace existujφcφho zßznamu zp∙sobyla chybu. |
ukInsert |
Vlo╛enφ novΘho zßznamu zp∙sobylo chybu. |
ukDelete |
Zru╣enφ existujφcφho zßznamu zp∙sobylo chybu. |
Specifikace akce k provedenφ
UpdateAction je parametr typu TUpdateAction.
Kdy╛ na╣e aktualizaΦnφ chybovß obsluha je poprvΘ volßna, pak hodnota pro
tento parametr je v╛dy nastavena na uaFail. Na zßklad∞ chybovΘ podmφnky
pro zßznam zp∙sobujφcφ chybu jej m∙╛eme nastavit na jinou hodnotu p°ed
ukonΦenφm obsluhy. UpdateAction m∙╛eme nastavit na jednu z nßsledujφcφch
hodnot:
Hodnota |
V²znam |
uaAbort |
Zru╣enφ aktualizaΦnφ operace bez zobrazenφ chybovΘ zprßvy. |
uaFail |
Zru╣enφ aktualizaΦnφ operace a zobrazenφ chybovΘ zprßvy.
Je to implicitnφ hodnota pro UpdateAction. |
uaSkip |
P°eskoΦenφ aktualizovßnφ °ßdku, ale aktualizace pro zßznam
z∙stßvß v odklßdacφ pam∞ti. |
uaRetry |
Opakuje aktualizaΦnφ operaci. P°ed nastavenφm na tuto
hodnotu opravφme chybovou podmφnku. |
uaApplied |
Nepou╛φvßme ve funkcφch zpracovßnφ chyb. |
Jestli╛e na╣e obsluha chyby m∙╛e opravit chybovou podmφnku,
kterß zp∙sobila vyvolßnφ obsluhy, pak nastavφme UpdateAction na
p°φslu╣nou akci a obsluhu ukonΦφme. Pro opravenou chybovou podmφnku, nastavφme
SetAction
na uaRetry k opakovanΘmu aplikovßnφ aktualizace na zßznam. Kdy╛
nastavφme SetAction na uaSkip, pak aktualizace pro °ßdek
zp∙sobujφcφ chybu je p°eskoΦen a aktualizace z∙stane v odklßdacφ pam∞ti
po dokonΦenφ v╣ech ostatnφch aktualizacφ.
uaFail i uaAbort ukonΦujφ celou aktualizaΦnφ
operaci.
uaFail generuje v²jimku a zobrazuje chybovou zprßvu. uaAbort
generuje pouze v²jimku, ale zprßvu nezobrazuje.
Poznßmka: Pokud chyba vznikne v pr∙b∞hu aplikovßnφ
odlo╛en²ch aktualizacφ, pak je generovßna v²jimka a zobrazena chybovß zprßva.
Kdy╛
ApplyUpdates nenφ volßna z konstrukce try...catch, pak
chybovß zprßva pro u╛ivatele je zobrazena v obsluze udßlosti OnUpdateError,
m∙╛e b²t zobrazena dvakrßt. K zabrßn∞nφ duplikace chybovΘ zprßvy nastavφme
UpdateAction
na uaAbort.
Hodnota uaApplied m∙╛e b²t pou╛φvßna pouze v udßlosti
OnUpdateRecrd.
Tuto hodnotu nenastavujeme v aktualizaΦnφ obsluze chyby.
Prßce s textem chybovΘ zprßvy
Parametr E je obvykle typu EDBEngineError.
Z tohoto typu v²jimky, m∙╛eme zφskat chybovou zprßvu, kterou m∙╛eme zobrazit
pro u╛ivatele v na╣φ obsluze chyby. Nap°. nßsledujφcφ k≤d zobrazuje chybovou
zprßvu v komponet∞ Label:
ErrorLabel->Caption = E->Message;
Tento parametr je takΘ u╛iteΦn² k zji╣t∞nφ aktualnφ p°φΦiny
chyby. Z EDBEngineError m∙╛eme extrahovat chybov² k≤d a na zßklad∞
jeho hodnoty provΘst p°φslu╣nou akci. Nap°. nßsledujφcφ k≤d testuje, zda
chyba aktualizace je spojena s integritou klφΦe a pokud ano, pak parametr
UpdateAction
je nastaven na uaSkip.
// vlo╛φme BDE.hpp do na╣φ jednotky pro tento
p°φklad
void __fastcallTForm1::DataSetUpdateError(TDataSet
*DataSet,
EDatabaseError *E, TUpdateKind
UpdateKind, TUpdateAction &UpdateAction)
{
UpdateAction = uaFail
if (E->ClassNameIs("EDBEngineError"))
{
EDBEngineError *pDBE =
(EDBEngineError *)E;
if (pDBE->Errors[pDBE->ErrorCount
- 1]->ErrorCode == DBIERR_KEYVIOL)
UpdateAction
= uaSkip;
}
}
Zp°φstup≥ovßnφ
vlastnostφ OldValue, NewValue a CurValue polo╛ek
Kdy╛ jsou povoleny odlo╛enΘ aktualizace, pak p∙vodnφ hodnoty
pro polo╛ky v ka╛dΘm zßznamu jsou ulo╛eny ve vlastnostech OldValue
urΦen²ch pouze pro Φtenφ polo╛kov²ch komponent. NovΘ hodnoty jsou analogicky
ulo╛eny ve vlastnosti NewValue. V klientsk²ch datov²ch mno╛inßch,
dal╣φ vlastnost
CurValue, uklßdß hodnoty polo╛ek souΦasn∞ zobrazenΘ
v datovΘ mno╛in∞.
CurValue m∙╛e b²t stejnß jako OldValue
dokud jin² u╛ivatel needituje zßznam. Pokud jin² u╛ivatel edituje zßznam,
pak CurValue zφskß souΦasnou hodnotu polo╛ek kterΘ byly odeslßny
tφmto u╛ivatelem.
-
Nynφ se podφvßme na dal╣φ ji╛ hotov² program. Nalezneme jej v adresß°i
Program
files\Borland\CBuilder\Examples\DBTask\CachesUp. Jednß se o aplikaci
pou╛φvajφcφ odlo╛enΘ aktualizace. Aplikaci si prohlΘdn∞te a vyzkou╣ejte
ji.
![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/4/PreviousArrow.gif) ![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/4/NextArrow.gif) ![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/4/WayUpArrow.gif) |
21. Prßce s odlo╛en²mi aktualizacemi
|