V této kapitole popíšeme, jak používat ve svých databázových
aplikacích komponentu datové množiny TTable. Komponenta tabulky
zaobaluje úplnou strukturu a data v připojené databázové tabulce. Komponenta
tabulky dědí mnoho svých základních vlastností a metod od TDataSet,
TBDEDataSet
a
TDBDataSet. S těmito komponentami jsme se již seznámili.
S komponentou tabulky se seznámíme v těchto bodech:
Používání komponenty tabulky
Komponenta tabulky nám dává přístup ke každému řádku a sloupci
v připojené databázové tabulce, která je v Paradoxu, dBASE, Accessu, FoxPro,
ODBC databáze nebo SQL databáze na vzdáleném serveru, jako je InterBase,
Sybase nebo SQL Server.
Můžeme editovat a prohlížet data v každém sloupci a řádku
tabulky. Můžeme pracovat z rozsahem řádků v tabulce a můžeme filtrovat
záznamy k získání podmnožiny řádků tabulky splňující zadané filtrovací
kritérium. Můžeme vyhledávat záznamy, kopírovat, přejmenovávat a rušit
celé tabulky a vytvářet vztah Master-detail mezi tabulkami.
Poznámka: Komponenta tabulky se vždy odkazuje
na jednu databázovou tabulku. Pokud potřebujeme v jedné komponentě přistupovat
k více tabulkám, nebo pokud nás zajímá podmnožina řádků a sloupců z jedné
nebo více tabulek, pak místo komponenty tabulky můžeme použít komponentu
dotazu.
Nastavování komponenty tabulky
Následující kroky jsou obecné instrukce pro nastavování komponenty
tabulky při návrhu. Pro přizpůsobení vlastností podle požadavku naší aplikace
mohou být požadovány další kroky. K vytvoření komponenty tabulky:
-
Umístíme komponentu tabulky ze stránky Data Access
Palety komponent do Datového modulu nebo na formulář a nastavíme její vlastnost
Name
na unikátní hodnotu v naší aplikaci.
-
Nastavíme DatabaseName komponenty na jméno databáze,
ke které budeme přistupovat.
-
Nastavíme vlastnost TableName na jméno tabulky v databázi.
Pokud vlastnost DatabaseName je již specifikována, pak jméno tabulky
lze vybrat v rozbalovacím seznamu.
-
Umístíme komponentu Datového zdroje do Datového modulu nebo
na formulář a nastavíme její vlastnost DataSet na jméno komponenty
tabulky. Komponenta Datového zdroje je použita k předání výsledkové množiny
z tabulky do Datových ovladačů k zobrazení.
Pro zpřístupnění dat zaobalených komponentou tabulky:
-
Umístíme komponentu Datového zdroje ze stránky Data Access
Palety komponent do Datového modulu nebo na formulář a nastavíme její vlastnost
DataSet
na jméno komponenty tabulky.
-
Umístíme Datové ovladače, jako je TDBGrid na formulář
a nastavíme vlastnost DataSource ovladače na jméno komponenty Datového
zdroje umístěné v předchozím kroku.
-
Nastavíme vlastnost Active komponenty tabulky na true.
V tomto bodě se budeme zabývat:
Specifikování umístění tabulky
Vlastnost DatabaseName specifikuje, kde komponenta
tabulky hledá databázovou tabulku. Pro Paradox a dBASE, DatabaseName
může být přezdívka BDE nebo adresářová cesta. Pro tabulky SQL, DatabaseName
musí
být přezdívka BDE.
Výhodou používání přezdívek BDE ve všech případech je
to, že můžeme změnit Datový zdroj pro celou aplikaci jednoduchou změnou
definice přezdívky v Průzkumníku SQL.
K nastavení vlastnosti DatabaseName:
-
Nastavíme vlastnost Active na false (pokud
již není nastaveno).
-
Specifikujeme přezdívku BDE nebo adresářovou cestu ve vlastnosti
DatabaseName.
Tip: Pokud naše aplikace používá komponentu databáze
k řízení databázových transakcí, pak DatabaseName může být nastaveno
na lokální přezdívku definovanou pro komponentu databáze.
Specifikování jména tabulky
Vlastnost TableName specifikuje zpřístupňovanou tabulku
databáze v komponentě tabulky. Pro specifikaci tabulky provedeme tyto kroky:
-
Nastavíme vlastnost tabulky Active na false
(pokud již není nastaveno).
-
Nastavíme vlastnost DatabaseName na přezdívku BDE
nebo adresářovou cestu.
-
Nastavíme vlastnost TableName na zpřístupňovanou tabulku.
Při návrhu můžeme volit z přípustných jmen v rozbalovacím seznamu vlastnosti
TableName
v Inspektoru objektů. Za běhu musíme specifikovat přípustnou hodnotu v
kódu.
Po specifikaci přípustného jména tabulky můžeme nastavit
vlastnost komponenty
Active na true pro připojení k databázi,
otevření tabulky a zobrazení a editaci dat.
Za běhu, můžeme nastavit nebo změnit přiřazenou tabulku
ke komponentě tabulky:
-
Nastavením Active na false.
-
Přiřazením přípustného jména tabulky vlastnosti TableName.
Např. následující kód mění jméno tabulky pro komponentu tabulky
OrderOrCustTable
na základě jejího současného jména tabulky:
OrderOrCustTable->Active = false; // Uzavření
tabulky
if (OrderOrCustTable->TableName == "CUSTOMER.DB")
OrderOrCustTable->TableName = "ORDERS.DB";
else
OrderOrCustTable->TableName = "CUSTOMER.DB";
OrderOrCustTable->Active = true; // Opětovné
otevření nové tabulky
Specifikování
typu tabulky pro lokální tabulky
Pokud aplikace přistupuje k tabulkám Paradoxu, dBASE, FoxPro
nebo textovým tabulkám ASCII, pak BDE používá vlastnost TableType
k určení typu tabulky (její očekávané struktury). TableType není
používáno, když aplikace přistupuje k SQL tabulce na databázovém serveru.
Implicitně TableType je nastaveno na ttDefault.
Když
TableType je ttDefault, pak BDE určuje typ tabulky podle
přípony souboru tabulky. Následující tabulka sumarizuje přípony jmen souborů
rozeznávaných BDE a určení typu tabulky:
Přípona |
Typ tabulky |
Soubor bez přípony |
Paradox.DB |
.DB |
Paradox |
.DBF |
dBASE |
.TXT |
ASCII text |
Pokud naše lokální tabulky používají přípony souborů podle
předchozí tabulky, pak můžeme nastavit TableName na ttDefault.
Jinak, naše aplikace musí nastavit TableType k indikaci správného
typu tabulky (podle následující tabulky).
Hodnota TableType |
Typ tabulky |
ttDefault |
Typ je určen automaticky BDE |
ttParadox |
Paradox |
ttDBase |
dBASE |
ttFoxPro |
FoxPro |
ttASCII |
ASCII text |
Otevírání a uzavírání tabulky
Pro zobrazování a editování dat tabulky v Datových ovladačích
jako je TDBGrid, tabulku otevřeme. Jsou dva způsoby otevírání tabulek.
Můžeme nastavit její vlastnost Active na true nebo můžeme
volat metodu Open. Otevřením tabulku uvedeme do stavu dsBrowse
a všechny aktivní ovladače přiřazené k Datovému zdroji tabulky zobrazí
data.
Při ukončování zobrazování a editace dat nebo ke změně
základních vlastností komponenty tabulky (např. DatabaseName, TableName
a TableType), nejprve odešleme nebo zrušíme zatím neprovedené změny.
Pokud jsou povoleny odložené aktualizace, pak voláme ApplyUpdates
k zápisu neprovedených změn do databáze. Nakonec tabulku uzavřeme.
Jsou dva způsoby uzavření tabulky. Můžeme nastavit její
vlastnost Active na false nebo můžeme volat metodu Close.
Uzavřením tabulky uvedeme tabulku do stavu dsInactive. Aktivní ovladače
přiřazené k Datovému zdroji tabulky jsou vyprázdněny.
Řízení čtecího/zápisového
přístupu k tabulce
Implicitně, když tabulka je otevřena, je požadován čtecí
a zápisový přístup k připojené databázové tabulce. V závislosti na charakteristikách
připojené databázové tabulky, požadované zápisové privilegium nemusí být
přiděleno (např. když je požadován přístup k SQL tabulce na vzdáleném serveru
a server omezí přístup k tabulce pouze na čtení).
Jsou tři vlastnosti komponenty tabulky, které ovlivňují
čtecí a zápisový přístup k tabulce: CanModify, ReadOnly a
Exclusive.
CanModify je vlastnost, která určuje zda komponenta
tabulky má čtecí a zápisový přístup do připojené databázové tabulky. Po
otevření tabulky za běhu, naše aplikace může testovat CanModify
k zjištění zda tabulka má zápisový přístup. Pokud CanModify je false,
pak aplikace nemůže zapisovat do databáze. Když CanModify je true,
pak naše aplikace může do databáze zapisovat (pokud ReadOnly tabulky
je false).
ReadOnly určuje, zda uživatel může editovat data.
Když ReadOnly je false (implicitně), pak uživatel může prohlížet
i editovat data. K omezení uživatele na prohlížení dat, nastavíme ReadOnly
na true před otevřením tabulky.
Exclusive řídí zda aplikace získá výhradní přístup
k tabulce Paradoxu, dBASE nebo FoxPro. K získání výhradního přístupu pro
tyto typy tabulek nastavíme vlastnost Exclusive komponenty tabulky
na true před otevřením tabulky. Po úspěšném otevření tabulky s výhradním
přístupem, ostatní aplikace nemohou číst nebo zapisovat data tabulky. Požadavek
na výhradní přístup není akceptován, pokud při pokusu o otevření tabulky,
je tabulka již používána.
Následující příkazy otevírají tabulku pro výhradní přístup:
CustomersTable->Exclusive = true; // Nastavení
požadavku na výhradní přístup
CustomersTable->Active = true;
// Otevření tabulky
Poznámka: Můžeme se pokusit nastavit Exclusive
pro SQL tabulku, ale některé servery nemají podporu úrovně výlučného uzamčení
tabulky. Jiné mohou přidělit výlučný zámek, ale umožní ostatním aplikacím
číst data z tabulky.
Vyhledávání záznamů
Záznamy v tabulce lze vyhledávat různými způsoby. Nejpružnější
a preferovaný způsob vyhledávání záznamu, je použití obecných metod Locate
a Lookup. Tyto metody umožňují prohledávat libovolný typ položky
v libovolné tabulce a to bez ohledu na to, zda jsou indexované nebo klíčované.
Locate hledá první řádek vyhovující specifikovaným
kritériím a přesouvá kurzor na tento řádek. Lookup vrací hodnoty
z prvního řádku vyhovujícího specifikovaným kritériím, ale nepřesouvá kurzor
na tento řádek.
Locate a Lookup můžeme použít s libovolným
typem Datové množiny (nejen s TTable). Úplný popis najdeme v kapitole
Seznámení
s datovými množinami.
Komponenty tabulek také podporují metody Goto
a Find. Tyto metody jsou již zastaralé a je vhodné místo nich používat
ve svých aplikacích Lookup a Locate. Pokud chceme zvýšit
výkonnost existujících aplikací (které je používají), pak aplikaci můžeme
převést na používání nových metod.
S vyhledávání záznamů se seznámíme v těchto bodech:
Vyhledávání záznamů
na základě indexovaných položek
Komponenty tabulek podporují množinu vyhledávacích metod
Goto
pro zachování zpětné kompatibility. Metody Goto umožňují vyhledání
záznamu na základě indexovaných položek a udělání prvního nalezeného záznamu
novým současným záznamem.
Pro tabulky Paradoxu a dBASE, klíč musí být vždy indexem,
který můžeme specifikovat ve vlastnosti IndexName komponenty tabulky.
Pro SQL tabulky, klíč může být také seznam položek specifikovaných ve vlastnosti
IndexFieldNames.
Můžeme také specifikovat položkový seznam pro tabulky Paradoxu a dBASE,
ale položky musí mít na sobě definované indexy.
Tip: K vyhledávání na neindexovaných položkách
tabulky Paradoxu nebo dBASE, použijeme Locate. Alternativně, můžeme
k hledání na neindexovaných položkách v tabulkách Paradoxu a dBASE použít
komponentu
TQuery a příkaz SELECT.
Následující tabulka uvádí šest metod svázaných s Goto
a Find, které aplikace může použít k vyhledávání záznamů:
Metoda |
Popis |
EditKey |
Chrání současný obsah vyrovnávací paměti vyhledávacího
klíče a uvádí tabulku do stavu dsSetKey, aby aplikace mohla modifikovat
existující vyhledávací kritéria před provedením vyhledávání. |
FindKey |
Kombinuje metody SetKey a GotoKey do jedné
metody. |
FindNearest |
Kombinuje metody SetKey a GotoNearest do
jedné metody. |
GotoKey |
Hledá první záznam v datové množině, který přesně odpovídá
vyhledávacímu kritériu a přesouvá kurzor na tento záznam, pokud je nalezen. |
GotoNearest |
Vyhledávání na řetězcové položce na neúplnou shodu hodnoty
klíče a přesouvá kurzor na tento záznam. |
SetKey |
Vyprazdňuje vyrovnávací paměť vyhledávacího klíče a uvádí
tabulku do stavu dsSetKey, aby aplikace mohla specifikovat nová
vyhledávací kritéria před provedením vyhledávání. |
GotoKey a FindKey jsou logické funkce, které
v případě úspěchu, přesouvají kurzor na nalezený záznam a vracejí true.
Pokud hledání je neúspěšné, pak kurzor není přesunut a funkce vrací false.
GotoNearest a FindNearest vždy mění pozici
kurzoru, a to na první přesně odpovídající záznam (je-li nalezen) nebo
na první záznam, který je větší než specifikovaná vyhledávací kritéria.
Provedení vyhledávání metodou Goto
K provedení vyhledávání pomocí metody Goto musíme
provést tyto obecné kroky:
-
V případě potřeby ve vlastnosti IndexName specifikujeme
index použitý při vyhledávání. Pro SQL tabulky seznam položek použitých
jako klíč nalezneme v IndexFieldNames. Pokud použijeme primární
index tabulky není nutno nastavovat tyto vlastnosti.
-
Otevřeme tabulku.
-
Pomocí SetKey uvedeme tabulku do stavu dsSetKey.
-
Ve vlastnosti Fields specifikujeme hodnotu (hodnoty)
k vyhledávání.
Fields je seznam řetězců, který je indexován pořadovými
čísly odpovídající sloupcům (jsou číslovány od 0).
-
Pomocí GotoKey nebo GotoNearest hledáme a přesuneme
se na první vyhovující záznam.
Např. následující kód, spojený s obsluhou stisku tlačítka,
přemístí kurzor na první záznam obsahující hodnotu položky, která se přesně
shoduje s textem v editačním ovladači na formuláři:
void __fastcall TSearchDemo::SearchExactClick(TObject
*Sender)
{
Table1->SetKey();
Table1->Fields[0]->AsString = Edit1->Text;
if (!Table1->GotoKey())
ShowMessage("Záznam nenalezen");
}
GotoNearest je podobné. Vyhledává nejbližší shodu
v částečné hodnotě položky. Může být použita pouze na řetězcových položkách.
Např.
Table1->SetKey();
Table1->Fields[0]->AsString = "Sm";
Table1->GotoNearest();
Pokud existuje záznam s "Sm" jako prvními dvěmi znaky,
pak kurzor je umístěn na tento záznam. Jinak, pozice kurzoru se nemění
a GotoNearest vrací false.
Provedení vyhledávání metodou Find
K provedení vyhledávání metodou Find provedeme
následující kroky:
-
V případě potřeby ve vlastnosti IndexName specifikujeme
index použitý při vyhledávání. Pro SQL tabulky seznam položek použitých
jako klíč nalezneme v IndexFieldNames. Pokud použijeme primární
index tabulky není nutno tyto vlastnosti nastavovat.
-
Otevřeme tabulku.
-
Pomocí FindKey nebo FindNearest hledáme a přesuneme
se na první nebo nejbližší záznam. Obě metody přebírají jeden parametr
(čárkami oddělený seznam hodnot položky), kde každá hodnota odpovídá indexovaným
sloupcům v připojené tabulce.
Poznámka: FindNearest můžeme používat pouze
na řetězcové položky.
Specifikování
současného záznamu po úspěšném vyhledávání
Implicitně, úspěšné vyhledávání umisťuje kurzor na první
záznam vyhovující vyhledávacím kritériím. Pokud požadujeme, můžeme nastavit
vlastnost tabulky
KeyExclusive na true k umístění kurzoru
na následující záznam za prvním vyhovujícím záznamem. Implicitně, KeyExclusive
je false, což znamená, že kurzor je umístěn na první vyhovující
záznam.
Vyhledávání na částečných
klíčích
Pokud tabulka má více než jeden sloupec klíče a chceme vyhledávat
hodnoty na podmnožině těchto klíčů, pak nastavíme KeyFieldCount
na počet sloupců, které budeme prohledávat. Např. pokud tabulka má třísloupcový
primární klíč a chceme vyhledávat hodnoty pouze v prvním sloupci, pak nastavíme
KeyFieldCount
na 1.
Pro tabulky s vícesloupcovými klíči, můžeme vyhledávat
hodnoty pouze v sousedních sloupcích klíče, počínaje od prvního. Např.
pro třísloupcový klíč můžeme vyhledávat hodnoty v prvním sloupci, v prvním
a druhém sloupci nebo ve všech třech sloupcích, ale ne např. v prvním a
třetím sloupci.
Vyhledávání na alternativních
indexech
Pokud chceme vyhledávat na jiných indexech než na primárním
klíči tabulky, pak musíme specifikovat jméno použitého indexu ve vlastnosti
IndexName
tabulky. Tabulka musí být uzavřena při specifikování hodnoty pro IndexName.
Např. pokud tabulka CUSTOMER má sekundární index nazvaný CityIndex,
na kterém chceme vyhledávat hodnoty, pak musíme nastavit hodnotu vlastnosti
IndexName
tabulky na "CityIndex":
Customer->Close();
Customer->IndexName = "CityIndex";
Customer->Open();
Customer->SetKey();
Customer->FieldValues["City"] = Edit1->Text;
Customer->GotoNearest();
Místo specifikace jména indexu, můžeme ve vlastnosti
IndexFieldNames
uvést seznam používaných položek jako klíč. Pro tabulky Paradoxu a dBASE,
položky seznamu musí být indexovány nebo při provádění hledání je generována
výjimka. Pro SQL tabulky, položky v seznamu nemusí být indexovány.
Pokaždé, když voláme SetKey nebo FindKey,
pak jsou vyprázdněny všechny předchozí hodnoty ve vlastnosti Fields.
Pokud chceme zopakovat vyhledávání pomocí dříve nastavených položek, nebo
chceme něco přidat k položkám použitým k vyhledávání, pak voláme EditKey
místo SetKey a FindKey. Např. pokud index CityIndex
obsahuje položky City i Country, pak k nalezení záznamu se
specifikovaným jménem firmy ve specifikovaným městě použijeme následující
kód:
Customer->EditKey();
Customer->FieldValues["Country"] = Variant(Edit2->Text);
Customer->GotoNearest();
Řazení záznamů
Index určuje zobrazovací pořadí záznamů v tabulce. Obecně,
záznamy jsou zobrazovány ve vzestupném pořadí primárního indexu (pro tabulky
dBASE bez primárního indexu, pořadí je založeno na fyzickém pořadí záznamu).
Toto implicitní pořadí nevyžaduje žádnou intervenci aplikace. Pokud požadujeme
jiné pořadí, pak musíme specifikovat:
-
Alternativní index
-
Seznam sloupců pro řazení (pouze pro SQL)
Specifikace jiného řadícího pořadí vyžaduje následující kroky:
-
Určení dostupných indexů.
-
Specifikování alternativního indexu nebo seznamu sloupců
k používání.
V této části se budeme zabývat:
Získávání seznamu
dostupných sloupců pomocí GetIndexNames
Za běhu, naše aplikace může volat metodu GetIndexNames
k získání seznamu dostupných indexů pro tabulku. GetIndexNames vrací
seznam řetězců obsahující přípustná jména indexů. Např. následující kód
určuje seznam indexů dostupných Datovou množinou CustomerTable:
TStringList *IndexList = new TStringList();
CustomersTable->GetIndexNames(IndexList);
Poznámka: Pro tabulky Paradoxu, primární index
je nepojmenovaný a tedy není vracen GetIndexNames. Pokud se potřebujeme
vrátit k používání primárního indexu tabulky Paradoxu po používání alternativního
indexu, nastavíme vlastnost IndexName tabulky na prázdný řetězec.
Specifikace
alternativního indexu pomocí IndexName
Pro specifikaci, že tabulka bude řazena použitím alternativního
indexu, specifikujeme jméno indexu ve vlastnosti IndexName komponenty
tabulky. Během návrhu můžeme specifikovat toto jméno v Inspektoru objektů
a za běhu můžeme k vlastnosti přistupovat našim kódem. Např. následující
kód nastaví index pro CustomersTable na CustDescending:
CustomersTable->IndexName = "CustDescending";
Pro tabulky dBASE, které používají ne-vytvářené indexy,
nastavíme vlastnost
IndexFiles na jméno používaného indexového souboru
před nastavením
IndexName. Během návrhu můžeme kliknout na tlačítko
se třemi tečkami u vlastnosti
IndexFiles v Inspektoru objektů k
vyvolání Editoru indexových souborů. Uvidíme seznam dostupných indexových
souborů, zvolíme
Add a vybereme jeden nebo více indexových souborů
ze seznamu. Indexový soubor dBASE může obsahovat vícenásobné indexy. K
výběru indexu z indexového souboru, vybereme jméno indexu z rozbalovacího
seznamu IndexName v Inspektoru objektů. Můžeme také specifikovat
více indexů v souboru zadáním požadovaných jmen indexů (oddělovaných středníky).
Můžeme také nastavit IndexFiles a IndexName
za běhu. Např. následující kód nastavuje IndexFiles pro tabulku
AnimalsTable
na ANIMALS.MDX a pak nastavuje IndexName na NAME:
AnimalsTable->IndexFiles->Add("ANIMALS.MDX");
AnimalsTable->IndexName = "NAME";
Specifikace řadícího
pořadí pro tabulky SQL
V SQL řadící pořadí řádků je určeno klauzulí ORDER BY. Můžeme
specifikovat index použitý touto klauzulí pomocí:
-
vlastnosti IndexName ke specifikaci existujícího indexu
-
vlastnosti IndexFieldNames k vytvoření pseudoindexu
založeného na podmnožině sloupců v tabulce
IndexName a IndexFieldNames se vzájemně vylučují.
Nastavením jedné vlastnosti zrušíme nastavenou hodnotu v druhé vlastnosti.
IndexFieldNames je vlastnost seznamu řetězců.
Ke specifikaci řadícího pořadí, zapíšeme seznam všech jmen sloupců použitých
k určení řazení do vlastnosti a jména oddělujeme středníky. Řazení je pouze
ve vzestupném pořadí. Rozlišování velikosti písmen při řazení závisí na
schopnostech našeho serveru. Více informací nalezneme v dokumentaci serveru.
Následující kód nastavuje řadící pořadí pro PhoneTable
na LastName a potom na FirstName:
PhoneTable->IndexFieldNames = "LastName;FirstName";
Poznámka: Pokud použijeme IndexFieldNames
pro tabulky Paradoxu a dBASE, pak C++ Builder se pokusí nalézt index používající
námi specifikovaný sloupec. Pokud index není nalezen, pak je generována
výjimka.
Zkoumání seznamu položek
na indexy
Když naše aplikace používá za běhu indexy, pak může testovat:
-
Vlastnost IndexFieldCount k určení počtu sloupců v
indexu
-
Vlastnost IndexFields k zjištění seznamu jmen sloupců
tvořících index
IndexFields je seznam řetězců obsahující jména sloupců
pro index. Následující kód ukazuje jak můžeme použít IndexFieldCount
a IndexFields k procházení seznamem jmen sloupců v aplikaci:
AnsiString ListOfIndexFields[20];
for (int i = 0; i < CustomersTable->IndexFieldCount;
i++)
ListOfIndexFields[i] = CustomersTable->IndexFields[i]->FieldName;
Poznámka: IndexFieldCount není přípustný
pro tabulky otevřené na výrazových indexech.
Práce s podmnožinou dat
Vytvořené tabulky mohou být rozsáhlé a aplikace může požadovat
omezení počtu řádků se kterými pracuje. Pro komponenty tabulek jsou dvě
možnosti omezení záznamů používaných aplikací: rozsahy a filtry. Filtry
mohou být používány s libovolným typem datových množin, včetně komponent
TTable,
TQuery
a TStoredProc. Protože jsou aplikovatelné na všechny datové množiny,
najdeme jejich úplný popis v Seznámení s datovými množinami.
Rozsahy jsou aplikovatelné pouze na komponenty TTable.
I když se podobají, rozsahy a filtry mají různé použití. V této části jsou
následující body:
Seznámení s rozdíly
mezi rozsahy a filtry
Rozsahy i filtry omezují viditelnost záznamů v tabulce na
podmnožinu všech dostupných záznamů, ale způsob provedení se liší. Rozsah
je množina souvisle indexovaných záznamů, které se nacházejí mezi specifikovanými
hodnotami mezí. Např. v databázi zaměstnanců indexované jmény, můžeme aplikovat
rozsah k zobrazení všech zaměstnanců jejichž jména jsou větší než "Jones"
a menší než "Smith". Protože rozsahy závisí na indexech, rozsahy mohou
být aplikovány pouze na indexované tabulky Paradoxu a dBASE (pro SQL tabulky,
rozsahy mohou být aplikovány na libovolné položky v seznamu vlastnosti
IndexFieldNames).
Rozsahy mohou být řazeny pouze na základě existujících indexů.
Filtr, na druhé straně, je libovolná množina souvisejících
nebo nesouvisejících záznamů, které sdílejí specifikované datové prvky
a to bez ohledu na indexaci. Např. máme filtr v databázi zaměstnanců, který
zobrazuje všechny zaměstnance, které žijí v Kalifornii a během pěti nebo
více let pracovali v našem podniku. I když filtry mohou používat indexy,
filtry na nich nejsou závislé. Filtry jsou aplikovány, záznam po záznamu,
jak aplikace prochází datovou množinou.
Obecně filtry jsou flexibilnější než rozsahy. Rozsahy
ale mohou být efektivnější, když datová množina je značně velká a záznamy
nás zajímající, jsou seskupeny do skupin sousedních indexů. Pro značně
rozsáhlé datové množiny je ale mnohem výhodnější použít komponentu dotazu
k výběru dat pro zobrazení i editaci.
Vytváření a aplikování
nového rozsahu
Proces vytváření a aplikování rozsahu vyžaduje tyto obecné
kroky:
-
Uvedeme datovou množinu do stavu dsSetKey a nastavíme
počáteční hodnotu indexu pro rozsah.
-
Nastavíme koncovou hodnotu indexu pro rozsah.
-
Aplikujeme rozsah na datovou množinu.
Nastavování počátku rozsahu
Voláním SetRangeStart uvedeme datovou množinu
do stavu dsSetKey a zahájíme vytváření seznamu počátečních hodnot
pro rozsah. Po volání SetRangeStart následující řada přiřazení vlastnosti
Fields
jsou chápány jako hodnoty počátečních indexů k použití při aplikování rozsahu.
Když používáme tabulky Paradoxu nebo dBASE, pak specifikované položky musí
být indexované položky.
Např. předpokládejme, že naše aplikace používá komponentu
tabulky nazvanou
Customers, spojenou s tabulkou CUSTOMER a že máme
vytvořené trvalé položkové komponenty pro všechny položky v datové množině
Customers.
CUSTOMER je indexován na svém prvním sloupci (CustNo). Formulář
aplikace má dvě editační komponenty nazvané StartVal a
EndVal
pro specifikaci počáteční a koncové hodnoty rozsahu. Následující kód může
být použit k vytvoření a aplikování rozsahu:
Customers->SetRangeStart();
Customers->FieldValues["CustNo"] = StrToInt(StartVal->Text);
Customers->SetRangeEnd();
if (!EndVal->Text.IsEmpty())
Customers->FieldValues["CustNo"] =
StrToInt(EndVal->Text);
Customers->ApplyRange();
Tento kód testuje zda text zadaný v EndVal není
prázdný před přiřazením nějaké hodnoty Fields. Pokud text zadaný
pro StartVal je prázdný, pak všechny záznamy od začátku tabulky
jsou vloženy do rozsahu, neboť všechny hodnoty jsou větší než null.
Ale pokud do EndVal je přiřazen prázdný text, pak do rozsahu není
vložen žádný záznam, neboť žádný není menší než null.
Pro vícesloupcové indexy můžeme specifikovat počáteční
hodnotu pro všechny nebo některé položky v indexu. Pokud nepřiřadíme hodnotu
pro položku použitou v indexu, pak je použita hodnota null při aplikování
rozsahu. Pokud nastavíme více hodnot než je hodnot v indexu, pak nadbytečné
položky jsou při výpočtu rozsahu ignorovány.
K ukončení specifikace počátku rozsahu, voláme SetRangeEnd
nebo
ApplyRange. Tyto metody budou popsány dále.
Tip: K zahájení od začátku datové množiny,
vynecháme volání
SetRangeStart.
Můžeme také nastavit počáteční (a koncové) hodnoty pro
rozsah pomocí volání SetRange (viz dále).
Nastavování konce rozsahu
Volání SetRangeEnd uvádí datovou množinu do stavu
dsSetKey
a zahajuje vytváření seznamu koncových hodnot pro rozsah. Po volání SetRangeEnd
následuje řada přiřazení do vlastnosti Fields chápaných jako koncové
hodnoty použitých indexů při aplikování rozsahu. Specifikované položky
musí být pro tabulky Paradoxu a dBASE indexovanými položkami.
Poznámka: Vždy specifikujte koncovou hodnotu
pro rozsah, i když rozsah chceme končit posledním záznamem v datové množině.
Pokud nedodáme koncovou hodnotu, pak C++ Builder předpokládá, že koncová
hodnota rozsahu je null. Rozsah s koncovou hodnotou rovnou null
je vždy prázdný.
Koncovou hodnotu nejsnadněji přiřadíme voláním metody
FieldByName.
Např.
Table1->SetRangeStart();
Table1->FieldByName("LastName")->Value =
Edit1->Text;
Table1->SetRangeEnd();
Table1->FieldByName("LastName")->Value =
Edit2->Text;
Table1->ApplyRange();
Pro vícesloupcové indexy, můžeme specifikovat počáteční
hodnotu pro všechny nebo pro některé položky v indexu. Pokud nezadáme hodnotu
pro některou položku použitou v indexu, pak se zde při aplikování rozsahu
předpokládá hodnota null. Pokud nastavíme více hodnot než je položek
v indexu, pak je generována výjimka.
Po dokončení specifikace konce rozsahu voláme ApplyRange.
Poznámka: Koncovou (a také počáteční) hodnotu
pro rozsah můžeme také nastavit voláním SetRange.
Nastavování počáteční a koncové hodnoty rozsahu
Místo odděleného volání SetRangeStart a SetRangeEnd
ke specifikací hranic rozsahu, můžeme volat SetRange k uvedení datové
množiny do stavu dsSetKey a nastavení počáteční a koncové hodnoty
rozsahu v jediném volání. SetRange přebírá dva parametry konstantních
polí: množina počátečních hodnot a množina koncových hodnot. Např. následující
příkazy zřizují rozsah pro dvousloupcový index:
TVarRec StartVals[2];
TVarRec EndVals[2];
StartVals[0] = Edit1->Text;
StartVals[1] = Edit2->Text;
EndVals[0] = Edit3->Text;
EndVals[1] = Edit4->Text;
Table1->SetRange(StartVals, 1, EndVals, 1);
Pro vícesloupcové indexy, můžeme specifikovat počáteční
a koncovou hodnotu pro všechny nebo pro některé položky v indexu. Pokud
nezadáme hodnotu pro některou položku použitou v indexu, pak se zde předpokládá
hodnota
null při aplikování rozsahu. K vynechání hodnoty pro první
položku v indexu a specifikaci hodnot pro následující položky, předáme
pro vynechanou položku hodnotu null. Pokud nastavíme více hodnot
než je položek v indexu, pak nadbytečné položky jsou ignorovány.
Poznámka: Vždy specifikujte koncovou hodnotu
pro rozsah, i když rozsah chceme končit posledním záznamem v datové množině.
Pokud nedodáme koncovou hodnotu, pak C++ Builder předpokládá, že koncová
hodnota rozsahu je null. Rozsah s koncovou hodnotou rovnou null
je vždy prázdný, protože počáteční hodnota je větší nebo rovna koncové
hodnotě.
Specifikace rozsahu na základě částečných klíčů
Pokud klíč je tvořen jednou nebo více řetězcovými položkami,
pak metoda
SetRange podporuje částečné klíče. Např. pokud index
je založen na sloupcích LastName a FirstName, pak následující
specifikace rozsahu je přípustná:
Table1->SetRangeStart();
Table1->FieldValues["LastName"] = "Smith";
Table1->SetRangeEnd();
Table1->FieldValues["LastName"] = "Zzzzzz";
Table1->ApplyRange();
Tento kód zahrnuje všechny záznamy v rozsahu kde LastName
je větší nebo rovno "Smith". Hodnota specifikace může také být:
Table1->FieldValues["LastName"] = "Sm";
Tento příkaz zahrnuje záznamy, které mají LastName
větší nebo rovno "Sm. Následující příkaz vkládá záznamy s LastName
větším nebo rovno "Smith" a FirstName je větší nebo rovno
"J":
Table1->FieldValues["LastName"] = "Smith";
Table1->FieldValues["FirstName"] = "J";
Zahrnování nebo vylučování záznamů odpovídajících
hraničním hodnotám
Implicitně rozsah zahrnuje všechny záznamy, které jsou
větší nebo rovny specifikované počáteční hodnotě a menší nebo rovny specifikované
koncové hodnotě. Toto chování je řízeno vlastností KeyExclusive.
KeyExclusive
má implicitně hodnotu false. Pokud to požadujeme, pak můžeme nastavit
KeyExclusive
pro komponentu tabulky na true k vyloučení záznamu odpovídajícímu
konečné hodnotě. Např.
Table1->SetRangeStart();
Table1->KeyExclusive = true;
Table1->FieldValues["LastName"] = "Smith";
Table1->SetRangeEnd();
Table1->FieldValues["LastName"] = "Tyler";
Table1->ApplyRange();
Tento kód vkládá všechny záznamy v rozsahu kde LastName
je větší nebo rovno "Smith" a menší než "Tyler".
Aplikování rozsahu
Metoda SetRange zřizuje hraniční podmínky pro
rozsah, ale neuvádí je v činnost. Aby se rozsah projevil musíme volat ApplyRange.
ApplyRange
bezprostředně omezuje uživatelův pohled a přístup k datům na specifikovanou
podmnožinu datové množiny.
Zrušení rozsahu
Metoda CancelRange ukončuje rozsah a obnovuje
přístup k úplné datové množině. I když zrušením rozsahu obnovíme přístup
ke všem záznamům v datové množině, hraniční podmínky pro rozsah jsou stále
dostupné a rozsah můžeme kdykoli obnovit. Meze jsou chráněny dokud nezadáme
nové meze nebo existující meze nemodifikujeme. Např. následující kód je
přípustný:
...
Table1->CancelRange();
...
// později aplikujeme stejný rozsah znovu.
Není nutno volat SetRangeStart ...
Table1->ApplyRange();
...
Modifikování rozsahu
Dvě funkce povolují modifikovat existující hraniční podmínky
pro rozsah:
EditRangeStart pro změnu počáteční hodnoty rozsahu a
EditRangeEnd
pro změnu koncové hodnoty rozsahu. Proces editace a aplikování rozsahu
vyžaduje obecně tyto kroky:
-
Uvedeme datovou množinu do stavu dsSetKey a modifikujeme
počáteční hodnotu indexu pro rozsah.
-
Modifikujeme koncovou hodnotu pro rozsah.
-
Aplikujeme rozsah na datovou množinu.
Můžeme modifikovat počáteční nebo koncové hodnoty rozsahu
nebo můžeme modifikovat obě hraniční podmínky. Pokud modifikujeme hraniční
podmínky pro rozsah, který je právě aplikován na datovou množinu, pak změny
se neprojeví dokud znova nevoláme ApplyRange.
Editace počátku rozsahu
Voláním EditRangeStart uvedeme datovou množinu
do stavu dsSetKey a začneme modifikování současného seznamu počátečních
hodnot pro rozsah. Přiřazení do vlastnosti Fields následující po
volání EditRangeStart přepisují současné počáteční hodnoty rozsahu.
Při používání Paradoxu nebo dBASE, položky musí být indexovanými položkami.
Tip: Pokud vytváříme rozsah založený na částečných
klíčích, pak můžeme použít EditRangeStart k rozšíření počátečních
hodnot pro rozsah.
Editace konce rozsahu
Voláním EditRangeEnd uvedeme datovou množinu do
stavu dsSetKey a začneme modifikování současného seznamu koncových
hodnot pro rozsah. Přiřazení do vlastnosti Fields následující po
volání
EditRangeEnd přepisují současné koncové hodnoty rozsahu.
Při používání Paradoxu nebo dBASE položky musí být indexovanými položkami.
Poznámka: Vždy specifikujte koncovou hodnotu
pro rozsah, i když rozsah chceme končit posledním záznamem v datové množině.
Pokud nedodáme koncovou hodnotu, pak C++ Builder předpokládá, že koncová
hodnota rozsahu je null. Rozsah s koncovou hodnotou rovnou null
je vždy prázdný, protože počáteční hodnota je větší nebo rovna koncové
hodnotě.
Zrušení všech záznamů v tabulce
Pro zrušení všech řádků dat v tabulce voláme metodu EmptyTable
komponenty tabulky. Pro SQL tabulky je tato metoda úspěšná pouze tehdy,
pokud k tabulce máme privilegium DELETE. Např. následující příkaz zruší
všechny záznamy v datové množině:
PhoneTable->EmptyTable();
Pozor: Zrušení dat pomocí EmptyTable
nelze odvolat.
Zrušení tabulky
Při návrhu, k zrušení tabulky v databázi, klikneme pravým
tlačítkem na komponentě tabulky a v zobrazené místní nabídce zvolíme Delete
Table. Tato volba v nabídce je dostupná pouze pokud komponenta tabulky
reprezentuje existující databázovou tabulku (vlastnosti DatabaseName
a TableName specifikují existující tabulku).
Pro zrušení tabulky za běhu, voláme metodu DeleteTable
komponenty tabulky. Např. následující příkaz odstraňuje tabulku připojené
datové množiny:
CustomersTable->DeleteTable();
Pozor: Když zrušíme tabulku pomocí DeleteTable,
pak tabulka a všechna její data jsou ztracena.
Přejmenování tabulky
K přejmenování tabulky Paradoxu a dBASE při návrhu, v místní
nabídce komponenty tabulky zvolíme Rename Table. Můžeme také přejmenovat
tabulku přepsáním vlastnosti TableName existující tabulky v Inspektoru
objektů. Když změníme vlastnost TableName, pak v zobrazeném dialogovém
okně jsme dotázáni, zda chceme tabulku přejmenovat. Lze zde zvolit přejmenování
tabulky, nebo zrušení operace měnící vlastnost TableName (např.
pro vytvoření nové tabulky) beze změny jména tabulky reprezentované starou
hodnotou TableName.
Pro přejmenování tabulky Paradoxu nebo dBASE za běhu,
voláme metodu
RenameTable komponenty tabulky. Např. následující
příkaz přejmenovává tabulku Customer na CustInfo:
Customer->RenameTable("CustInfo");
Vytváření tabulky
Nové tabulky databáze lze vytvářet při návrhu nebo za běhu.
Příkaz Create Table (při návrhu) nebo metoda CreateTable
(za běhu) umožňuje vytvářet tabulky bez nutnosti znát SQL. Vyžaduje to
ale dobrou znalost vlastností, událostí a metod komponent datových množin.
Nejprve je nutno takto definovat vytvářenou tabulku:
-
Nastavíme vlastnost DatabaseName na databázi, která
novou tabulku bude obsahovat.
-
Nastavíme vlastnost TableType na požadovaný typ tabulky.
Pro tabulky Paradoxu, dBASE nebo ASCII nastavíme TableType na ttParadox,
ttDBase
nebo ttASCII. Pro všechny ostatní tabulky nastavíme
TableTypes
na ttDefault.
-
Nastavíme vlastnost TableName na jméno nové tabulky.
Pokud hodnota vlastnosti TableType je ttParadox nebo ttDBase,
pak není nutno specifikovat příponu.
-
Přidáme definice položek popisující položky v nové tabulce.
Při návrhu můžeme přidávat definice položek dvojitým kliknutím na vlastnosti
FieldDefs
v Inspektoru objektů k zobrazení Editoru. Tento editor použijeme k přidávání,
odstraňování nebo změnu vlastností definic položek. Za běhu vyčistíme všechny
existující definice položek a potom použijeme metodu AddFieldDef
pro přidání každé nové definice položky. Pro každou novou definici položky,
nastavíme vlastnosti objektu TFieldDef na specifikaci požadovaných
atributů položky.
-
Volitelně, přidáme definice indexů popisující indexy nové
tabulky. Při návrhu můžeme přidat definici indexu dvojitým kliknutím na
vlastnosti IndexDefs v Inspektoru objektů k zobrazení editoru. Tento
editor použijeme k přidávání, odstraňování nebo modifikování vlastností
definicí indexů. Za běhu, vyprázdníme všechny existující definice indexů,
a pak použijeme metodu AddIndexDef pro každou novou definici indexu.
Pro každou novou definici indexu, nastavíme vlastnosti objektu TIndexDef
na specifikaci požadovaných atributů indexu.
Poznámka: Při návrhu, můžeme předzavést definice
položek a definice indexů existující tabulky ve vlastnostech FieldDefs
a IndexDefs. Nastavíme vlastnosti DatabaseName a TableName
na specifikaci existující tabulky. V místní nabídce komponenty tabulky
zvolíme Update Table Definition. To automaticky nastavuje hodnoty
vlastností FieldDefs a IndexDefs na popis položek a indexů
existující tabulky. Dále nastavíme
DatabaseName a TableName
na specifikaci vytvářené tabulky, a zrušíme všechny dotazy na přejmenování
existující tabulky. Pokud chceme uložit tyto definice s komponentou tabulky
(např. pokud naše aplikace je pak použije k vytvoření tabulek na systému
uživatele), pak nastavíme vlastnost
StoreDefs na true.
Když již máme tabulku úplně popsanou, pak ji můžeme vytvořit.
Při návrhu v místní nabídce komponenty tabulky zvolíme Create Table.
Za běhu voláme metodu CreateTable pro generování specifikované tabulky.
Varování: Pokud vytváříme tabulku, která duplikuje
jméno existující tabulky, pak existující tabulka a všechna její data jsou
přepsána nově vytvořenou tabulkou. Starou tabulku a její data nelze obnovit.
Následující kód vytváří novou tabulku za běhu a přiřazuje
ji k přezdívce BCDEMOS. Před vytvořením nové tabulky ověříme zda její jméno
se neshoduje se jménem již existující tabulky.
TTable *NewTable = new TTable(Form1);
NewTable->Active = false;
NewTable->DatabaseName = "BCDEMOS";
NewTable->TableName = Edit1->Text;
NewTable->TableType = ttDefault;
NewTable->FieldDefs->Clear();
TFieldDef *NewField=NewTable->FieldDefs->AddFieldDef();//definování
1.položky
NewField->DataType = ftInteger;
NewField->Name = Edit2->Text;
NewField = NewTable->FieldDefs->AddFieldDef();
// definování druhé položky
NewField->DataType = ftString;
NewField->Size = StrToInt(Edit3->Text);
NewField->Name = Edit4->Text;
NewTable->IndexDefs->Clear();
TIndexDef *NewIndex = NewTable->IndexDefs->AddIndexDef();
// přidání indexu
NewIndex->Name = "PrimaryIndex";
NewIndex->Fields = Edit2->Text;
NewIndex->Options << ixPrimary <<
ixUnique;
// Testujeme zda tabulka již neexistuje
bool CreateIt = (!NewTable->Exists);
if (!CreateIt)
if (Application->MessageBox((AnsiString("Overwrite
table ") + Edit1->Text +
AnsiString("?")).c_str(),
"Table Exists", MB_YESNO) == IDYES)
CreateIt = true;
if(CreateIt)
NewTable->CreateTable(); // vytvoření
tabulky
Importování dat z jiné tabulky
Metodu BatchMove komponenty tabulky můžeme použít
k importování dat z jiné tabulky. BatchMove může:
-
Kopírovat záznamy z jiné tabulky do této tabulky.
-
Aktualizovat záznamy v této tabulce, které se vyskytují v
jiné tabulce.
-
Přidávat záznamy z jiné tabulky na konec této tabulky.
-
Rušit záznamy v této tabulce, které se vyskytují v jiné tabulce.
BatchMove přebírá dva parametry: jméno tabulky, ze
které chceme data importovat a specifikace režimu operace importu. Následující
tabulka popisuje možné nastavení pro specifikace režimu.
Hodnota |
Význam |
batAppend |
Připojení všech záznamů ze zdrojové tabulky na konec
této tabulky. |
batAppendUpdate |
Připojení všech záznamů ze zdrojové tabulky na konec
této tabulky a aktualizace existujících záznamů v této tabulce stejnými
záznamy ze zdrojové tabulky. |
batCopy |
Kopíruje všechny záznamy ze zdrojové tabulky do této
tabulky. |
batDelete |
Ruší všechny záznamy v této tabulce, které se také vyskytují
ve zdrojové tabulce. |
batUpdate |
Aktualizace existujících záznamů v této tabulce jejich
protějšky ve zdrojové tabulce. |
Např. následující kód aktualizuje záznamy v současné tabulce
záznamy z tabulky Customer:
Table1->BatchMove("CUSTOMER.DB", batUpdate);
BatchMove vrací počet úspěšně importovaných záznamů.
Pozor: Importované záznamy pomocí režimu batCopy
přepisují existující záznamy. K ochránění existujících záznamů použijeme
batAppend.
BatchMove provádí pouze některé funkce dostupné
naší aplikací přímo prostřednictvím komponenty TBatchMove. Pokud
potřebujeme přesouvat větší množství dat mezi tabulkami, pak použijeme
komponentu dávkového přesunu, místo volání funkce BatchMove komponenty
tabulky.
Synchronizování
tabulek připojených ke stejné databázové tabulce
Pokud více než jedna komponenta tabulky je spojena se stejnou
tabulkou databáze pomocí jejich vlastností DatabaseName a TableName
a tabulky nesdílí komponentu datového zdroje, pak každá tabulka má svůj
vlastní pohled na data a svůj vlastní aktuální záznam. Při procházení záznamy
uživatelem se aktuální záznamy komponent tabulek liší.
K vnucení aktuálního záznamu pro každou z těchto komponent
tabulky na stejnou hodnotu voláme metodu GotoCurrent. GotoCurrent
nastavuje svůj vlastní aktuální záznam tabulky na aktuální záznam komponenty
jiné tabulky. Např. následující kód nastavuje aktuální záznam CustomerTableOne
na
aktuální záznam CustomerTableTwo:
CustomerTableOne->GotoCurrent(CustomerTableTwo);
Tip: Pokud naše aplikace potřebuje synchronizovat
komponenty tabulek tímto způsobem, pak vložíme komponenty do datového modulu
a vložíme hlavičku datového modulu do každé jednotky, ve které přistupujeme
k tabulkám.
Pokud musíme synchronizovat komponenty tabulek na oddělených
formulářích, pak musíme vložit hlavičkový soubor jednoho formuláře do jednotky
druhého formuláře a alespoň jedno jméno tabulky musíme kvalifikovat jménem
formuláře. Např.
CustomerTableOne->GotoCurrent(Form2->CustomerTableTwo);
Vytváření
formulářů Master-detail
Vlastnosti MasterSource a MasterFields komponenty
tabulky mohou být použity k zřízení vazby 1 : N mezi dvěmi tabulkami. Vlastnost
MasterSource
je použita ke specifikaci datového zdroje, ze kterého tabulka bude získávat
data pro tabulku Master. Např. pokud spojíme dvě tabulky do vazby Master-detail,
pak tabulka Detail může zachycovat události nastalé v tabulce Master specifikací
datového zdroje tabulky Master v této vlastnosti.
Vlastnost MasterFields specifikuje sloupce společné
v obou tabulkách použité pro zřízení vazby. Pro spojení tabulek na základě
více jmen sloupců použijeme středníky oddělovaný seznam:
Table1->MasterFields = "OrderNo;ItemNo";
Pro pomoc při vytváření smysluplných vazeb mezi dvěmi
tabulkami, můžeme použít Návrhář vazby položek.
Příklad formuláře Master-detail
Následující kroky vytvářejí jednoduchý formulář, ve kterém
uživatel může procházet záznamy zákazníků a zobrazovat všechny objednávky
od aktuálního zákazníka. Tabulka Master je tabulka CustomersTable
a tabulka Detail je OrdersTable:
-
Umístíme dvě komponenty TTable a dvě komponenty TDataSource
do datového modulu.
-
Nastavíme vlastnosti první komponenty TTable takto:
-
DatabaseName: BCDEMOS
-
TableName: CUSTOMER
-
Name: CustomersTable
-
Nastavíme vlastnosti druhé TTable takto:
-
DatabaseName: BCDEMOS
-
TableName: ORDERS
-
Name: OrdersTable
-
Nastavíme vlastnosti první TDataSource na:
-
Name: CustSource
-
DataSet: CustomersTable
-
Nastavíme vlastnosti druhé TDataSource na:
-
Name: OrdersSource
-
DataSet: OrdersTable
-
Umístíme dvě komponenty TDBGrid na formulář.
-
Zvolíme File | Include Unit Hdr k určení, že formulář
bude používat datový modul.
-
Nastavíme vlastnost DataSource první komponenty mřížky
na DataModule2->CustSource a nastavíme vlastnost DataSource
druhé komponenty mřížky na DataModule2->OrdersSource.
-
Nastavíme vlastnost MasterSource komponenty OrdersTable
na
CustSource. Tím propojíme tabulku CUSTOMER (tabulka Master) s
tabulkou ORDERS (tabulka Detail).
-
Dvojitě klikneme na hodnotu vlastnosti MasterFields
v Inspektoru objektů k vyvolání Návrháře vazby položek k nastavení následujících
vlastností:
-
V Available Index zvolíme CustNo k propojení
dvou tabulek položkou CustNo.
-
V obou seznamech položek Detail Fields i Master
Fields vybereme
CustNo.
-
Stiskneme tlačítko Add pro přidání této podmínky spojení.
V seznamu
JoinedList se zobrazí CustNo -> CustNo.
-
Zvolíme OK k ukončení našeho výběru a uzavření okna
Návrháře
-
Nastavíme vlastnosti Active komponent CustomersTable
a OrdersTable na true k zobrazení dat v mřížkách na formuláři.
-
Přeložíme a spustíme aplikaci.
Pokud aplikaci spustíme nyní, pak uvidíme, že tabulky jsou
spojeny a když přejdeme na jiný záznam v tabulce CUSTOMER, pak vidíme pouze
ty záznamy tabulky ORDERS, které se vztahují k aktuálnímu zákazníku.
Práce s vnořenými tabulkami
Vnořené komponenty tabulek poskytují přístup k datům ve vnořené
datové množině tabulky. Vlastnost NestedDataSet trvalé položky vnořené
datové množiny obsahuje odkaz na vnořenou datovou množinu. Jelikož TNestedDataSet
je odvozena od TBDEDataSet, vnořené tabulky dědí funkčnost BDE a
můžeme použít BDE pro přístup k datům vnořené tabulky. Vnořené tabulky
poskytují více funkčnosti tabulky komponenty, ale zpřístupňovaná data jsou
uložena ve vnořené tabulce.
Následující kroky jsou obecné instrukce pro nastavování
komponent vnořených tabulek při návrhu. Komponenta tabulky nebo živého
dotazu musí být dostupná v datové množině obsahující datovou množinu nebo
odkazovanou položku. Trvalé položky pro TDataSetField nebo TReferenceField
musí také existovat. K použití komponenty vnořené tabulky:
-
Umístíme komponentu vnořené tabulky ze stránky Data Access
Palety komponent do datového modulu nebo na formulář a nastavíme její vlastnost
Name
na unikátní hodnotu v naší aplikaci.
-
Nastavíme DataSetField komponenty na jméno trvalé
položky datové množiny nebo položkový odkaz k přístupu. Položky můžeme
vybrat z rozbalovacího seznamu.
-
Umístíme komponentu datového zdroje do datového modulu nebo
na formulář a nastavíme vlastnost DataSet na jméno komponenty vnořené
tabulky. Komponenta datového zdroje je použita k předání výsledkové množiny
z tabulky do datových ovladačů k zobrazení.
-
V adresáři Program files\Borland\CBuilder\Examples\DBTask\Find nalezneme
demonstrační aplikaci hledající záznamy na základě hodnot v tabulce Customer.
Prohlédněte si tuto aplikaci a zjistěte jak pracuje.