Tato kapitola popisuje využití vlastností a prostředků Delphi pro vytváření databázových aplikací. Je uveden základní přehled a krátký popis tříd pro práci s databázovými soubory. Bližší informace týkající se databázových prvků a jejich metod a vlastností lze najít v on-line helpu.
Hierarchie tříd pro práci s databázemi je podstatná pro pochopení vlastností, metod a událostí, které jednotlivé třídy dědí od svých předků. Nejdůležitější třídy pro práci s databázemi jsou:
Prvky třídy TSession jsou používány zřídka, ale v některých speciálních případech mohou být užitečné. Delphi vytváří instanci třídy TSession se jménem Session při každém běhu databázové aplikace. Tento prvek není explicitně zobrazen a nemůže být explicitně vytvořen, lze však použít jeho metody a vlastnosti, které ovlivňují globální chování aplikace.
Třída TSession umožňuje globální řízení databázových sezení dané aplikace. Vlastnost Databases třídy TSession obsahuje seznam všech aktivních databázových sezení. Vlastnost DatabaseCount obsahuje počet aktivních databází (tj. počet použitých instancí třídy TDatabase).
Logická vlastnost KeepConnections udává, zda mají být uchována neaktivní databázová sezení - databázové sezení přestane být aktivní, když prvek třídy TDatabase nemá žádné aktivní prvky třídy TDataSet. Implicitní hodnota vlastnosti KeepConnections je true a aplikace uchovává databázová sezení, i když nejsou aktivní. To je obecně vhodnější v případě, že aplikace opakovaně otevírá a uzavírá tabulky databáze. Má-li KeepConnections hodnotu false, databázové sezení je ukončeno okamžitě, jakmile přestane být aktivní. Metoda DropConnections ukončí všechna neaktivní databázová sezení.
Vlastnost NetFileDir obsahuje cestu k pracovnímu adresáři BDE. Vlastnost PrivateDir udává adresář pro uchování dočasných souborů (např. souborů vytvářených při zpracování SQL příkazů). Tato vlastnost by se měla nastavovat jen v případě, že může aplikace běžet v každém okamžiku pouze jednou. V opačném případě dochází ke kolizi takto vytvářených dočasných souborů.
Třída TSession má několik metod, které umožňují aplikaci získat informace týkající se zpracovávané databáze. Všechny metody používají parametr typu TStrings, vrací v tomto parametru požadované informace a jejich přehled je v následující tabulce.
Metody třídy TSession | |
---|---|
Metoda | Vrací |
GetAliasNames | Alias jméno v BDE |
GetAliasParams | Parametry daného BDE aliasu |
GetDatabaseNames | Použitá jména databází a BDE aliasů |
GetDriverNames | Jména instalovaných BDE driverů |
GetDriverParams | Parametry zadaného BDE driveru |
GetTableNames | Jména všech tabulek zadané databáze |
Třídy TTable a TQuery jsou odvozeny od třídy TDataSet. Obě tyto třídy sdílí řadu společných vlastností, metod i událostí. Z tohoto důvodu používáme společný termín datové množiny a budeme se s nimi zabývat nejprve společně.
Poznámka:
Mezi datové množiny řadíme i instance třídy TStoredProc,
protože i ta je odvozena od třídy TDataSet. Většina údajů
v této části se vztahuje i na třídu TStoredProc
v případě, že příslušná procedura vrací výsledkovou množinu (a
ne např. jednu hodnotu).
Stavy datových množin | |
---|---|
Stav | Popis |
Neaktivní (Inactive) | Datová množina není otevřena. |
Prohlížení (Browse) | Implicitní stav po otevření datové množiny. Záznamy lze prohlížet, nelze je měnit ani vkládat. |
Editace (Edit) | Umožňuje editaci aktuálního záznamu. |
Vkládání (Insert) | Umožňuje vložení nového záznamu. |
Nastavení klíče (SetKey) | Tento stav se týká pouze třídy TTable a umožňuje hledání v tabulkách databáze pomocí metod FindKey, GoToKey a GoToNearest. Třída TQuery využívá k hledání prostředků jazyka SQL. |
Výpočet položek (CalcFields) | Aplikace nastavuje tento stav při provádění události OnCalcFields, explicitně se používá zřídka. |
Aplikace převádí datovou množinu do požadovaného stavu většinou
voláním metody, jejíž jméno odpovídá anglickému názvu stavu. Například
tabulku Table1 převedeme do stavu "Vkládání" voláním metody
Table1.Insert
nebo do stavu "Editace" voláním
Table1.Edit
. Řada dalších metod vrací prvky do základního stavu
"Prohlížení", v závislosti na výsledku volané metody. Volání metody
Cancel má vždy za následek přechod do stavu "Prohlížení".
Speciálním případem je stav "Výpočet položek". Z programu tento stav explicitně nenastavujeme, ale datová množina do tohoto stavu přechází automaticky při provádění události OnCalcFields, která slouží k definici hodnot "vypočítávaných" položek. V tomto stavu je generována výjimka, pokud se aplikace pokusí přiřadit hodnotu jiné než vypočítávané položce. Po ukončení události OnCalcFields se datová množina vrátí do původního stavu.
Základní stavy datových množin a přechod mezi těmito stavy při volání jednotlivých metod obsahuje následující diagram.
Vlastnost State uchovává aktuální stav datové množiny. Možné hodnoty této vlastnosti odpovídají výše uvedeným stavům: dsInactive, dsEdit, dsInsert, dsSetKey a dsCalcFields.
Při změně stavu připojeného prvku třídy TDataSource je provedena událost OnStateChange. Bližší informace jsou v části Použití událostí třídy TDataSource.
Dříve než může aplikace přistupovat pomocí datových množin ke zpracovávaným datům, je třeba datovou množinu otevřít. To lze provést dvěma způsoby:
Table1.Active := true;
Query1.Open;
Oba výše uvedené příkazy otevírají datovou množinu a převádí ji do režimu "Prohlížení".
Podobně existují dva způsoby, jak datovou množinu uzavřít:
Query1.Active := false;
Table1.Close;
Oba výše uvedené příkazy uzavírají datovou množinu a převádí jí do režimu "Neaktivní".
Pro pochopení toho, jak Delphi pracuje s datovými množinami, je důležitý pojem kurzor. Každá aktivní datová množina má kurzor, což je v podstatě ukazatel na aktuální záznam v příslušné datové množině. Kurzor můžeme chápat také jako lokální kopii tohoto pracovního záznamu, jako prostor do něhož se například ukládají změny položek provedené v režimu "Editace" před tím, než jsou voláním metody Post fyzicky zapsány do databáze.
Skupinu datových záznamů před a za kurzorem umísťuje Delphi do lokální vyrovnávací paměti pro urychlení práce s datovou množinou při pohybu v datech směrem nahoru nebo dolů.
Metody umožňující pohyb v datové množině jsou uvedeny v následující tabulce:
Navigační metody a vlastnosti | |
---|---|
Metoda nebo vlastnost | Popis |
metoda First | Nastavuje kurzor na první záznam datové množiny. |
metoda Last | Nastavuje kurzor na poslední záznam datové množiny. |
metoda Next | Nastavuje kurzor na následující záznam. |
metoda Prior | Nastavuje kurzor na předcházející záznam. |
vlastnost BOF | Má hodnotu true, pokud je známo, že je kurzor na prvním záznamu datové množiny; jinak má hodnotu false. |
vlastnost EOF | Má hodnotu true, pokud je známo, že je kurzor na posledním záznam datové množiny; jinak má hodnotu false. |
metoda MoveBy(n) | Přesunuje kurzor o n záznamů dopředu; n je kladné nebo záporné celé číslo. |
Většina těchto metod je dostupná i přes ovládací prvek třídy TDBNavigator. Bližší informace o této třídě je v části "Použití databázových ovládacích prvků".
Metoda Next přesunuje kurzor na další záznam:
Table1.Next;
Podobně metoda Prior přesunuje kurzor na předcházející záznam příslušné datové množiny. Přesun na předcházející záznam v tabulce tedy vypadá následovně:
Table1.Prior;
Jak vyplývá z anglických názvů těchto metod, nastavují kurzor na první, resp. na poslední záznam datové množiny. Následující příkaz nastavuje kurzor na první záznam tabulky zpřístupněné datovou množinou Table1:
Table1.First;
Podobně metoda Last nastavuje kurzor na poslední záznam datové množiny:
Table1.Last;
BOFje logická vlastnost určená pouze pro čtení, která udává, zda je o datové množině známo, že je nastavena na první záznam. Vlastnost BOF obsahuje hodnotu true pouze v následujících případech:
Databáze jsou dynamické; zatímco jedna aplikace zprostředkovává prohlížení dat, jiná může vkládat řádek před záznam, který první aplikace považuje za první. Z tohoto důvodu se nelze vždy spolehnout na předpokládanou hodnotu vlastnosti BOF.
Vezměme jako příklad následující kód:
Table1.Open; {BOF = true} Table1.Next; {BOF = false} Table1.Prior; {BOF = false}
Po provedení tohoto zlomku programu má vlastnost BOF hodnotu false, a to i v případě, kdy před aktuálním záznamem žádné další záznamy nejsou. U otevřené datové množiny může Delphi nastavit BOF na hodnotu true pouze tehdy, když aplikace explicitně vyvolá First nebo když selže volání Prior. Podobně může Delphi nastavit EOF na hodnotu true pouze v případě, když aplikace explicitně vyvolá metodu Last nebo když selže volání Next.
Následující zlomek programu ukazuje standardní postup využívající vlastnost BOF:
while not Table1.BOF do begin UdelejNeco; Table1.Prior end;
V tomto příkladu je volána hypotetická funkce UdelejNeco pro aktuální záznam a potom pro všechny záznamy mezi aktuálním záznamem a začátkem datové množiny. Cyklus pokračuje až do doby, kdy se nepodaří voláním Prior přesunout aktuální záznam. Tím získá vlastnost BOF hodnotu true a programový cyklus se ukončí.
Před iteračním zpracováním datové množiny je vhodné vyvolat metodu DisableControls. Tím zabráníme databázovým ovládacím prvkům zobrazovat hodnoty jednotlivých záznamů a jednak značně urychlíme provádění cyklu, jednak zamezíme pro uživatele nepříjemným rychlým změnám obsahu obrazovky. Po dokončení cyklu vyvoláme metodu EnableControls. Je žádoucí použít příkaz try...finally...end s voláním metody EnableControls ve frázi finally. V opačném případě zůstanou po výskytu chyby databázové ovládací prvky neaktivní.
Obdobné zásady platí i pro vlastnost EOF, která nabývá hodnoty true v následujících případech:
Následující ukázka programu představuje jednoduchý cyklus přes všechny záznamy datové množiny využívající metodu Next a vlastnost EOF :
Table1.DisableControls; try Table1.First; while not Table1.EOF do begin UdelejNeco; Table1.Next; end; finally Table1.EnableControls; end;Pozor! Typickou chybou při použití těchto metod pro pohyb v datové množině je použití cyklu repeat...until se zapomenutým voláním metody Next tak, jak ukazuje následující příklad:
Table1.First; repeat UdelejNeco until Table1.EOF;
Při provedení tohoto nebo obdobného kódu aplikace "zamrzne", protože tatáž akce bude donekonečna prováděna pro první záznam datové množiny a vlastnost EOF nikdy nenabude hodnoty true.
Pro prázdnou tabulku nabývají obě vlastnosti BOF i EOF po otevření datové množiny nebo po volání kterékoliv z navigačních metod hodnotu true.
Funkce MoveBy umožňuje pohyb v datové množině dopředu i dozadu o zadaný počet záznamů. Tato funkce má jediný parametr, kterým je požadovaný počet záznamů. Kladné číslo znamená pohyb dopředu, záporné číslo pohyb dozadu.
Například pro posun o dva záznamy dopředu v tabulce Table1 použijeme příkaz:
Table1.MoveBy(2);
Při použití této funkce je třeba mít na paměti, že ve víceuživatelském prostředí jsou datové množiny proměnlivé entity a že záznam, který byl nedávno o pět záznamů zpátky, může být nyní zpět o čtyři záznamy, nebo o šest záznamů, nebo o nějaký jiný počet záznamů, protože s databází může pracovat a databázi modifikovat současně větší počet uživatelů.
Poznámka:
Funkčně není rozdíl mezi voláním Table1.Next a voláním
Table1.MoveBy(1), stejně jako není rozdíl mezi voláním
Table1.Prior a Table1.MoveBy(-1).
Pro vkládání, modifikaci a rušení dat v datových množinách může aplikace použít metody z následující tabulky.
Metody pro vkládání, modifikaci a rušení dat | |
---|---|
Metoda | Popis |
Edit | Převádí datovou množinu do stavu "Editace". Je-li datová množina již ve stavu "Editace" nebo "Vkládání", volání metody Edit nemá žádný efekt. |
Append | Předává připravená data, nastavuje kurzor na konec datové množiny a převádí datovou množinu do stavu "Vkládání". |
Insert | Předává připravená data a převádí datovou množinu do stavu "Vkládání". |
Post | Předává nový nebo modifikovaný záznam do databáze. Při úspěšném předání převádí datovou množinu do stavu "Prohlížení"; při neúspěšném předání se stav nemění. |
Cancel | Ukončuje předčasně rozpracovanou operaci a převádí datovou množinu do stavu "Prohlížení". |
Delete | Ruší aktuální záznam a převádí datovou množinu do stavu "Prohlížení" |
CanModify je vlastnost datové množiny pouze pro čtení, která udává, zda může aplikace data v této datové množině měnit. Má-li CanModify hodnotu false, datovou množinu lze pouze číst a nelze změnit její stav na "Editace" nebo "Vkládání". Má-li CanModify hodnotu true, stav datové množiny může být změněn na "Editace" nebo "Vkládání". Ani v případě, že tento atribut má hodnotu true, není garantována uživateli možnost vkládat nebo modifikovat data v databázi. Mezi faktory, které tomu mohou zabránit, jsou například chybějící přístupová práva na úrovni databáze.
Třída TTable má vlastnost ReadOnly, která při nastavení na hodnotu false umožňuje zápis, má-li uživatel příslušná přístupová práva. Má-li ReadOnly hodnotu true, je vlastnost CanModify automaticky nastavena na hodnotu false. Bližší informace viz část Použití třídy TTable.
Metoda Post má klíčovou roli při interakci aplikace v Delphi s databázovou tabulkou. Činnost metody Post závisí na stavu datové množiny.
Předání dat může být explicitní nebo může být implicitní součástí jiné metody. Při opuštění aktuálního záznamu volá Delphi metodu Post implicitně. Pokud je datová množina ve stavu "Editace" nebo "Vkládání", vede volání metod First, Next, Prior a Last k volání Post. Metody Append a Insert rovněž volají pro připravená data metodu Post.
Poznámka:
Metoda Post není implicitně volána při provedení
Close. Pro explicitní předání připravených dat lze použít
událost BeforeClose.
Předtím, než může aplikace modifikovat záznamy ve zpracovávané tabulce, musí být datová množina ve stavu "Editace". Do tohoto stavu přejde datová množina voláním své metody Edit. Ve stavu "Editace" změníme voláním Post hodnotu aktuálního záznamu. Pokud datová množina již ve stavu "Editace" je, volání Edit nemá žádný efekt.
Metody Edit a Post používáme většinou společně. Příklad:
Table1.Edit; Table1.FieldByName('CISLO_ZAK').AsString := '1234'; Table1.Post;
První řádek tohoto příkladu převádí datovou množinu do stavu "Editace". Další řádek přiřazuje položce CISLO_ZAK řetězec '1234'. Poslední řádek potom předává, nebo zapisuje, právě modifikovaná data do databáze.
Pro přidání nového záznamu k datové množině volá aplikace buď metodu Insert nebo metodu Append. Obě metody převádí datovou množinu do stavu "Vkládání". Metoda Insert otevírá nový prázdný záznam bezprostředně za aktuálním záznamem. Metoda Append nastavuje kurzor na konec datové množiny a tam otevírá nový prázdný záznam.
Při následném volání metody Post je nový záznam vložen do databáze na pozici podle aktuálního indexu, je-li nějaký definován. Pro indexované tabulky se tedy Insert i Append chovají stejně. Není-li pro danou tabulku definován index, pozice záznamu zůstane zachována -- Append proto přidá záznam na konec tabulky a Insert ho přidá za záznam, který byl aktuální v okamžiku volání metody Insert. V obou případech může při zápisu do mřížky dojít ke změně všech zobrazených záznamů, pokud datová množina přejde na pozici danou indexem nově vytvořeného záznamu a načte data zobrazená v okolních záznamech mřížky.
Metoda Delete ruší aktuální záznam a ponechává datovou množinu ve stavu "Prohlížení". Kurzor se přesune na následující záznam.
Změny provedené v aktuálním záznamu může aplikace kdykoliv vrátit zpět až do doby, kdy jsou explicitně nebo implicitně zapsány do databáze metodou Post. Pokud je například datová množina ve stavu "Editace" a uživatel změnil data v jedné nebo více položkách, aplikace může obnovit původní stav záznamu voláním metody Cancel příslušné datové možiny. Volání metody Cancel vždy způsobí přechod do stavu "Prohlížení".
V následující tabulce jsou uvedeny metody, které umožňují pracovat jedním příkazem současně s celým záznamem. Každá z těchto metod má jako parametr pole hodnot oddělených čárkami, kde každá hodnota odpovídá sloupci příslušné tabulky. Hodnotami mohou být konstanty, proměnné a hodnota Null nebo nil. Je-li počet hodnot menší než počet sloupců datové množiny, zbývající hodnoty jsou pokládány za prázdné.
Metody pro práci s celými záznamy | |
---|---|
Metoda | Popis |
AppendRecord([pole hodnot]) | Připojuje na konec datové množiny záznam se zadanými hodnotami položek analogicky jako metoda Append. Provádí implicitní volání metody Post. |
InsertRecord([pole hodnot]) | Vkládá záznam vytvořený ze zadaných hodnot položek za aktuální pozici kurzoru analogicky jako metoda Insert. Provádí implicitní volání metody Post. |
SetFields([pole hodnot]) | Nastavuje hodnoty v daném záznamu. Aplikace musí sama provést volání metody Post. |
U neindexovaných tabulek přidává metoda AppendRecord záznam na konec tabulky a metoda InsertRecord vkládá záznam za aktuální kurzor. U indexovaných tabulek vkládají obě metody záznam na místo odpovídající hodnotě indexu pro daný záznam. V obou případech je kurzor nastaven na nový záznam.
Metoda SetFields přiřazuje hodnoty zadané v poli hodnot položkám datové množiny. Aplikace musí nejprve provést volání Edit pro převedení datové množiny do stavu "Editace" a po modifikaci záznamu provést volání Post.
Protože všechny tyto metody závisí na struktuře příslušných tabulek, měly by být v aplikaci použity pouze v případě, že se struktura tabulky nebude měnit (a to je dost silný požadavek).
Vezměme jako příklad tabulku STAT s položkami NAZEV, HLAVNI_MESTO, SVETADIL, PLOCHA a OBYVATEL. Je-li datová množina Table1 navázána na tabulku STAT, následující příkaz vloží do tabulky STAT nový záznam:
Table1.InsertRecord(['Japonsko','Tokio','Asie']);
V příkazu nejsou zadány hodnoty pro plochu a počet obyvatel, proto bude do těchto položek vložena hodnota Null. Pokud je tabulka indexována podle položky NAZEV, záznam bude vložen na základě abecedního pořadí názvu "Japonsko".
K doplnění záznamu mohou být použity následující příkazy:
Table1.Edit; Table1.SetFields(nil, nil, nil, 344567, 164700000); Table1.Post;
Tyto příkazy předpokládají, že kurzor bude umístěn na právě vložený záznam týkající se Japonska. Přiřazuje hodnoty pro plochu a počet obyvatel a předává je do databáze. První tři hodnoty nil tedy slouží jako specifikace místa pro první tři položky, jejichž hodnota se nemění.
Vlastnost UpdateMode datové množiny udává, jak bude aplikace hledat záznamy pro modifikaci v SQL databázi. Tato vlastnost je podstatná ve víceuživatelském prostředí, kdy mohou uživatelé vybírat stejné záznamy a provádět v nich konfliktní úpravy.
Když uživatel předá do databáze změnu, Delphi používá k nalezení záznamu v databázi původní hodnoty záznamu. Tento přístup odpovídá optimistickému uzamykacímu schématu. Vlastnost UpdateMode udává, které položky k nalezení záznamu má Delphi použít. V pojmech jazyka SQL UpdateMode udává, které položky jsou obsaženy ve frázi WHERE příkazu UPDATE. Pokud Delphi nedokáže najít záznam s původními hodnotami zadaných položek (protože je jiný uživatel v databázi změnil), Delphi změnu neprovede a generuje výjimku.
Vlastnost UpdateMode může nabývat následujících hodnot:
Jako příklad vezměme tabulku STAT s položkami NAZEV (jako klíč), HLAVNI_MESTO a SVETADIL. Předpokládejme, že si já a ještě jeden uživatel prohlížíme záznam s následujícími hodnotami:
NAZEV = "Filipíny" HLAVNI_MESTO = "Nairobi" SVETADIL = "Afrika"
Oba si všimneme, že zobrazená informace je nesprávná a je třeba jí opravit. Nechť druhý uživatel změní SVETADIL na "Asie" a HLAVNI_MESTO na "Manila" a předá data do databáze. O několik sekund později změním já NAZEV na "Keňa" a předám do databáze i svojí změnu.
Má-li aplikace nastaven UpdateMode pro datovou množinu na hodnotu WhereKeyOnly, Delphi porovná původní hodnotu klíče (NAZEV = "Filipíny") s aktuální hodnotou v databázi. Protože druhý uživatel nezměnil sloupec NAZEV, moje modifikace proběhne. Já předpokládám, že záznam je nyní ["Keňa", "Nairobi", "Afrika"] a druhý uživatel předpokládá, že záznam je ["Filipíny", "Manila", "Asie"]. Bohužel skutečný záznam je ["Keňa", "Manila", "Asie"], což je i nadále chybně, přestože si oba uživatelé myslí, že chybu opravili. Problém vznikl proto, že atribut UpdateMode byl nastaven na nejméně omezující hodnotu, která proti těmto případům nechrání.
Pokud má datová množina nastaveno UpdateMode na hodnotu WhereAll, Delphi zkontroluje všechny sloupce předtím, než se pokusí provést modifikaci. Protože druhý uživatel změnil sloupce HLAVNI_MESTO a SVETADIL, Delphi nedovolí další změnu provést. Získám-li záznam znovu, uvidím nové hodnoty vložené druhým uživatelem a poznám, že chyba již byla opravena.
Často je užitečné si označit konkrétní pozici v tabulce tak, aby bylo možno se tam v případě potřeby rychle vrátit. Pro tento účel dává Delphi k dispozici značkovací metody (bookmarking methods). Tyto metody umožňují umístit do datové množiny značku a později se k ní rychle vrátit.
Značkovací metody jsou tři:
Tyto metody se používají společně. Funkce GetBookMark vrací proměnnou typu TBookMark. Tato proměnná obsahuje ukazatel na konkrétní pozici v datové množině. Předáme-li tuto značku metodě GoToBookMark, tato metoda nastaví kurzor datové množiny na tuto označenou pozici.
Metoda FreeBookMark uvolňuje paměť přidělenou dané značce. Volání metody GetBookMark přidělí pro značku paměť, proto by aplikace měla přidělenou paměť po použití značky voláním metody FreeBookMark opět vrátit.
Následující příkazy ilustrují typické použití značky:
procedure UdelejNeco; var BookMark:TBookMark; begin BookMark:=Table1.GetBookMark; {označení pozice} Table1.DisableControls; try Table1.First; while not Table1.EOF do begin {požadovaná činnost} Table1.Next; end; finally Table1.GoToBookMark; {použití značky} Table1.EnableControls; Table1.FreeBookMark(BookMark); {uvolnění značky} end; end;
Metoda DisableControls blokuje všechny databázové ovládací prvky připojené k datové množině. Tuto metodu je možno s určitou opatrností použít k zamezení "blikání" obrazovky při pohybu v datech - například když programově procházíme nebo prohledáváme datovou množinu. Jakmile je kurzor znovu nastaven, aplikace by měla vyvolat EnableControls a tak databázové ovládací prvky znovu odblokovat. Je důležité ovládací prvky metodou EnableControls odblokovat ihned, jakmile aplikace dokončí iteraci nebo prohledávání, aby byla zaručena aktuálnost informací zobrazovaných těmito ovládacími prvky. Způsob použití příkazu try...finally ukazuje předcházející příklad.
Metoda Refresh vyprazdňuje všechny lokální vyrovnávací paměti a znovu obnovuje data z příslušné datové množiny. Tuto funkci lze použít k obnovení tabulky, pokud předpokládáme, že mohlo dojít ke změně zobrazovaných dat. Obnovení datové množiny někdy může vést k neočekávaným výsledkům. Pokud si například uživatel prohlíží záznam, který byl mezitím zrušen, tento záznam v okamžiku volání metody Refresh neočekávaně zmizí. Podobně se mohou změnit data, pokud je některý jiný uživatel změnil v době mezi původním natažením dat a voláním metody Refresh.
K datovým množinám patří řada událostí, které umožňují aplikaci provádět validaci dat, počítat součty nebo provádět další akce v závislosti na volané metodě. Seznam těchto událostí je v následující tabulce.
Události vázané k datovým množinám | |
---|---|
Událost | Popis |
BeforeOpen, AfterOpen | Je provedena před/po otevření datové množiny. |
BeforeClose, AfterClose | Je provedena před/po uzavření datové množiny. |
BeforeInsert, AfterInsert | Je provedena před/po změně stavu datové množiny na "Vkládání". |
BeforeEdit, AfterEdit | Je provedena před/po změně stavu datové množiny na "Editace". |
BeforePost, AfterPost | Je provedena před/po předání změn do databáze. |
BeforeCancel, AfterCancel | Je provedena před/po zrušení operace. |
BeforeDelete, AfterDelete | Je provedena před/po zrušení záznamu. |
OnNewRecord | Je provedena po vytvoření nového záznamu; používá se k zadání implicitních hodnot. |
OnCalcFields | Je provedena při výpočtu hodnot vypočítávaných položek. |
Pro zrušení metod jako je Open nebo Insert je možno generovat výjimku nebo volat proceduru Abort v kterékoliv z metod Before.... Následující příklad vyžaduje potvrzení zrušení záznamu:
procedure TForm1.TableBeforeDelete (DataSet: TDataSet); begin if MessageDlg('Mohu zrušit tento záznam?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then Abort; end;
Událost OnCalcFields se používá k nastavení hodnot vypočítávaných položek. Okamžik volání metody OnCalcFields je řízen vlastností AutoCalcFields. Má-li AutoCalcFields hodnotu true, je událost OnCalcFields volána:
Metoda OnCalcFields je také volána při každé změně skutečné (nevypočítávané) položky, bez ohledu na hodnotu vlastnosti AutoCalcFields.
Událost OnCalcFields je typicky volána mnohokrát a měla by být tudíž krátká. Pokud má AutoCalcFields hodnotu true, událost OnCalcFields by neměla dělat nic, co vede ke změně datové množiny (nebo jiné datové množiny svázané relací), protože to může vést k rekurzivnímu volání události. Pokud by například událost OnCalcFields volala metodu Post a vlastnost AutoCalcFields by měla hodnotu true, byla by metoda OnCalcFields vyvolána znovu, znovu by vyvolala Post atd.
Má-li AutoCalcFields hodnotu false, je událost OnCalcFields provedena při volání metody Post příslušné datové množiny (nebo jiné metody, která volá Post implicitně, jako je Insert nebo Append).
Při provádění události OnCalcFields je datová množina ve stavu "Výpočet položek". Ve stavu "Výpočet položek" nelze změnit hodnotu jiné než vypočítávané položky. Po dokončení události OnCalcFields je datová množina vrácena do původního stavu.
Třída TTable je jednou z nejdůležitějších tříd databázových
prvků. Spolu s další databázovou třídou TQuery umožňuje aplikaci
přístup k databázovým tabulkám. Tato část popisuje nejdůležitější
vlastnosti specifické pro prvky třídy TTable.
Vlastnost TableName obsahuje jméno tabulky, na kterou je
datová množina třídy TTable navázána. Tuto vlastnost většinou
nastavujeme při vytváření programu v Editoru objektů.
Vlastnost DatabaseName udává, kde má Delphi zadanou
databázovou tabulku hledat. Může to být BDE alias, explicitní určení
adresáře nebo hodnota vlastnosti DatabaseName některé z instancí
třídy TDatabase v dané aplikaci. Pro Paradox nebo Dbase tabulky
je explicitním určením jméno adresáře včetně cesty; pro SQL tabulky to
může být úplné jméno souboru obsahujícího databázi.
Vlasnost TableType udává typ použité databázové tabulky. Pro
SQL tabulky se tato vlastnost nepoužívá. Je-li vlastnost TableType
nastavena na hodnotu Default, je typ tabulky určen extenzí zadaného
souboru:
Nemá-li TableType hodnotu Default, tabulka je
považována za tabulku zadaného typu bez ohledu na extenzi souboru.
Třída TTable má několik metod, které umožňují vyhledávat
v databázových tabulkách zadané hodnoty:
Novější verze Delphi doporučují používání obecnějších metod
Locate a Lookup, použití starších metod "GoTo" a "Find"
může být někdy jednodušší a efektivnější.
Nejjednodušší je vyhledání hodnot pomocí vyhledávacích ("Find")
funkcí FindKey a FindNearest. Tyto dvě funkce kombinují
možnosti základních funkcí "GoTo", které popíšeme napřed.
V tabulkách typu Paradox a Dbase lze hledat pouze podle položek,
pro něž byl vytvořen index. V SQL tabulkách lze hledat podle
libovolných položek, pokud je uvedeme ve vlastnosti
IndexFieldNames příslušné datové množiny třídy TTable. Bližší
informace viz část Indexy.
Potřebujeme-li hledat v tabulkách typu Paradox nebo Dbase
hodnotu položky, pro níž není vytvořen index, použijeme datovou mnopžinu
třídy TQuery a vhodný SQL příkaz SELECT. Bližší informace
o použití SQL datových množin třídy TQuery viz "Použití jazyka
SQL".
Metody GoToKey a GoToNearest umožňují vyhledávat
v tabulkách klíčové položky. Metoda SetKey převádí datovou
množinu do stavu "Nastavení klíče". V tomto stavu zadáme do položek
tvořících index hodnoty, které mají být vyhledány. Metoda GotoKey
nastavuje kurzor na první záznam tabulky, který obsahuje zadané hodnoty
položek.
Následující příklad může být použit jako obsluha události
OnClick tlačítka "Hledej":
První řádek příkladu za klíčovým slovem begin převádí datovou
množinu do stavu "Nastavení klíče". Následující přiřazení hodnoty
vlastnosti Fields je tedy zadáním hledané hodnoty - předpokládáme
že je nastaven index podle první položky tabulky. V tomto příkladu
hledáme text, který uživatel zapsal do editačního pole Edit1. Nakonec
provedeme voláním metody GoToKey vlastní vyhledání a nastavení
kurzor na nalezený záznam (pokud existuje).
Metoda GoToKey je logická funkce, která nastaví kurzor a
vrací true, bylo-li hledání úspěšné. Je-li hledání neúspěšné,
nastavení kurzoru se nemění a metoda vrací hodnotu false. Příklad:
Pokud není nalezen záznam, ve kterém je v první položce hodnota
"Smith", standardní funkce ShowMessage zobrazí dialog se
zprávou "Záznam nenalezen".
Je-li primární klíč tabulky tvořen více položkami a chceme-li hledat
jen podle části klíče, nastavíme vlastnost KeyFieldCount na
počet položek, podle kterých chceme hledat. Pokud je například primární
klíč tabulky tvořen třemi položkami a chceme hledat hodnotu pouze první
z nich, nastavíme KeyFieldCount na hodnotu 1. U tabulek
se složenými klíči lze hledat pouze podle začátku klíče. Můžeme tedy
hledat podle první položky, nebo podle první a druhé, případně podle
první, druhé a třetí, ale nikoliv třeba podle první a třetí.
Podobná je procedura GoToNearest, s tím, že hledá částečnou
shodu. Lze ji použít pouze pro položky obsahující řetězce. Například:
Pokud existuje záznam obsahující v prvních dvou znacích první
položky znaky "Sm", kurzor bude nastaven na nalezený záznam. V opačném
případě se nastavení kurzoru nezmění.
Pokud se nejedná o vyhledávání podle primárního indexu lokální
tabulky, musí aplikace buď specifikovat jména použitých položek
ve vlastnosti IndexFieldNames nebo specifikovat index pomocí
vlastnosti IndexName příslušné datové množiny. Pokud má například
tabulka ZAKAZNIK sekundární index se jménem MestoIdx a
chceme podle něj vyhledávat, je třeba nastavit hodnotu vlastnosti
IndexName dané datové množiny na hodnotu "MestoIdx".
Prohledání tabulky potom probíhá následujícím způsobem:
Protože jména indexů často nebývají příliš intuitivní, lze
alternativně použít vlastnost IndexFieldNames pro zadání jmen
indexovaných položek.
Po každém volání SetKey musí aplikace nastavit hodnoty všech
položek, podle kterých má hledání proběhnout. Jinými slovy, volání
SetKey maže všechny existující hodnoty položek z předchozích
volání. Tyto hodnoty lze použít voláním metody EditKey.
Pokud chceme například pokračovat v předcházejícím hledání
doplněním jména města o jméno státu, lze použít následující příkazy:
Funkce FindKey a FindNearest kombinují v jednom
příkaze funkci metody SetKey, přiřazení hledané hodnoty a volání
funkce "GoTo".
Obě tyto funkce mají jako parametr seznam hodnot oddělených čárkami,
přičemž každá hodnota odpovídá jedné položce příslušné tabulky. Hodnotami
mohou být konstanty, proměnné, hodnota Null nebo nil. Pokud
je počet hodnot uvedených v parametru menší než počet položek indexu,
zbývající hodnoty jsou považovány za prázdné. Obě funkce provedou hledání
zadaných hodnot podle aktuálního indexu.
Metoda FindKey je rozšířením metody GoToKey:
Pokud je například Table1 indexována podle první položky,
potom příkaz
provede tutéž činnost jako tři příkazy
Metoda FindNearest je rozšířením funkce GoToNearest a
přesune kurzor na záznam s nejblíže odpovídající hodnotou. Může být
použita pouze pro sloupce položky textového typu.
Implicitně pracují obě metody s primárním indexem. Pro hledání
podle jiného indexu je třeba nastavit jméno položky ve vlastnosti
IndexFieldNames příslušné datové množiny nebo jméno indexu ve
vlastnosti IndexNames.
Vlastnost KeyExclusive udává, zda má hledání nastavit kurzor
na nebo za záznam, který je hledán. Má-li KeyExclusive hodnotu
false (což je implicitní hodnota), potom metody
GoToNearest a FindNearest přesunou kurzor na záznam, který
odpovídá zadaným hodnotám. Má-li hodnotu true, dojde k nastavení
na záznam bezprostředně za záznamem s případně nalezenou hodnotou
klíče.
V reálném světě mohou být tabulky hodně velké, proto často
potřebujeme omezit množinu záznamů, se kterou se bude pracovat. Možnost
tohoto omezení (nastavení filtru) je velkou výhodou třídy TTable.
Nastavení podmnožiny se provádí následujícími metodami třídy TTable:
Metoda SetRangeStart udává, že následující přiřazení hodnotám
položek definuje začátek intervalu záznamů, s nimiž bude aplikace
pracovat. Metoda SetRangeEnd udává, že následující přiřazení definuje
konec požadovaného intervalu záznamů. Nespecifikované hodnoty položek nemají
vliv. Odpovídající metody EditRangeStart a EditRangeEnd
zachovávají stávající hodnoty hranic intervalu, s tím, že následujícím
přiřazením se provádí jejich modifikace.
Metoda ApplyRange nastavuje připravený interval. Pokud nebyla
před voláním ApplyRange volána metoda SetRangeStart,
interval začíná na začátku tabulky; podobně, pokud nebyla volána metoda
SetRangeEnd, interval končí na konci tabulky. Metoda
CancelRange ruší nastavení filtru a nadále se pracuje s celou
tabulkou.
Funkce SetRange kombinuje metody SetRangeStart,
SetRangeEnd a následující přiřazení do jednoho příkazu, který má
jako parametr seznamy hodnot.
Předpokládejme například, že máme formulář s datovou množinou
třídy TTable se jménem Zakaznik, připojeným k tabulce
ZAKAZNIK. Tabulka ZAKAZNIK je indexována podle první
položky (CISLO_ZAK). Nechť má formulář také dvě editační pole
pojmenované Prvni_hod a Posledni_hod a nechť byla pro
položku CISLO_ZAK vytvořena instance třídy TField. Potom
omezíme interval zobrazených záznamů použitím následujících příkazů:
Za zmínku stojí to, že program před přiřazením koncové hodnoty
intervalu testuje, zda text zadaný do editačního pole
Posledni_hod není prázdný. Pokud je prázdný text
v Prvni_hod, jsou zahrnuty všechny záznamy od začátku tabulky,
protože všechny hodnoty jsou větší než Null. Pokud je však prázdný
text v Posledni_hod, není zahrnut žádný záznam, protože žádná
hodnota není menší než Null.
Tento program lze také přepsat pomocí funkce SetRange:
Je-li klíč složen z jedné nebo více textových položek, lze použít
hledání podle parciálních klíčů. Existuje-li například složený index pro
položky PRIJMENI a JMENO, lze použít následující
specifikaci intervalu:
Tím zahrneme všechny záznamy, kde je příjmení "Novák" nebo
abecedně větší. Zadání hodnoty může být i částečné:
Tím zahrneme všechny záznamy, kde je příjmení rovno nebo abecedně
větší než "No". Další příklad zahrnuje záznamy s příjmením rovným nebo
větším než "Novák" a křestním jménem rovným nebo větším než "J":
Vlastnost KeyExclusive udává, zda filtrovaný interval
vylučuje hranice intervalu. Implicitní hodnota je false, což
znamená, že záznamy budou zahrnuty, pokud je hodnota klíče rovna nebo
větší než zadaný začátek intervalu a rovna nebo menší než zadaný konec
intervalu. Má-li atribut KeyExclusive hodnotu true,
interval nebude obsahovat hraniční hodnoty.
Index určuje, jak budou data při zobrazení setříděna. Delphi
implicitně zobrazuje data vzestupně na základě hodnot primárního klíče
tabulky.
Delphi podporuje SQL indexy, udržované indexy pro tabulky typu
Paradox a .MDX indexy pro tabulky typu Dbase. Delphi nepodporuje:
Metoda GetIndexNames vrací seznam jmen indexů použitelných
pro zpracovávanou tabulku. Pro tabulky typu Paradox je primární index
bezejmenný a není tedy v seznamu metody GetIndexNames zahrnut.
Potřebujeme-li použít u tabulek typu Paradox primární index, přiřadíme
atributu IndexName příslušné datové množiny třídy TTable
prázdný řetězec.
IndexFields obsahuje seznam jmen položek, pro něž je vytvořen
index. IndexFieldCount obsahuje počet položek v indexu.
IndexFieldCount a IndexFields jsou vlastnosti použitelné
pouze ke čtení při běhu programu.
Vlastnost IndexName používáme pro setřídění tabulky nebo pro
hledání v tabulce podle jiného indexu než podle primárního klíče.
Jinými slovy, při použití pouze primárního indexu tabulky nemusíme
s vlastností IndexName pracovat. Při použití sekundárního indexu
je však třeba IndexName zadat.
Pro tabulky v SQL databázi udává atribut IndexFieldNames
položky, které lze při vybírání dat uvést ve frázi ORDER BY. Do tohoto
atributu zadáváme seznam jmen položek oddělených středníky. Záznamy jsou
potom tříděny podle hodnot zadaných položek. Třídění může být pouze
vzestupné. Rozlišování velkých a malých písmen závisí na použitém SQL
serveru.
Pokud chceme setřídit záznamy o zákaznících uložené v SQL
tabulce podle poštovního směrovacího čísla a o úroveň níž podle čísla
zákazníka, zadáme do atributu IndexFieldName hodnotu
Pro tabulky typu Paradox a Dbase vybere Delphi index podle položek
zadaných v IndexFieldName. Je-li zadána položka nebo položky,
pro něž není definován index, dojde k chybě.
Vlastnosti IndexName a IndexFieldName se vzájemně
vylučují. Nastavení jedné z nich maže hodnotu obsaženou v druhé
z nich.
Vlastnost Exclusive udává, zda se tabulky otevírají
s výhradním právem přístupu. Má-li hodnotu true, nemůže
s tabulkou pracovat další uživatel. Pokud s tabulkou pracuje
nějaký jiný uživatel, nelze tabulku v režimu Exclusive otevřít.
Pracujeme-li s tabulkou v SQL databázi, exklusivní zámek
umožňuje ostatním uživatelům data číst, ale neumožňuje jim je modifikovat.
Některé SQL servery nepodporují exklusivní zamykání tabulek. Bližší
informace viz dokumentace příslušného SQL serveru.
Kromě vlastností sdílených s třídou TQuery má třída
TTable některé specifické vlastnosti a metody. Některé
z nich jsou například:
V této části je uvedeno několik důležitějších metod. Kompletní
popis je v on-line helpu.
Před otevřením datové množiny třídy TTable nastavíme
vlastnost ReadOnly na hodnotu false, pokud požadujeme
právo číst i zapisovat, a na hodnotu true, pokud požadujeme
přístup pouze pro čtení. V závislosti na charakteristikách zpracovávané
tabulky může být právo zapisovat do tabulky databází poskytnuto nebo
odmítnuto.
CanModify je vlastnost datové množiny, kterou můžeme pouze
číst při běhu programu a která odráží faktická práva k dané datové
množině. Má-li ReadOnly hodnotu true, CanModify
je automaticky nastaveno na false. Má-li ReadOnly hodnotu
false, CanModify bude mít hodnotu true, pokud
databáze povoluje čtecí i zápisová práva pro danou datovou množinu a
příslušnou tabulku.
Má-li CanModify hodnotu false, tabulku lze pouze číst
a datovou množinu nelze převést do stavu "Editace" ani "Vkládání".
I v případě, že má CanModify hodnotu true, není
zaručeno, že bude uživatel moci vkládat nebo modifikovat záznamy
v tabulce. Závisí to i na dalších vlivech, například přístupových
právech k dané tabulce v SQL databázi.
Metoda GoToCurrent synchronizuje dvě instance třídy
TTable připojené k téže databázové tabulce a používající tentýž
index. Tato metoda má jako parametr instanci třídy TTable a
nastavuje kurzor na aktuální záznam této datové množiny předané jako
parametr. Například:
Vlastnosti MasterSource a MasterFields slouží
k definici vazby 1:n mezi dvěma tabulkami. Vlastnost
MasterSource odkazuje na instanci třídy TDataSource, přes
kterou jsou získávána data pro hlavní tabulku. Pokud tedy svážeme dvě
tabulky vazbou 1:n, potom může podřízená tabulka na základě tohoto odkazu
reagovat na události v hlavní tabulce.
Pro spojení tabulek na základě více položek zadáváme seznam jmen
položek oddělený středníky:
Při vytváření aplikace lze dvojitým kliknutím na vlastnost
MasterFields v Editoru objektů (nebo jednoduchým kliknutím na
tři tečky tamtéž) vyvolat Dialog pro spojování tabulek. Ten umožňuje
interaktivně provést propojení hlavní a podřízené tabulky. Rozbalovací
seznam označený "Available Indexes" ("indexy k použití") ukazuje
aktuálně existující indexy použitelné pro spojení tabulek. Pro tabulky
typu Paradox je implicitně zvoleno "Primary", což znamená použití
primárního klíče pro podřízenou tabulku. V seznamu jsou i ostatní
indexy definované pro danou tabulku.
V seznamu "Detail Fields" ("položky podřízené tabulky")
vybereme položku, kterou použijeme pro spojení na straně podřízené
tabulky, dále v seznamu "Master Fields" ("položky hlavní tabulky")
vybereme položku odkazovanou z podřízené tabulky a nakonec odešleme
tlačítko označené "Add" ("přidej"). Vybrané položky jsou zobrazeny
v seznamu "Joined Fields" ("spojené položky"), například
Pro spojování tabulek na SQL serveru není zobrazován rozbalovací
seznam "Available Indexes" a je třeba ručně vybrat spojovací položky
v obou seznamech "Master Fields" a "Detail Fields".
Prvky třídy TDataSource slouží jako spojky mezi datovými
množinami a databázovými ovládacími prvky. Většinou je jedinou akcí
prováděnou s prvky třídy TDataSource nastavení jejich vlastnosti
DataSet na odpovídající datovou množinu. Potom nastavíme
vlastnost DataSource příslušného databázového ovládacího prvku tak,
aby odkazovala na příslušnou instanci třídy TDataSource. Třída
TDataSource se používá i pro spojení datových množin vazbou 1:n.
Třída TDataSource má kromě standardních vlastností Name
a Tag pouze několik málo dostupných vlastností.
Vlastnost DataSet obsahuje jméno datové množiny,
která je pro daný prvek třídy TDataSource zdrojem dat. Vlastnost
DataSet lze nastavit i na datovou množinu z jiného formuláře a
synchronizovat tak databázové ovládací prvky v obou formulářích.
Příklad:
Vlastnost Enabled umožňuje dočasně odpojit TDataSource
od příslušné datové množiny. Nastavíme-li tuto vlastnost na false,
všechny připojené databázové ovládací prvky zůstanou neaktivní až do doby,
kdy nastavíme tuto vlastnost opět na hodnotu true.
Obecně bývá vhodnější použít pro tuto funkci metody
DisableControls a EnableControls datové množiny, protože
ovlivňují všechny připojené objekty třídy TDataSource.
Vlastnost AutoEdit udává, zda datová množina připojené
k tomuto prvku třídy TDataSource automaticky přechází do stavu
"Editace", když uživatel začne psát do připojených databázových ovládacích
prvků. Má-li vlastnost nastavenu (implicitní) hodnotu true, Delphi
automaticky převádí datovou množinu do stavu "Editace", pokud uživatel
zahájí vstup do některého z připojených databázových ovládacích prvků.
V opačném případě přechází datová množina do stavu "Editace" pouze
v případě, když aplikace explicitně vyvolá její metodu Edit.
Bližší informace o stavech datových množin viz část
Stavy datových množin.
Použití třídy TTable
Vazba na databázovou tabulku
Poznámka:
Tyto vlastnosti nelze měnit, je-li tabulka otevřená -- tj. když
má vlastnost Active dané datové množiny hodnotu true.
Vlastnosti třídy TTable
Prohledávání tabulky
Použití funkcí "GoTo"
procedure PrikladVyhledani.SearchClick(Sender: TObject);
begin
Table1.SetKey;
Table1.Fields[0].AsString := Edit1.Text;
Table1.GoToKey;
end;
Table1.SetKey;
Table1.Fields[0].AsString := 'Smith';
if not Table1.GoToKey then
ShowMessage('Záznam nenalezen');
Table1.SetKey;
Table1.Fields[0].AsString := 'Sm';
Table1.GoToNearest;
Table1.IndexName := 'MestoIdx';
Table1.Open;
Table1.SetKey;
Table1.FieldByName('Mesto').AsString := Edit1.Text;
Table1.GoToNearest;
Table1.EditKey;
Table1.FieldByName('STAT').AsString := Edit2.Text;
Použití funkcí "Find"
Table1.FindKey([Edit1.Text]);
Table1.SetKey;
Table1.Fields[0].AsString := Edit1.Text;
Table1.GoToKey;
Poznámka:
Pro tabulky typu Paradox nebo Dbase lze takto pracovat pouze
s položkami, pro které je definován index. U SQL databází
lze pracovat s libovolnými položkami uvedenými v atributu
IndexFieldNames.
Vlastnost KeyExclusive
Omezení množiny záznamů získané z tabulky
Poznámka:
Pro tabulky typu Paradox a Dbase lze tyto metody použít pouze pro
položky, pro něž byl definován index. U SQL databází lze
pracovat s libovolnými položkami uvedenými ve vlastnosti
IndexFieldNames.
Zakaznik.SetRangeStart;
ZakaznikCislo_Zak.AsString := Prvni_hod.Text;
Zakaznik.SetRangeEnd;
if Posledni_hod <> '' then
ZakaznikCislo_Zak.AsString := Posledni_hod.Text;
Zakaznik.ApplyRange;
if Posledni_hod.Text <> '' then
Zakaznik.SetRange([Prvni_hod.Text], [Posledni_hod.Text]);
Zakaznik.ApplyRange;
Použití parciálních klíčů
Table1.SetRangeStart;
Table1.FieldByName('PRIJMENI').AsString := 'Novák';
Table1.SetRangeEnd;
Table1.ApplyRange;
Table1.FieldByName('PRIJMENI').AsString := 'No';
Table1.FieldByName('PRIJMENI').AsString := 'Novák';
Table1.FieldByName('JMENO').AsString := 'J';
Vlastnost KeyExclusive
Indexy
"PSC ; CISLO_ZAK"
Vlastnost Exclusive
Další vlastnosti a metody
Vlastnosti ReadOnly a CanModify
Metoda GoToCurrent
Table1(GoToCurrent(Table2));
Vytváření formulářů s vazbou 1:n
Table1.MasterFields := 'Cislo_Obj;Cislo_Pol';
Dialog pro spojování tabulek
Cislo_Obj -> Cislo_Obj
Použití třídy TDataSource
Vlastnostni třídy TDataSource
Vlastnost DataSet
procedure TForm2.FormCreate (Sender:TObject);
begin
DataSource1.DataSet := Form1.Table1;
end;
Vlastnost Enabled
Vlastnost AutoEdit
Vlastnosti třídy TField | |
---|---|
Vlastnost | Význam |
Alignement | Zobrazení obsahu položky v databázových ovládacích prvcích se zarovnáním doleva, doprava nebo centrovaně. |
Calculated | Při hodnotě true je hodnota vypočítávána při běhu programu metodou CalcFields. Při hodnotě false je hodnota převzata z aktuálního záznamu. |
Currency | Hodnota true je určena pro peněžní údaje. |
DisplayFormat | Udává formát, v němž je hodnota databázovými ovládacími prvky zobrazována. |
DisplayLabel | Udává jméno sloupce použité v mřížce. |
DisplayWidth | Udává šířku sloupce v mřížce tabulce (v počtu znaků). |
EditFormat | Udává editační formát používaný databázovými ovládacími prvky při vstupu dat. |
EditMask | Omezuje množinu vstupních znaků v editovatelné položce na zadaný typ a interval znaků a specifikuje dodatečné, needitovatelné znaky zobrazované v položce (pomlčky, závorky, apod.). |
FieldName | Udává aktuální jméno položky fyzické tabulky, z něhož odvozuje prvek třídy TField svou hodnotu a datový typ. |
Index | Udává pořadí položek v datové množině. |
MaxValue | Udává maximální numerickou hodnotu, kterou lze do dané editovatelné numerické položky zadat. |
MinValue | Udává minimální numerickou hodnotu, kterou lze do dané editovatelné numerické položky zadat. |
Name | Udává jméno položky z hlediska programového kódu Delphi. |
ReadOnly | Při hodnotě true je položka zobrazena, ale nelze ji měnit. Při hodnotě false to možné je. |
Size | Udává maximální počet znaků, který lze zobrazit nebo zapsat do textové položky, nebo velikost položek typu byte nebo var byte. |
Tag | Položka typu longint k volnému použití programátorem. |
Visible | Při hodnotě true je položka v mřížce. Prvky definované uživatelem mohou tuto položku použít k rozhodování o zobrazení nebo nezobrazení položky. Při hodnotě false není položka mřížkou zobrazována. |
Hodnotu logických vlastností (s možnou hodnotou true nebo false) lze změnit dvojitým kliknutím na danou vlastnost v Editoru objektů. Ostatní vlastnosti vyžadují zápis příslušné hodnoty nebo výběr z rozbalovacího seznamu. Všechny vlastnosti prvků třídy TField lze rovněž měnit programově.
Smysl většiny výše uvedených vlastností je zřejmý, některé vlastnosti jako např. Calculated však vyžadují při použití ještě další programátorské obraty. Některé další vlastnosti jako je DisplayFormat, EditFormat a EditMask jsou na sobě závislé a jejich nastavení musí být koordinováno. Bližší informace o použití vlastnosti Calculated obsahuje část Stanovení hodnoty vypočítávané položky. Bližší informace k vlastnostem DisplayFormat, EditFormat a EditMask obsahuje část Formátování položek.
Atribut EditMask umožňuje omezit vstup zadávaný uživatelem do databázového ovládacího prvku připojenému k položce. Konkrétní editační masku lze buď přímo zapsat nebo ji lze vytvořit pomocí Editoru vstupní masky.
Editor vstupní masky otevřeme po výběru prvku třídy TField dvojitým kliknutím na vlastnost EditMask v Editoru objektů nebo kliknutím na tři tečky ve sloupci Values.
V seznamu "Sample Masks" lze vybrat některý ze zobrazených vzorů vstupních masek. Ten je potom možno upravit editací v textovém editačním poli "Input Mask". Povolený vstup je možno otestovat v editačním poli "Test Input". Bližší informace viz on-line help.
Poznámka:
U třídy TStringField je vlastnost EditMask použita
také jako zobrazovací formát.
Formátovací procedury třídy TField | |
---|---|
Procedura | Používaná pro třídy ... |
FormatFloat | TFloatField, TCurrencyField |
FormatDateTime | TDateField, TTimeField, TDateTimeField |
FormatInteger | TIntegerField, TSmallintField, TWordField |
Formátovací procedury používají lokální nastavení z Ovládacího panelu Windows k rozhodnutí, jak zobrazit datum, čas, peněžní hodnoty a numerické hodnoty. Toto implicitní nastavení je možné změnit buď úpravou DisplayFormat a EditFormat nebo lze použít událost OnGetText a OnSetText prvku třídy TField k vlastnímu programovému formátování.
Pro úpravu událostí u vybraného prvku třídy TField vybereme v Editoru objektů skupinu "Events". Zveřejněné události shrnuje následující tabulka:
Zveřejněné události třídy TField | |
---|---|
Událost | Význam |
OnChange | Je provedena při změně hodnoty prvku. |
OnGetText | Je provedena při získání hodnoty prvku pro zobrazení nebo editaci. |
OnSetText | Je provedena při zápisu hodnoty prvku. |
OnValidate | Je volána pro provedení validace při změně nebo vložení hodnoty. |
Události OnGetText a OnSetText jsou určeny především pro vlastní formátování přesahující možnosti vestavěných funkcí Delphi jako jsou FormatFloat nebo FormatDate.
Třída TField obsahuje metodu FocusControl, která umožňuje, aby událost aktivovala první databázový ovládací prvek přiřazený danému prvku této třídy. To je podstatné hlavně pro validaci záznamu (např. při provádění události BeforePost třídy TTable), protože validaci prvku TField lze provádět bez ohledu na to, zda je přiřazený databázový ovládací prvek právě aktivován.
Třída TField obsahuje funkce pro konverzi mezi datovými typy. V závislosti na typu prvku třídy TField jsou dostupné různé konverzní funkce a tyto konverzní funkce se jinak chovají. Konverzní funkce sumarizuje následující tabulka:
Konverzní funkce třídy TField | |||||
---|---|---|---|---|---|
Typ | AsString | AsInteger | AsFloat | AsDateTime | AsBoolean |
TStringField | -- | Konverze na integer (lze-li) | Konverze na float (lze-li) | Konverze na datum (lze-li) | Konverze na boolean (lze-li) |
TIntegerField TSmallintField TWordField |
Konverze na řetězec | -- | Konverze na float | Nelze | Nelze |
TFloatField TCurrencyField TBCDField |
Konverze na řetězec | Zaokrouhlení | -- | Nelze | Nelze |
TDateTimeField TDateField TTimeField |
Konverze na řetězec (závisí na DisplayFormat) | Konverze data na počet dnů od 1.1.0001 | Konverze času na zlomek dne | -- | Nelze |
TBytesField TVarBytesField TBlobField TMemoField TGraphicField |
Konverze na řetězec (obecně má smysl pouze pro TMemoField) | Nelze | Nelze | Nelze | Nelze |
Konverzní funkce k danému prvku třídy TField lze použít na obou stranách přiřazovacího příkazu. Následující příkaz například transformuje hodnotu prvku třídy TField pojmenovaného MojePolozka na řetězec a přiřazuje ho do editačního pole Edit1:
Edit1.Text := MojePolozka.AsString;
Další příkaz naopak přiřazuje text z editačního pole Edit1 prvku třídy TField:
MojePolozka.AsString := Edit1.Text;
Pokud by měla být při běhu programu provedena nepodporovaná nebo chybná konverze, je generována výjimka.
Přístup aplikace k hodnotě položky databázové tabulky je realizován prostřednictvím vlastnosti Value daného prvku třídy TField. Následující příkaz například přiřazuje hodnotu prvku třídy TField se jménem Zakaznik_Stat do editačního ovládacího prvku Edit3:
Edit3.Text := Zakaznik_Stat.Value;
Všechny vlastnosti třídy TField dostupné z Editoru objektů jsou rovněž dostupné a nastavitelné programově. Následující příkaz například mění pořadí položek nastavením vlastnosti Index prvku Zakaznik_Stat na hodnotu 3:
Zakaznik_Stat.Index := 3;
Hodnoty z databáze lze při běhu programu zobrazovat jak pomocí standardních ovládacích prvků, tak i pomocí databázových ovládacích prvků. Kromě práce s prvky třídy TField vytvořenými Editorem položek lze při běhu programu pracovat s hodnotami uloženými v databázi ještě dalšími dvěma způsoby: pomocí vlastnosti Fields a metody FieldByName. V obou případech se jedná o přístup k hodnotám zadané položky aktuálního záznamu připojené databázové tabulky a v obou případech je vyžadována existence datové množiny, ale nikoliv prvku třídy TDataSource.
Obecně je nejvhodnější používat v databázových aplikacích databázové ovládací prvky, které jsou součástí Delphi. Tyto prvky již mají vlastnosti a metody umožňující jim napojit se na databázové položky, zobrazovat aktuální hodnotu dané položky a provádět její modifikaci. Použijeme-li standardní ovládací prvky, musíme k nim analogický programový kód doplnit sami.
K hodnotám položek lze přistupovat i prostřednictvím vlastnosti Fields datových množin udáním pořadového čísla položky v tabulce (počínaje číslem 0). Pro přístup nebo změnu hodnoty je třeba použít odpovídající konverzní funkce jako je AsString nebo AsInteger.
Tato metoda vyžaduje znalost pořadí položek v tabulce a jejich datových typů. Tuto metodu používáme, pokud chceme realizovat cyklus přes několik položek nebo pokud pracujeme s tabulkami, jejichž struktura není při vytváření programu známa.
Následující příkaz například přiřazuje aktuální hodnotu sedmé položky tabulky ZAKAZNIK editačnímu prvku Edit1:
Edit1.Text := ZAKAZNIK.Fields[6].AsString;
Naopak lze položce datové množiny (která je ve stavu "Editace") přiřadit hodnotu tak, že ji přiřadíme vlastnosti Fields této množiny:
ZAKAZNIK.Fields[6].AsString := Edit1.Text;
K hodnotě položky lze přistupovat rovněž pomocí metody FieldByName, kde pro určitou datovou množinu voláme tuto metodu FieldByName a předáme jí jako parametr jméno požadované položky. Pro přístup nebo změnu hodnoty je třeba použít odpovídající konverzní funkce jako je AsString nebo AsInteger.
Tento postup vyžaduje znalost jména položky, se kterým potřebujeme pracovat. Rovněž lze použít pro práci s databázovými tabulkami, jejichž struktura není při vytváření aplikace známa.
Následující příkaz například předává hodnotu položky STAT tabulky ZAKAZNIK do editačního pole Edit2:
Edit2.Text := ZAKAZNIK.FieldByName('STAT').AsString;
Naopak lze přiřadit hodnotu do položky datové množiny (která je ve stavu "Editace"), tak, že přiřadíme tuto hodnotu vlatnosti FieldByName:
ZAKAZNIK.FieldByName('STAT').AsString := Edit2.Text;
Prvky třídy TBatchMove umožňují provádět operace pro skupiny záznamů nebo pro celou tabulku. Hlavní použití této třídy je pro přenesení dat ze serveru do lokální aplikace (pro analýzu apod.) nebo pro přenesení databáze z osobního počítače na server ("upsizing").
TBatchMove je mocná třída, neboť umožňuje vytvářet nové tabulky na základě existujících a automaticky při tom mapovat jména sloupců a jejich datové typy.
Dvě vlastnosti třídy TBatchMove specifikují odkud a kam se budou data přesouvat -- Source udává zdrojovou datovou množinu (prvek třídy TTable nebo TQuery) odpovídající existující databázové tabulce a Destination udává prvek třídy TTable odpovídající cílové databázové tabulce. Cílová tabulka může a nemusí existovat.
Vlastnost Mode udává režim činnost daného prvku. Význam jednotlivých hodnot shrnuje následující tabulka.
Režimy prvků třídy TBatchMove | |
---|---|
Vlastnost | Význam |
batAppend | Přidává záznamy k cílové tabulce. Cílová tabulka musí existovat. Tento režim je implicitní. |
batUpdate | Modifikuje záznamy v cílové tabulce podle odpovídajících záznamů zdrojové tabulky. Cílová tabulka musí existovat a musí mít definován vhodný index. |
batAppendUpdate | Pokud v cílové tabulce existuje odpovídající záznam, je modifikován. Jinak je k cílové tabulce přidán nový záznam. Cílová tabulka musí existovat a musí mít definován vhodný index. |
batCopy | Vytváří novou tabulku se strukturou zdrojové tabulky. Cílová tabulka nesmí existovat -- pokud ano, je touto operací zrušena. |
batDelete | Ruší v cílové tabulce záznamy odpovídající zdrojové tabulce. Cílová tabulka musí existovat a musí mít definován vhodný index. |
Atribut Transliterate udává, zda se mají znaková data transformovat podle znakové množiny cílové tabulky.
Při běhu programu použijeme k provedení operace metodu Execute. Máme-li například prvek třídy TBatchMove se jménem PridejVsechno, jeho činnost je vyvolána příkazem:
PridejVsechno.Execute;
Při tvorbě programu lze provést operaci dvojitým kliknutím na prvek třídy TBatchMove a volbou "Execute". Vlastnost MoveCount obsahuje počet záznamů přesunutých při provedení operace.
Při operacích přesunu mohou v zásadě nastat dva druhy chyb: chyby konverze dat a porušení integritních omezení. Třída TBatchMove má několik vlastností, které se týkají zpracování chyb. Vlastnost AbortOnProblem udává, zda se má operace ukončit při chybě konverze. Atribut AbortOnKeyViol udává, zda se má operace ukončit při porušení integritního omezení.
Další vlastnosti umožňují vytvořit doplňkové tabulky, které dokumentují prováděnou operaci: