17. Prßce s dotazy

Tato kapitola popisuje komponentu datovΘ mno╛iny TQuery, kterß umo╛≥uje pou╛φvat p°φkazy SQL k zp°φstup≥ovßnφ dat. P°edpoklßdß se, ╛e jsme se ji╛ seznßmili s obecn²m popisem datovΘ mno╛iny v kapitole 6.
Komponenta dotazu zaobaluje p°φkaz SQL, kter² je pou╛it v klientskΘ aplikaci k zφskßvßnφ, vklßdßnφ, aktualizaci a ru╣enφ dat z jednΘ nebo vφce databßzov²ch tabulek. SQL je jazykem pr∙myslovΘho standardu relaΦnφch databßzφ, kter² je pou╛φvßn databßzemi zalo╛en²mi na serveru, jako je Sybase, Oracle, InterBase a Microsoft SQL Server. Komponenty dotazu mohou b²t pou╛ity se vzdßlen²mi databßzov²mi servery (pokud na╣e verze C++ Builderu obsahuje SQL links), s Paradoxem, dBASE, FoxPro a Access a s databßzemi podporujφcφmi ODBC.
V tΘto kapitole se budeme zab²vat body:

Efektivnφ pou╛φvßnφ dotaz∙

K efektivnφmu pou╛φvßnφ komponenty dotazu se musφme seznßmit s: Pokud se zab²vßme v²vojem desktopu a p°echßzφme na aplikace zalo╛enΘ na serveru, pak se podφvejte do Dotazy pro v²vojß°e desktopu na ·vod k dotaz∙m p°ed p°eΦtenφm zbytku tΘto kapitoly.
Pokud jsme v²vojß°em databßzovΘho serveru, ale je pro nßs novΘ budovßnφ klient∙ pomocφ C++ Builderu, pak ji╛ dob°e znßme SQL a nß╣ server, ale nejsme seznßmeni s BDE. Podφvejte se na Dotazy pro v²vojß°e serveru na ·vod k dotaz∙m a BDE p°ed p°eΦtenφm zbytku tΘto kapitoly.
V tomto bod∞ se budeme zab²vat:
Dotazy pro v²vojß°e desktopu
Jako v²vojß° desktopu jsme seznßmeni s v²razy tabulka, zßznam a polo╛ka pou╛φvan²mi C++ Builderem a BDE. Umφme pou╛φvat komponentu TTable k zφskßnφ p°φstupu ke v╣em polo╛kßm v ka╛dΘm zßznamu v datovΘ mno╛in∞. Vφme, ╛e kdy╛ nastavφme vlastnost TableName pak specifikujeme databßzovou tabulku ke kterΘ p°istupujeme.
K omezenφ poΦtu dostupn²ch zßznam∙ pro na╣φ aplikaci pou╛φvß TTable metodu pro urΦenφ rozsahu a vlastnost filtru. Aplikacφ rozsahu doΦasn∞ omezφme datov² p°φstup na blok zßznam∙ souvisl²ch index∙, kterΘ vyhovujφ zadanΘ hraniΦnφ podmφnce, jako je nßvrat v╣ech zßznam∙ pro zam∞stnance jejich╛ jmΘna jsou v∞t╣φ nebo rovna Jones a men╣φ nebo rovna Smith. Nastavenφm filtru doΦasn∞ omezφme datov² p°φstup na mno╛inu zßznam∙, kterΘ obvykle nejsou sousednφ a spl≥ujφ filtrovacφ kritΘrium, jako je nßvrat pouze t∞ch zßkaznφk∙, kterΘ ╛ijφ v Kalifornii.
Dotazy se chovajφ v mnoha zp∙sobech jako filtr, s v²jimkou, ╛e pou╛φvajφ vlastnost SQL komponenty dotazu (a n∞kdy vlastnosti Params) k identifikaci zßznam∙ v datovΘ mno╛in∞ k zφskßnφ, vlo╛enφ, zru╣enφ nebo aktualizaci. V n∞kter²ch mo╛nostech dotaz je u╛iteΦn∞j╣φ ne╛ filtr, proto╛e usnad≥uje p°φstup: Dotazy mohou b²t nem∞nnΘ nebo mohou obsahovat nahraditelnΘ parametry. Dotazy, kterΘ pou╛φvajφ parametry se naz²vajφ parametrizovanΘ dotazy. Kdy╛ pou╛φvßme parametrizovanΘ dotazy, pak aktußlnφ hodnoty p°i°azenΘ k parametr∙m jsou vlo╛eny do dotazu pomocφ BDE p°ed provedenφm nebo spu╣t∞nφm dotazu. Pou╛φvßnφ parametrizovan²ch dotaz∙ je znaΦn∞ flexibilnφ, proto╛e m∙╛eme m∞nit pohled u╛ivatele a p°istupovanß data za b∞hu bez nutnosti modifikace p°φkazu SQL.
NejΦast∞j╣φ pou╛itφ dotaz∙ v na╣ich aplikacφch je k v²b∞ru dat, kterΘ u╛ivatel vidφ, stejn∞ jako kdy╛ pou╛ijeme komponentu tabulky. Dotazy ale takΘ mohou provßd∞t operace aktualizace, vklßdßnφ a ru╣enφ mφsto zφskßvßnφ zßznam∙ pro zobrazenφ. Kdy╛ pou╛ijeme dotaz k provedenφ operace vlo╛enφ, aktualizace nebo zru╣enφ, pak dotaz nevracφ zßznamy. Tφm se dotazy li╣φ od tabulek.
Vφce informacφ o vlastnosti SQL k zßpisu p°φkaz∙ SQL, o pou╛φvßnφ parametr∙ a provßd∞nφ dotazu bude uvedeno v dal╣φch bodech tΘto kapitoly.
Dotazy pro v²vojß°e serveru
Jako v²vojß° serveru se musφme dob°e seznßmit s SQL a s mo╛nostmi na╣eho databßzovΘho serveru. Dotaz je pro nßs SQL p°φkaz, kter² pou╛φvßme pro p°φstup k dat∙m. Musφme znßt jak pou╛φvat p°φkaz a jak s nφm pou╛φvat volitelnΘ parametry.
P°φkaz SQL a jeho parametry jsou nejd∙le╛it∞j╣φ Φßstφ komponenty dotazu. Vlastnost SQL komponenty dotazu je pou╛ita k poskytnutφ p°φkazu SQL pro p°φstup k dat∙m a vlastnost Params komponenty je volitelnΘ pole parametr∙ k vlo╛enφ do dotazu. Komponenta dotazu je ale mnohem vφce ne╛ jejφ p°φkaz SQL a jeho parametry. Komponenta dotazu je takΘ rozhranφ mezi na╣φ klientskou aplikacφ a BDE.
Klientskß aplikace pou╛φvß vlastnosti a metody komponenty dotazu k manipulaci s p°φkazem SQL a s jeho parametry, ke specifikaci dotazovanΘ databßze, k p°φprav∞ a zru╣enφ p°ipraven²ch p°φkaz∙ s parametry a k provßd∞nφ dotazu. Metody komponenty dotazu volajφ BDE, kterΘ zpracovßvajφ po╛adavky na╣eho dotazu a komunikujφ s databßzov²m serverem, obvykle prost°ednictvφm ovladaΦ∙ SQL Links. Server p°edßvß v²sledkovou mno╛inu (je-li) zp∞t BDE a BDE ji vracφ na╣φ aplikaci prost°ednictvφm komponenty dotazu.
Kdy╛ pracujeme s komponentou dotazu, pak musφme znßt terminologii pou╛φvanou k popisu slu╛eb BDE, proto╛e se li╣φ od terminologie pou╛φvanΘ programßtory SQL databßzφ. Nap°. BDE Φasto pou╛φvß termφn alias (p°ezdφvka) k odkazovßnφ na zkrßcenΘ jmΘno pro cestu k databßzovΘmu serveru. P°ezdφvka BDE je ulo╛ena v konfiguraΦnφm souboru a je nastavena ve vlastnosti DatabaseName komponenty dotazu. M∙╛eme stßle pou╛φvat p°ezdφvky tabulek nebo korelaΦnφ jmΘna tabulek v na╣ich SQL p°φkazech.
Podobn∞ BDE se Φasto odkazuje na dotazy pou╛φvajφcφ parametry jako na parametrizovanΘ dotazy, kterΘ jsou znßm∞j╣φ jako p°φkazy SQL pou╛φvajφcφ svßzanΘ prom∞nnΘ.
Vφce informacφ o pou╛φvßnφ vlastnosti SQL, o pou╛φvßnφ parametr∙, p°φprav∞ a provßd∞nφ dotaz∙ bude uvedeno v nßsledujφcφch bodech.

Ke kter²m databßzφm m∙╛eme p°istupovat komponentou dotazu?

Komponenta TQuery m∙╛e p°istupovat k dat∙m v: C++ Builder takΘ podporuje heterogennφ dotazy na vφce ne╛ jednom serveru nebo typu tabulky (nap°. data z tabulky Oracle a tabulky Paradoxu). Kdy╛ vytvß°φme heterogennφ dotaz, pak BDE pou╛φvß Lokßlnφ SQL ke zpracovßnφ dotazu.

Seznßmenφ s pou╛φvßnφm komponent dotazu

K pou╛itφ komponenty dotazu v aplikaci musφme p°i nßvrhu provΘst tyto kroky:
  1. Umφstφme komponentu dotazu ze strßnky DataAccess Palety komponent do datovΘho modulu a nastavφme jejφ vlastnost Name p°ijateln∞ pro na╣φ aplikaci.
  2. Nastavφme vlastnost DatabaseName komponenty na jmΘno dotazovanΘ databßze. DatabaseName m∙╛e b²t p°ezdφvka BDE, explicitnφ adresß°ovß cesta (pro lokßlnφ tabulky) nebo hodnota z vlastnosti DatabaseName komponenty TDatabase v aplikaci.
  3. Ve vlastnosti SQL komponenty specifikujeme p°φkaz SQL a nepovinn∞ specifikujeme libovolnΘ parametry pro p°φkaz ve vlastnosti Params.
  4. Pokud data dotazu majφ b²t pou╛ity vizußlnφmi datov²mi ovladaΦi, pak umφstφme komponentu datovΘho zdroje ze strßnky Data Access Palety komponent do datovΘho modulu a nastavφme jejφ vlastnost DataSet na jmΘno komponenty dotazu. Komponenta datovΘho zdroje je pou╛ita k nßvratu v²sledku dotazu (nazvanΘho v²sledkovß mno╛ina) z dotazu do datov²ch ovladaΦ∙ pro zobrazenφ. P°ipojenφ datov²ch ovladaΦ∙ k datovΘmu zdroji provedeme jejich vlastnostmi DataSource a DataField.
  5. Aktivujeme komponentu dotazu. Pro dotazy, kterΘ vracejφ v²sledkovou mno╛inu pou╛ijeme vlastnost Active nebo metodu Open. Pro dotazy, kterΘ provßd∞jφ pouze akci na tabulce a nevracφ v²sledkovou mno╛inu, pou╛ijeme metodu ExecSQL.
K prvnφmu provedenφ dotazu za b∞hu provedeme tyto kroky:
  1. Komponentu dotazu uzav°eme.
  2. Do vlastnosti SQL vlo╛φme p°φkaz SQL (pokud nebyl nastaven ji╛ p°i nßvrhu nebo chceme-li zm∞nit ji╛ poskytnut² p°φkaz SQL). P°i pou╛itφ p°φkazu z nßvrhu tento krok p°eskoΦφme.
  3. Nastavφme parametry a hodnoty parametr∙ ve vlastnosti Params p°φmo nebo pou╛itφm metody ParamByName. Pokud dotaz neobsahuje parametry nebo parametry nastavenΘ p°i nßvrhu se nem∞nφ, pak tento krok p°eskoΦφme.
  4. Volßme Prepare k inicializaci BDE a spojenφ hodnoty parametr∙ v dotazu. Volßnφ Prepare je nepovinnΘ, ale je doporuΦovßno.
  5. Volßme Open pro dotazy, kterΘ vracejφ v²sledkovou mno╛inu nebo volßme ExecSQL pro dotazy nevracejφcφ v²sledkovou mno╛inu.
Po prvnφm provedenφ dotazu, pokud nemodifikujeme p°φkaz SQL, aplikace m∙╛e opakovan∞ uzavφrat a op∞tovn∞ otevφrat nebo opakovan∞ spou╣t∞t dotaz bez op∞tovnΘ p°φpravy.

Specifikovßnφ p°φkazu SQL k provedenφ

Vlastnost SQL pou╛φvßme ke specifikaci p°φkazu dotazu SQL k provedenφ. B∞hem nßvrhu, dotaz je p°ipraven a proveden automaticky, kdy╛ nastavφme vlastnost Active komponenty dotazu na true. Za b∞hu, dotaz je p°ipraven volßnφm Prepare a proveden, kdy╛ aplikace volß metodu Open nebo ExecSQL komponenty.
Vlastnost SQL je objekt TStrings, co╛ je pole textov²ch °et∞zc∙ a obsahuje vlastnosti, udßlosti a metody, kterΘ s nim manipulujφ. ╪et∞zce v SQL jsou automaticky spojeny k vytvo°enφ p°φkazu SQL k provedenφ. P°φkaz m∙╛eme poskytnout v jednom nebo mnoha odd∞len²ch °et∞zcφch, jak pot°ebujeme. Jednou z v²hod pou╛itφ °ady °et∞zc∙ je to, ╛e m∙╛eme rozd∞lit p°φkaz SQL do logick²ch jednotek (nap°. vlo╛φme klauzuli WHERE pro p°φkaz SELECT do svΘho vlastnφho °et∞zce) a tak usnadnit modifikaci a lad∞nφ dotazu.
P°φkaz SQL m∙╛e b²t dotaz, kter² obsahuje pevn∞ k≤dovanß jmΘna polo╛ek a hodnoty nebo m∙╛e jφt o parametrizovan² dotaz, kter² obsahuje nahraditelnΘ parametry reprezentujφcφ hodnoty polo╛ek, kterΘ musφ b²t spojeny do p°φkazu p°ed jeho provedenφm. Nap°. nßsledujφcφ p°φkaz je pevn∞ k≤dovan²:
SELECT * FROM Customer WHERE CustNo = 1231
Pevn∞ k≤dovanΘ p°φkazy jsou u╛iteΦnΘ, kdy╛ aplikace provßdφ stejn² dotaz p°i ka╛dΘm spu╣t∞nφ. P°i nßvrhu nebo za b∞hu m∙╛eme snadno nahradit jeden pevn∞ k≤dovan² dotaz jin²m pevn∞ k≤dovan²m nebo parametrizovan²m dotazem podle pot°eby. Kdy╛ vlastnost SQL je m∞n∞na, pak dotaz je automaticky uzav°en a uvoln∞n.
Poznßmka: V dotazech pou╛φvajφcφch Lokßlnφ SQL, kdy╛ jmΘna sloupc∙ v dotazu obsahujφ mezery nebo specißlnφ znaky, pak jmΘno sloupce musφ b²t uzav°eno v uvozovkßch a musφ b²t p°edchßzeno odkazem na tabulku a teΦkou. Nap°. BIOLIFE."Species Name".
Parametrizovan² dotaz obsahuje jeden nebo vφce mφst pro parametry, aplikaΦnφ prom∞nnΘ kterΘ slou╛φ pro porovnßvßnφ hodnot v klauzulφch WHERE p°φkazu SELECT. Pou╛φvßnφ parametrizovan²ch dotaz∙ umo╛≥uje zm∞nit hodnotu bez nutnosti p°epsßnφ aplikace. Hodnoty parametr∙ musφ b²t svßzanΘ s p°φkazem SQL p°ed prvnφm provedenφm p°φkazu. Komponenta dotazu toto provede automaticky i kdy╛ nevolßme metodu Prepare p°ed provedenφm p°φkazu.
Tento p°φkaz je parametrizovan² dotaz:
SELECT * FROM Customer WHERE CustNo = :Number
Prom∞nnß Number (zaΦφnajφcφ dvojteΦkou) je parametr jeho╛ hodnota pro porovnßvßnφ musφ b²t poskytnuta za b∞hu a p°i ka╛dΘm provßd∞nφ p°φkazu m∙╛e b²t jinß. Aktußlnφ hodnota pro Number je poskytovßna ve vlastnosti Params komponenty dotazu.
Tip: Je vhodnou programovacφ zßsadou k poskytovßnφ jmen prom∞nn²ch pro parametry, kterΘ odpovφdajφ aktußlnφmu jmΘnu sloupce se kter²m jsou p°i°azeny. Nap°. pokud jmΘno sloupce je Number, pak jeho odpovφdajφcφ parametr bude :Number. Pou╛φvßnφ shodujφcφch se jmen zajistφme, ╛e kdy╛ dotaz pou╛ije svou vlastnost DataSource k poskytnutφ hodnot pro parametry pak m∙╛eme p°i°adit jmΘno prom∞nnΘ k p°φpustnΘmu jmΘnu polo╛ky.
V tΘto sekci nalezneme je╣t∞ tyto body:
Specifikovßnφ vlastnosti SQL p°i nßvrhu
Vlastnost SQL m∙╛eme specifikovat p°i nßvrhu pomocφ Editoru seznamu °et∞zc∙. K vyvolßnφ Editoru seznamu °et∞zc∙ pro vlastnost SQL: P°φkaz SQL m∙╛eme zadßvat na n∞kolika °ßdcφch. To usnad≥uje jeho Φtenφ, zm∞ny a lad∞nφ. Stiskem OK p°i°adφme zapsan² text vlastnosti SQL. Normßln∞ vlastnost SQL m∙╛e obsahovat pouze jeden kompletnφ p°φkaz SQL, i kdy╛ tyto p°φkazy mohou b²t slo╛itΘ (nap°. p°φkaz SELECT s klauzulφ WHERE, kterß pou╛φvß n∞kolik vno°en²ch logick²ch operßtor∙ jako je AND a OR). N∞kterΘ servery takΘ podporujφ "dßvkovou" syntaxi kterß umo╛≥uje vφce p°φkaz∙; pokud nß╣ server tuto syntaxi podporuje, pak do vlastnosti SQL m∙╛eme zadat vφce p°φkaz∙.
Poznßmka: V n∞kter²ch verzφch C++ Builderu, m∙╛eme takΘ pou╛φt SQL Builder k vytvß°enφ dotazu na zßklad∞ viditelnΘ reprezentace tabulek a polo╛ek v databßzi. K pou╛itφ SQL Builderu, vybereme komponentu dotazu, vyvolßme jejφ mφstnφ nabφdku a zvolφme Graphical Query Editor. Tato volba je dostupnß pouze v n∞kter²ch verzφch C++ Builderu.
Specifikovßnφ p°φkazu SQL za b∞hu
Jsou t°i mo╛nosti jak nastavit vlastnost SQL za b∞hu. Aplikace m∙╛e nastavit vlastnost SQL p°φmo, m∙╛e volat metodu LoadFromFile vlastnosti SQL k zavedenφ p°φkazu SQL ze souboru nebo p°φkaz SQL v seznamu °et∞zc∙ m∙╛e b²t p°i°azen vlastnosti SQL.

P°φmΘ nastavovßnφ vlastnosti SQL
K p°φmΘmu nastavenφ vlastnosti SQL za b∞hu:

  1. Volßme Close k deaktivaci dotazu. I kdy╛ pokus o modifikaci vlastnosti SQL automaticky deaktivuje dotaz, je vhodnΘ to provΘst explicitn∞.
  2. Pokud nahrazujeme cel² p°φkaz SQL, pak volßme metodu Clear pro vlastnost SQL k zru╣enφ souΦasnΘho p°φkazu SQL.
  3. Pokud vytvß°φme cel² p°φkaz SQL z niΦeho nebo k existujφcφmu p°φkazu p°idßvßme °ßdek, pak volßme metodu Add pro vlastnost SQL k p°idßnφ jednoho nebo vφce °et∞zc∙ k vlastnosti SQL v vytvo°enφ novΘho p°φkazu SQL. M∙╛eme takΘ modifikovat existujφcφ °ßdek vlastnosti SQL s indexem indikujφcφm ovliv≥ovan² °ßdek a p°i°azenφm novΘ hodnoty.
  4. Volßme Open nebo ExecSQL k provedenφ dotazu.
Nßsledujφcφ k≤d ukazuje budovßnφ celΘho p°φkazu SQL z niΦeho:
CustomerQuery->Close();      // Uzav°enφ dotazu, je-li aktivnφ
CustomerQuery->SQL->Clear(); // Zru╣enφ p°φkazu SQL, je-li
CustomerQuery->SQL->Add("SELECT * FROM Customer");
CustomerQuery->SQL->Add("WHERE Company = 'Sight Diver'");
CustomerQuery->Open();
Poznßmka: Pokud dotaz pou╛φvß parametry, je takΘ nutno nastavit jejich poΦßteΦnφ hodnoty a volat metodu Prepare p°ed otev°enφm nebo provedenφm dotazu. Explicitnφm volßnφm Prepare je obzvlß╣t∞ u╛iteΦnΘ, pokud stejn² p°φkaz SQL je pou╛φvßn opakovan∞, jinak je metoda volßna automaticky komponentou dotazu.

Zavßd∞nφ vlastnosti SQL ze souboru
K p°i°azenφ p°φkazu SQL z textovΘho souboru, m∙╛eme takΘ pou╛φt metodu LoadFromFile vlastnosti SQL. Metoda LoadFromFile automaticky vyprazd≥uje souΦasn² obsah vlastnosti SQL p°ed zavedenφm novΘho p°φkazu ze souboru. Nap°.
CustomerQuery->Close();
CustomerQuery->SQL->LoadFromFile("C:\\ORDERS.TXT");
CustomerQuery->Open();
Poznßmka: Pokud p°φkaz SQL obsa╛en² v souboru je parametrizovan² p°φkaz, pak nastavφme poΦßteΦnφ hodnoty pro parametry a volßme metodu Prepare p°ed otev°enφm nebo provedenφm dotazu. Explicitnφm volßnφm Prepare je obzvlß╣t∞ u╛iteΦnΘ, pokud stejn² p°φkaz SQL je pou╛φvßn opakovan∞, jinak je metoda volßna automaticky komponentou dotazu.

Zavßd∞nφ vlastnosti SQL z objektu seznamu °et∞zc∙
M∙╛eme takΘ pou╛φt metodu Assign vlastnosti SQL ke kopφrovßnφ obsahu seznamu °et∞zc∙ do vlastnosti SQL. Metoda Assign automaticky vyprßzdnφ souΦasn² obsah p°ed kopφrovßnφm novΘho p°φkazu.

Nastavovßnφ parametr∙

ParametrizovanΘ p°φkazy SQL obsahujφ parametry nebo prom∞nnΘ, jejich╛ hodnoty se mohou m∞nit. Parametry nahrazujφ datovΘ hodnoty (nap°. hodnoty pou╛itΘ v klauzuli WHERE po porovnßvßnφ), kterΘ se vyskytujφ v p°φkazu SQL. Parametry normßln∞ slou╛φ pro p°edßvßnφ hodnot p°φkazu. Nap°. v nßsledujφcφm p°φkazu INSERT vklßdanΘ hodnoty jsou p°edßny jako parametry:
INSERT INTO Country (Name, Capital, Population)
VALUES (:Name, :Capital, :Population)
V tomto p°φkazu SQL, :name, :capital a :population jsou mφsta pro hodnoty aktußlnφch parametr∙ p°edan²ch p°φkazu za b∞hu aplikacφ. D°φve ne╛ parametrizovan² dotaz m∙╛e b²t poprvΘ proveden, na╣e aplikace musφ volat metodu Prepare ke spojenφ souΦasn²ch hodnot parametr∙ s p°φkazem SQL. Spojenφ znamenß, ╛e BDE a server alokuje zdroje pro p°φkaz a jeho parametry pro zv²╣enφ rychlosti provßd∞nφ dotazu.
V tΘto sekci je╣t∞ nalezneme:
Dodßvßnφ parametr∙ p°i nßvrhu
P°i nßvrhu, parametry v p°φkazu SQL se zobrazujφ v Editoru parametr∙. K zp°φstupn∞nφ objekt∙ TParams pro parametry, vyvolßme Editor parametr∙, vybereme parametr a p°istupujeme k vlastnostem TParam v Inspektoru objekt∙. Pokud p°φkaz SQL neobsahuje ╛ßdnΘ parametry, pak v Editoru parametr∙ nenφ uveden ╛ßdn² objekt TParam. M∙╛eme pouze p°idßvat parametry zßpisem v p°φkazu SQL.
K zp°φstupn∞nφ parametr∙:
  1. Vybereme komponentu dotazu.
  2. Stiskneme tlaΦφtko se t°emi teΦkami pro vlastnost Params v Inspektoru objekt∙.
  3. V Editoru parametr∙ vybereme parametr.
  4. Objekt TParam pro vybran² parametr je zobrazen v Inspektoru objekt∙.
  5. ProhlΘdneme a modifikujeme vlastnosti pro TParam v Inspektoru objekt∙.
Pro dotazy, kterΘ neobsahujφ parametry (vlastnost SQL je prßzdnß nebo existujφcφ p°φkaz SQL nemß parametry), majφ seznam parametr∙ v Editoru parametr∙ prßzdn². Pokud v p°φkazu SQL jsou pou╛ity parametry, pak Editor parametr∙ uvßdφ v╣echny existujφcφ parametry.
Poznßmka: Komponenta TQuery sdφlφ objekt TParam a jeho Editor s n∞kolika r∙zn²mi komponentami. Mφstnφ nabφdka Editoru v╛dy obsahuje volby Add a Delete, kterΘ pro komponentu TQuery nemajφ nikdy v²znam. Jedinou mo╛nostφ p°idßvßnφ nebo ru╣enφ parametr∙ TQuery je samotn² p°φkaz SQL.
Kdy╛ v Editoru parametr∙ je vybrßn parametr, pak Inspektor objekt∙ zobrazuje vlastnosti a udßlosti pro tento parametr. Hodnoty vlastnostφ parametr∙ tedy nastavujeme v Inspektoru objekt∙.
Vlastnost DataType uvßdφ datovΘ typy BDE pro parametr vybran² v Editoru. P∙vodnφ typ je ftUnknown. Pro ka╛d² parametr musφme nastavit datov² typ. Obecn∞ datovΘ typy BDE jsou p°izp∙sobenΘ na datovΘ typy serveru.
Vlastnost ParamType uvßdφ typ parametru vybranΘho v Editoru. P∙vodnφ typ je ptUnknown. Typ musφme nastavit pro ka╛d² parametr.
Vlastnost Value pou╛ijeme ke specifikaci hodnoty pro vybran² parametr p°i nßvrhu. Toto nenφ nutnΘ, kdy╛ hodnotu parametru dodßvßme za b∞hu. V t∞chto p°φpadech ponechßme Value prßzdnΘ.
Dodßvßnφ parametr∙ za b∞hu
K vytvo°enφ parametr∙ za b∞hu, m∙╛eme pou╛φt: Pro v╣echny nßsledujφcφ p°φkazy, p°edpoklßdßme, ╛e vlastnost SQL obsahuje nßsledujφcφ p°φkaz SQL. V╣echny t°i pou╛itΘ parametry jsou datovΘho typu ftString.
INSERT INTO "COUNTRY.DB"
(Name, Capital, Continent)
VALUES (:Name, :Capital, :Continent)
Nßsledujφcφ k≤d pou╛φvß ParamByName k p°i°azenφ textu z editaΦnφho ovladaΦe parametru Capital:
Query1->ParamByName("Capital")->AsString = Edit1->Text;
To samΘ je provedeno pomocφ vlastnosti Params, pou╛itφm indexu 1 (parametr Capital je druh²m parametrem p°φkazu SQL):
Query1->Params->Items[1]->AsString = Edit1->Text;
Pou╛φvßnφ datovΘho zdroje ke spojenφ parametr∙
Pokud hodnoty parametr∙ pro parametrizovan² dotaz nejsou spojeny p°i nßvrhu nebo specifikovßny za b∞hu, pak komponenta dotazu se pokusφ zφskat hodnoty na zßklad∞ svΘ vlastnosti DataSource. DataSource specifikuje jinou komponentu dotazu nebo tabulky, ve kterΘ komponenta dotazu m∙╛e nalΘzt jmΘna polo╛ek odpovφdajφcφ jmΘn∙m zatφm nespojen²ch parametr∙. Tedy prohledßvanß datovß mno╛ina musφ b²t vytvo°ena a zapln∞na p°ed vytvo°enφm komponenty dotazu, kterß ji pou╛φvß. Pokud polo╛ka je nalezena, pak komponenta dotazu spojuje hodnotu parametru s hodnotou polo╛ky v souΦasnΘm zßznamu na kter² ukazuje datov² zdroj.
Vytvo°φme jednoduchou aplikaci, abychom pochopili jak pou╛φt vlastnost DataSource k spojenφ dotazu do tvaru Master-detail. P°edpoklßdejme, ╛e datov² modul pro tuto aplikaci je nazvßn LinkModule a ╛e obsahuje komponentu dotazu nazvanou OrdersQuery, kterß mß nßsledujφcφ vlastnost SQL:
SELECT CustNo, OrderNo, SaleDate
FROM Orders
WHERE CustNo = :CustNo
Datov² modul LinkModule takΘ obsahuje: P°edpoklßdejme takΘ, ╛e tato aplikace mß formulß° nazvan² LinkedQuery, kter² obsahuje dv∞ datovΘ m°φ╛ky (m°φ╛ku Customer Table spojenou s CustomersSource a m°φ╛ku Order Query spojenou s OrdersSource).
Nßsledujφcφ obrßzek ukazuje jak aplikace vypadß p°i nßvrhu.


Poznßmka: Pokud budeme vytvß°et tuto aplikaci, pak musφme vytvo°it komponentu tabulky a jejφ datov² zdroj p°ed vytvo°enφm komponenty dotazu.
Pokud p°elo╛φme a spustφme tuto aplikaci, pak jeliko╛ parametr v p°φkazu SQL :CustNo pro OrdersQuery nemß p°i°azenou hodnotu, OrdersQuery se pokou╣φ nalΘzt stejnΘ jmΘno sloupce v tabulce urΦenΘ CustomersSource. CustomersSource zφskßvß svoje data z CustomersTable, kterß odvozuje data od tabulky CUSTOMER.DB. Proto╛e CUSTOMER.DB obsahuje sloupec nazvan² CustNo, je hodnota z polo╛ky CustNo souΦasnΘho zßznamu datovΘ mno╛iny CustomersTable p°i°azena parametru :CustNo pro p°φkaz SQL OrdersQuery. Ob∞ m°φ╛ky jsou sestaveny do vztahu Master-detail. Za b∞hu, poka╛dΘ, kdy╛ vybereme jin² zßznam v m°φ╛ce Customer Table, p°φkaz SELECT OrdersQuery je proveden k zφskßnφ v╣ech objednßvek pro prßv∞ vybranΘho zßkaznφka.

Provßd∞nφ dotazu

Po specifikaci p°φkazu SQL ve vlastnosti SQL a nastavenφ pot°ebn²ch parametru pro dotaz, m∙╛eme dotaz provΘst. P°i provßd∞nφ dotazu BDE zφskß a zpracovßvß p°φkaz SQL od na╣φ aplikace. Pokud dotaz se t²kß lokßlnφch tabulek (dBASE nebo Paradox), pak SQL BDE zpracovßvß p°φkaz SQL a pro p°φkaz SELECT vracφ data aplikaci. Pokud dotaz se vztahuje k tabulce SQL serveru a vlastnost RequiestLive dotazu je nastavena na false, pak p°φkaz SQL nenφ zpracovßn nebo interpretovßn BDE, ale je p°edßn p°φmo databßzovΘmu systΘmu. Kdy╛ vlastnost RequestLive je nastavena na true, pak p°φkaz SQL se chovß jako standard lokßlnφho SQL a BDE je pou╛ito pro p°evod datov²ch zm∞n na tabulku.
Poznßmka: D°φve ne╛ m∙╛eme provΘst dotaz poprvΘ, musφme volat metodu Prepare k zv²╣enφ v²konnosti dotazu. Prepare inicializuje BDE a databßzov² server a alokuje pro doraz pot°ebnΘ systΘmovΘ zdroje.
V nßsledujφcφch bodech jsou popisovßny jak statickΘ tak i dynamickΘ p°φkazy SQL. Jsou zde tyto body:
Provßd∞nφ dotazu p°i nßvrhu
K provedenφ dotazu p°i nßvrhu, nastavφme jeho vlastnost Active na true v Inspektoru objekt∙. V²sledek dotazu (je-li n∞jak²) je zobrazen v datov²ch ovladaΦφch p°i°azen²ch ke komponent∞ dotazu.
Poznßmka: Vlastnost Active m∙╛e b²t pou╛ita pouze s dotazem vracejφcφm v²sledkovou mno╛inu, jako je p°φkaz SELECT.
Provßd∞nφ dotazu za b∞hu
K provedenφ dotazu za b∞hu, pou╛ijeme jednu z nßsledujφcφch metod: Poznßmka: Pokud b∞hem nßvrhu nevφme zda dotaz bude za b∞hu vracet v²sledkovou mno╛inu, pak zak≤dujeme oba typy provßd∞nφ dotazu do bloku try ... catch. Volßnφ metody Open vlo╛φme do klauzule try. To umo╛nφ potlaΦit chybovΘ hlß╣enφ, kterΘ je p°φpadn∞ vyvolßno pou╛itφm neaplikovatelnΘ metody aktivace pro pou╛it² p°φkaz SQL. Testujeme tak vzniklΘ v²jimky. Jednß-li se o jinou ne╛ ENoResult, pak v²jimka byla zp∙sobena z jinΘho d∙vodu a musφ b²t zpracovßna. Toto pracuje, proto╛e akce dotazu bude provedena p°i aktivovßnφ dotazu metodou Open, ale v²jimka nastane p°i pou╛itφ jinΘho p°φkazu SQL ne╛ dotazu.

Provßd∞nφ dotazu vracejφcφho v²sledkovou mno╛inu
K provedenφ dotazu, kter² vracφ v²sledkovou mno╛inu (dotaz, kter² pou╛φvß p°φkaz SELECT), provedeme tyto kroky:

  1. Volßme Close k zaji╣t∞nφ toho, aby dotaz ji╛ opravdu nebyl otev°en. Pokud dotaz je otev°en, pak jej nem∙╛eme otev°φt znova bez jeho uzav°enφ. Uzav°enφm dotazu a op∞tovn²m otev°enφm zφskßme novou verzi dat ze serveru.
  2. Volßme Open k provedenφ dotazu.
Nap°.
CustomerQuery->Close();
CustomerQuery->Open(); // Nßvrat v²sledkovΘ mno╛iny

Provßd∞nφ dotazu bez v²sledkovΘ mno╛iny
K provedenφ dotazu, kter² nevracφ v²sledkovou mno╛inu (dotaz, kter² mß p°φkaz typu INSERT, UPDATE nebo DELETE), volßme k provedenφ dotazu ExecSQL. Nap°.
CustomerQuery->ExecSQL(); // Nevracφ v²sledkovou mno╛inu

P°φprava dotazu

P°φprava dotazu je nepovinn² krok, kter² p°edchßzφ provedenφ dotazu. P°φprava dotazu p°edßvß p°φkaz SQL a jeho parametry (jsou-li n∞jakΘ), BDE k rozlo╛enφ, alokovßnφ zdroj∙ a optimalizaci. BDE seznamuje databßzov² server s p°φpravou dotazu. Server takΘ pro dotaz m∙╛e alokovat zdroje. Tyto operce zvy╣ujφ v²konnost dotazu, zrychlujφ na╣φ aplikaci obzvlß╣t∞ p°i prßci s modifikovateln²mi dotazy.
Aplikace m∙╛e p°ipravit dotaz volßnφm metody Prepare. Pokud nep°ipravφme dotaz p°ed jeho provedenφm, pak jej C++ Builder p°ipravφ automaticky p°i volßnφ Open nebo ExecSQL. I kdy╛ C++ Builder p°ipravφ dotaz za nßs, je vhodnΘ provßd∞t explicitnφ p°φpravu dotazu. Nß╣ k≤d je tak srozumiteln∞j╣φ. Nap°.
CustomerQuery->Close();
if (!CustomerQuery->Prepared)
  CustomerQuery->Prepare();
CustomerQuery->Open();
Tento p°φklad testuje vlastnost Prepared komponenty dotazu k zji╣t∞nφ zda dotaz je ji╛ p°ipraven. Prepared je logickß hodnota, kterß je true, pokud dotaz je ji╛ p°ipraven. Pokud dotaz nenφ p°ipraven, pak p°φklad volß metodu Prepare p°ed volßnφm Open.

Zru╣enφ p°ipravenΘho dotazu k uvoln∞nφ zdroj∙

Metoda UnPrepared nastavuje vlastnost Prepared na false. UnPrepare: K zru╣enφ p°φpravy dotazu volßme
CustomerQuery->UnPrepare();
Poznßmka: Kdy╛ zm∞nφme text vlastnosti SQL pro dotaz, pak komponenta dotazu automaticky uzav°e a zru╣φ p°φpravu dotazu.

Vytvß°enφ heterogennφch dotaz∙

C++ Builder podporuje heterogennφ dotazy, tj. dotazy na tabulkßch ve vφce ne╛ jednΘ databßzi. Heterogennφ dotaz m∙╛e spojovat tabulky na r∙zn²ch serverech a na r∙zn²ch typech server∙. Nap°. heterogennφ dotaz m∙╛e po╛adovat tabulku z databßze Oracle, tabulku z databßze Sybase a lokßlnφ tabulku dBASE. Kdy╛ provßdφme heterogennφ dotaz, pak BDE rozlo╛φ a zpracovßvß dotaz pomocφ lokßlnφho SQL. Proto╛e BDE pou╛φvß lokßlnφ SQL, roz╣φ°enφ SQL specifickß pro servery nejsou podporovßna.
K provedenφ heterogennφho dotazu ud∞lßme tyto kroky:
  1. Definujeme samostatnΘ p°ezdφvky BDE pro ka╛dou databßzi pou╛itou v dotazu. Vyprßzdnφme vlastnost DatabaseName TQuery; jmΘna dvou pou╛it²ch databßzφ specifikujeme v p°φkazu SQL.
  2. Specifikujeme p°φkaz SQL k provedenφ ve vlastnosti SQL. Ka╛dΘ jmΘno tabulky v p°φkazu SQL musφ p°edchßzet p°ezdφvka pro databßzi, ve kterΘ tabulku m∙╛eme nalΘzt. P°ezdφvky BDE p°edchßzejφcφ jmΘno tabulky uzav°eme do dvojteΦek. Cel² odkaz na tabulku pak uzav°eme do uvozovek.
  3. Nastavφme pot°ebnΘ parametry pro dotaz do vlastnosti Params.
  4. Volßme Prepare pro p°φpravu dotazu na provedenφ p°ed prvnφm provedenφm.
  5. Volßme Open nebo ExecSQL v zßvislosti na typu provßd∞nΘho dotazu.
Nap°. p°edpoklßdejme, ╛e jsme definovali p°ezdφvku nazvanou Oracle1 pro databßzi Oracle s tabulkou CUSTOMER a p°ezdφvku Sybase1 pro databßzi Sybase s tabulkou ORDERS. Jednoduch² dotaz spojujφcφ tyto dv∞ tabulky bude:
SELECT Customer.CustNo, Orders.OrderNo
FROM ":Oracle1:CUSTOMER"
  JOIN ":Sybase1:ORDERS"
    ON (Customer.CustNo = Orders.CustNo)
WHERE (Customer.CustNo = 1503)
Jako alternativa k pou╛φvßnφ p°ezdφvky BDE ke specifikaci databßze v heterogennφm dotazu, m∙╛eme pou╛φt komponentu TDatabase. Konfigurujeme TDatabase jako normßln∞ k ukazovßnφ na databßzi, nastavφme TDatabase::DatabaseName na libovolnou, ale unikßtnφ hodnotu a potom pou╛ijeme tuto hodnotu v p°φkazu SQL namφsto jmΘna p°ezdφvky BDE.

Zvy╣ovßnφ v²konnosti dotazu

Nßsledujφ kroky, kterΘ m∙╛eme provΘst k zv²╣enφ rychlosti provßd∞nφ dotazu: Vlastnost UniDirectional urΦuje zda pro dotaz jsou povoleny obousm∞rnΘ kurzory BDE. Kdy╛ dotaz vrßtφ v²sledkovou mno╛inu, je takΘ zφskßn kurzor (ukazatel na prvnφ zßznam ve v²sledkovΘ mno╛in∞). Zßznam urΦen² kurzorem je souΦasn² aktivnφ zßznam. SouΦasn² zßznam je ten, jeho╛ hodnoty polo╛ek jsou zobrazeny v datov²ch ovladaΦφch p°i°azen²ch k datovΘmu zdroji v²sledkovΘ mno╛iny.
UniDirectional je implicitn∞ false, co╛ znamenß, ╛e kurzor pro v²sledkovou mno╛inu m∙╛e prochßzet po zßznamech dop°edu i dozadu. Obousm∞rnΘ kurzory vy╛adujφ urΦitΘ zpracovßnφ, co╛ m∙╛e zpomalit n∞kterΘ dotazy. Pro zv²╣enφ v²konnosti dotazu, m∙╛eme natavit UniDirectional na false k omezenφ zp∞tnΘho pohybu kurzoru ve v²sledkovΘ mno╛in∞.
Pokud nepot°ebujeme prochßzet v²sledkovou mno╛inou zp∞t, pak m∙╛eme nastavit UniDirectional na true pro dotaz. UniDirectional nastavφme p°ed p°φpravou a provedenφm dotazu. Nßsledujφcφ k≤d ukazuje nastavenφ UniDirectional p°ed p°φpravou a provedenφm dotazu:
if (!CustomerQuery->Prepared)
{
  CustomerQuery->UniDirectional = true;
  CustomerQuery->Prepare();
}
CustomerQuery->Open(); // Vracφ v²sledkovou mno╛inu s jednosm∞rn²m kurzorem

Prßce s v²sledkovou mno╛inou

Implicitn∞ v²sledkovß mno╛ina vracenß dotazem je urΦenß pouze pro Φtenφ. Na╣e aplikace m∙╛e zobrazovat hodnoty polo╛ek z v²sledkovΘ mno╛iny v datov²ch ovladaΦφch, ale u╛ivatel tyto hodnoty nem∙╛e editovat. K umo╛n∞nφ editovßnφ v²sledkovΘ mno╛iny, na╣e aplikace musφ po╛adovat "╛ivou" v²sledkovou mno╛inu.
V tΘto sekci jsou uvedeny tyto body:
Povolenφ editace v²sledkovΘ mno╛iny
K zφskßnφ v²sledkovΘ mno╛iny, kde u╛ivatel m∙╛e editovat datovΘ ovladaΦe, nastavφme vlastnost RequestLive komponenty dotazu na true. Nastavenφm RequestLive na true je╣te nezajistφme ╛ivou v²sledkovou mno╛inu, ale BDE se ji pokusφ zajisti, pokud je to mno╛nΘ. Jsou n∞kterß omezenφ na ╛ivou v²sledkovou mno╛inu, zßvisejφcφ na tom zda dotaz pou╛φvß lokßlnφ SQL nebo serverovΘ SQL. Heterogennφ dotazy provßd∞nΘ na tabulkßch Paradoxu nebo dBASE jsou p°edßny BDE pomocφ lokßlnφho SQL. Dotazy urΦenΘ vzdßlenΘmu databßzovΘmu serveru jsou p°edßny serveru.
Pokud aplikace po╛aduje a zφskß ╛ivou v²sledkovou mno╛inu, pak vlastnost CanModify komponenty dotazu je nastavena na true. Pokud aplikace po╛aduje ╛ivou v²sledkovou mno╛inu, ale syntaxe p°φkazu SELECT to neumo╛≥uje, pak BDE vracφ:
Po╛adavky lokßlnφho SQL na ╛ivou v²sledkovou mno╛inu
Pro dotazy, kterΘ pou╛φvajφ lokßlnφ SQL, BDE nabφzφ roz╣φ°enou podporu pro aktualizovßnφ ╛ivΘ v²sledkovΘ mno╛iny v jednoduchΘ tabulce i ve vφce tabulkovΘm dotazu. Lokßlnφ SQL je pou╛ito, kdy╛ dotaz je proveden na jednΘ nebo vφce tabulkßch dBASE nebo Paradoxu, nebo na jednΘ nebo vφce tabulkßch vzdßlenΘho serveru, kdy╛ tato jmΘna v dotazu jsou p°edchßzena BDE p°ezdφvkou databßze.
Pro dotaz na jednoduchΘ tabulce nebo pohledu je vrßcena ╛ivß v²sledkovß mno╛ina, pokud dotaz neobsahuje nic z nßsledujφcφho:
Po╛adavky vzdßlenΘho serveru pro ╛ivou v²sledkovou mno╛inu
Pro dotazy pou╛φvajφcφ pr∙chozφ SQL (cel² dotaz je p°edßn vzdßlenΘmu serveru), ╛ivΘ v²sledkovΘ mno╛iny jsou omezeny na standard definovan² SQL-92 a dal╣φ serverovß omezenφ. «ivß v²sledkovß mno╛ina pro dotaz na samostatnΘ tabulce nebo pohledu je vrßcena, pokud dotaz neobsahuje nic z nßsledujφcφho:
Omezenφ na aktualizacφch ╛ivΘ v²sledkovΘ mno╛iny
Pokud dotaz vracφ ╛ivou v²sledkovou mno╛inu, pak v²sledkovß mno╛ina nemusφ b²t aktualizovatelnß p°φmo, pokud v²sledkovß mno╛ina obsahuje spojovanΘ polo╛ky nebo p°epneme indexy p°ed pokusem o aktualizaci. Pokud tyto omezenφ existujφ, pak v²sledkovou mno╛inu m∙╛eme chßpat jako mno╛inu urΦenou pouze pro Φtenφ.
Aktualizovßnφ v²sledkovΘ mno╛iny urΦenΘ pouze pro Φtenφ
Aplikace m∙╛e aktualizovat data vracenß v²sledkovou mno╛inou urΦenou pouze pro Φtenφ, pokud pou╛φvßme odlo╛enΘ aktualizace. K aktualizaci v²sledkovΘ mno╛iny urΦenΘ pouze pro Φtenφ p°i°azenΘ ke komponent∞ dotazu:
  1. P°idßme komponentu TUpdateSQL k datovΘmu modulu v na╣i aplikaci k umo╛n∞nφ odesφlat aktualizace do datovΘ mno╛iny urΦenΘ pouze pro Φtenφ.
  2. Zadßme p°φkaz aktualizace SQL pro v²sledkovou mno╛inu k vlastnostem ModifySQL, InsertSQL nebo DeleteSQL komponenty.
  3. Nastavφme vlastnost CachedUpdate komponenty dotazu na true.

  1. V adresß°i Program files\Borland\CBuilder\Examples\DBTask\Filter nalezneme demonstraΦnφ aplikaci filtrujφcφ zßznamy databßze. Jsou zde takΘ p°epφnßny datovΘ mno╛iny. ProhlΘdn∞te si tuto aplikaci a zjist∞te jak pracuje.
  2. V adresß°i Program files\Borland\CBuilder\Examples\DBTask\Contacts spravujφcφ zßkaznφky a jejich objednßvky. ProhlΘdn∞te si takΘ tuto aplikaci a zjist∞te jak pracuje.
17. Prßce s dotazy