13. DatabßzovΘ aplikace I
  1. V tΘto a dalÜφ kapitole je uveden struΦn² ·vod do programovßnφ databßzov²ch aplikacφ v C++ Builderu. Databßze jsou data ulo₧enß ve formßtu tabulek. Tabulky obsahujφ polo₧ky jako P°ijmenφ, JmΘno, Adresa apod. Tyto polo₧ky tvo°φ jednotlivΘ zßznamy databßze. Termφn databßze je pou₧it k oznaΦenφ celΘho systΘmu vytvß°enφ a ·dr₧by dat. Databßze m∙₧e b²t jedna jednoduchß tabulka nebo takΘ stovky tabulek s miliony zßznam∙. Tabulky mohou obsahovat jeden nebo vφce index∙. SQL databßze takΘ mohou obsahovat dotazy a ulo₧enΘ procedury. Vidφme, ₧e databßze je vφce ne₧ jen tabulka s daty.

  2. Tabulka se sklßdß z polo₧ek a zßznam∙. Polo₧ky jsou jednotlivΘ kategorie dat v tabulce. Nap°. tabulka obsahujφcφ adresß° bude obsahovat polo₧ky P°φjmenφ, JmΘno, Adresa, Telefonnφ Φφslo apod. Polo₧ky takΘ n∞kdy oznaΦujeme jako sloupce. Zßznamy jsou kompletnφ informace o jednotliv²ch osobßch. Zßznam∙m takΘ n∞kdy °φkßme °ßdky. Databßze pou₧φvß ukazatel na aktußlnφ °ßdek databßze. Tomuto ukazateli °φkßme kurzor. Kurzor ukazuje na °ßdek, kter² Φteme nebo editujeme. Kurzor se p°esouvß p°i prohlφ₧enφ databßze, vklßdßnφ zßznam∙, ruÜenφ zßznam∙ apod. Kdy₧ °φkßme, ₧e kurzor je ukazatel, pak to neznamenß, ₧e se jednß o ukazatel ve smyslu C++. Je to pouze indikßtor pozice aktußlnφho zßznamu.
    Kolekce dat vracenß databßzφ se naz²vß datovß mno₧ina. Datovß mno₧ina m∙₧e b²t vφce ne₧ pouhß data obsa₧enß v tabulce. M∙₧e to b²t v²sledek dotazu kombinujφcφ data z mnoha tabulek. Nap°. m∙₧eme mφt databßzi obsahujφcφ jmΘna a adresy sv²ch zßkaznφk∙, jejich objednßvek a °ßdk∙ objednßvek. Tato data mohou b²t obsa₧ena v tabulkßch Zßkaznφk, Objednßvka a ╪ßdek objednßvky. M∙₧eme mφt po₧adavek na zjiÜt∞nφ detail∙ o deseti poslednφch objednßvkßch jistΘho zßkaznφka. Je tedy nutno zφskat informace ze vÜech t∞chto tabulek. I kdy₧ data pochßzejφ z n∞kolika r∙zn²ch tabulek, stßle jsou prezentovßny jako jedna datovß mno₧ina.
    NejjednoduÜÜφ typ databßze je lokßlnφ databßze. Lokßlnφ databßze je databßze, kterß je umφst∞na pouze na jednom poΦφtaΦi. P°edpoklßdejme, ₧e pot°ebujeme uklßdat seznam jmen a adres. M∙₧eme vytvo°it lokßlnφ databßzi k ulo₧enφ t∞chto dat. Tato databßze se pravd∞podobn∞ bude sklßdat z jednΘ tabulky. K tΘto tabulce budeme p°istupovat pouze naÜφm programem. VÜechny provedenΘ zm∞ny budou zapsßny p°φmo do tΘto tabulky. Databßze Paradox, dBASE a Access jsou obvykle lokßlnφmi databßzemi.
    Jsou takΘ databßze typu klient/server. Tyto databßze jsou ulo₧eny a udr₧ovßny na poΦφtaΦi serveru a m∙₧e k nim p°istupovat jeden nebo vφce u₧ivatel∙ (klient∙). Pou₧φvßnφ tohoto typu databßzφ je provßd∞no prost°ednictvφm sφt∞. Proto₧e u₧ivatel∙ b²vß obvykle vφce, m∙₧e se jich najednou pokusit vφce o p°φstup k databßzi. Tφm vznikajφ problΘmy soub∞₧nΘho databßzovΘho p°φstupu. U₧ivatel tohoto typu databßze nikdy nepracuje s databßzφ p°φmo. P°istupuje k databßzi pomocφ aplikace spuÜt∞nΘ na lokßlnφm poΦφtaΦi. Tyto aplikace (nazvanΘ klientskΘ aplikace) zajiÜ¥ujφ dodr₧ovßnφ jist²ch pravidel a nedovolφ ud∞lat nic, co by databßze nedokßzala zpracovat.
    Lokßlnφ databßze jsou takΘ naz²vßny jednovrstvovΘ databßze. Jednovrstvovß databßze je databßze, ve kterΘ vÜechny zm∞ny (jako je editace dat, vklßdßnφ zßznam∙ nebo ruÜenφ zßznam∙) jsou provedeny bezprost°edn∞. Program mß p°φmΘ p°ipojenφ k databßzi. U dvouvrstvov²ch databßzφ, klientskß aplikace pracuje s databßzov²m serverem prost°ednictvφm databßzov²ch ovladaΦ∙. Databßzov² server je zodpov∞dn² za vytvo°enφ p°ipojenφ. Klientskß aplikace odpovφdß za to, ₧e do databßze budou zapsßny sprßvnΘ informace.
    Ve vφcevrstvovΘ architektu°e klient/server, klientskß aplikace vyu₧φvß aplikaΦnφ slu₧by databßzovΘho serveru. Tyto programy st°ednφ vrstvy se naz²vajφ serverovskΘ aplikace, proto₧e slou₧φ klientsk²m aplikacφm. Jedna aplikace m∙₧e zodpovφdat za zpracovßnφ datov²ch po₧adavk∙ klient∙ a jejich p°edßnφ serveru. Jinß aplikace m∙₧e zajiÜ¥ovat bezpeΦnost dat. KlientskΘ aplikace b∞₧φ na lokßlnφch poΦφtaΦφch, serverovΘ aplikace obvykle na serveru a samotnß databßze m∙₧e b²t i na jinΘm serveru. Idea vφcevrstvovΘ architektury je, ₧e klientskΘ aplikace mohou b²t velmi malΘ, proto₧e v∞tÜinu prßce provedou serverovΘ aplikace. To umo₧≥uje vytvß°et aplikace, kterΘ naz²vßme tenk² klient.
    Jin² d∙vod k pou₧itφ vφcevrstvovΘ architektury je sprßva programovacφch zdroj∙. KlientskΘ aplikace mohou b²t vytvß°eny mΘn∞ zkuÜen²mi pracovnφky, proto₧e tyto aplikace pracujφ se serverov²mi aplikacemi, kterΘ °φdφ p°φstup k samotnΘ databßzi. ServerovΘ aplikace vytvß°ejφ zkuÜenφ programßto°i, kte°φ znajφ pravidla se kter²mi databßze musφ pracovat a musφ takΘ zajistit bezpeΦnost dat.
  3. K umo₧n∞nφ p°φstupu k databßzφm, C++ Builder poskytuje BDE (Borland Database Engine). BDE je kolekce DLL a ovladaΦ∙, kterΘ umo₧≥ujφ p°istupovat k r∙zn²m databßzφm. OvladaΦe BDE p°eklßdajφ databßzovΘ p°φkazy vyÜÜφ ·rovn∞ (jako Open nebo Post) na p°φkazy jistΘho typu databßze. To umo₧≥uje naÜφ aplikacφ p°ipojit se k n∞jakΘmu typu databßze a to bez nutnosti v∞d∞t, jak tato databßze pracuje.

  4. OvladaΦe, kterΘ jsou nainstalovßny na naÜem poΦφtaΦi, zßvisφ na verzi C++ Builderu, kterou vlastnφme. VÜechny verze umo₧≥ujφ p°ipojenφ k databßzφm Paradoxu a dBASE. Tento ovladaΦ nazvan² STANDARD umo₧≥uje pracovat s lokßlnφmi databßzemi. VyÜÜφ verze umo₧≥ujφ pracovat s dalÜφmi databßzemi.
    BDE pou₧φvß pro p°φstup k jistΘ databßzi p°ezdφvku. P°ezdφvka BDE je mno₧ina parametr∙, kterΘ popisujφ databßzovΘ p°ipojenφ.
    K zobrazenφ seznamu existujφcφch p°ezdφvek provedeme tyto kroky: zaΦneme v²voj novΘ aplikace a na formulß° umφstφme komponentu Table (je na strßnce DataAccess Palety komponent). Seznam p°ezdφvek je uveden v rozbalovacφm seznamu vlastnosti DatabaseName tΘto komponenty. Kdy₧ vybereme n∞jakou p°ezdφvku, pak v rozbalovacφm seznamu vlastnosti TableName vidφme dostupnΘ tabulky.
    Verze Client/Server C++ Builderu poskytuje mimo BDE i SQL Links. Jednß se o kolekci dalÜφch ovladaΦ∙. Tyto ovladaΦe umo₧≥ujφ aplikacφm C++ Builderu p°φmΘ p°ipojenφ k databßzφm firem Oracle, InterBase, Informix, Sybase a Microsoft.
  5. Nynφ se pokusφme vytvo°it jednoduchou databßzovou aplikaci. Nejprve si ale n∞co °ekneme o databßzov²ch komponentßch VCL. DatabßzovΘ komponenty je mo₧no rozd∞lit do dvou skupin: na nevizußlnφ komponenty datovΘho p°φstupu a na vizußlnφ datovΘ komponenty. Nevizußlnφ komponenty datovΘho p°φstupu poskytujφ mechanismus umo₧≥ujφcφ zφskßvat data (jsou na strßnce DataAccess Palety komponent) a vizußlnφ datovΘ komponenty umo₧≥ujφ prohlφ₧et a editovat tato data (jsou na strßnce Data Controls). Komponenty datovΘho p°φstupu jsou odvozeny od TDataSet a zahrnujφ t°φdy TTable, TQuery a TStoredProc. Mezi vizußlnφ komponenty pat°φ TDBEdit, TDBListBox, TDBGrid a dalÜφ. Tyto komponenty pracujφ jako standardnφ TEdit, TListBox, atd. s tou odchylkou, ₧e jsou spojeny s jistou tabulkou nebo polo₧kou v tabulce. Editacφ t∞chto komponent editujeme takΘ p°ipojenou databßzi.

  6. Pou₧itφ t∞chto komponent si nynφ ukß₧eme na p°φkladu. Budeme pot°ebovat n∞jak² databßzov² soubor (v nßsledujφcφch zadßnφch budou pot°eba dalÜφ soubory). Stßhneme si je. Jak ji₧ vφme vlastnost DatabaseName je urΦena k volb∞ p°ezdφvky BDE. Pro lokßlnφ databßze je vhodn∞jÜφ mφsto v²b∞ru p°ezdφvky, zadat zde p°φmo adresß°, ve kterΘm jsou databßzovΘ soubory ulo₧eny. Rozbalovacφ seznam vlastnosti TableName pak obsahuje seznam databßzov²ch soubor∙ v tomto adresß°i.
    ZaΦneme v²voj novΘ aplikace. Na formulß° umφstφme komponentu Table a zm∞nφme jejφ vlastnost DatabaseName na adresß°, do kterΘho jsme ulo₧ili sta₧enΘ soubory a vlastnost TableName na ANIMALS.DBF. Na formulß° dßle umφstφme komponentu DataSource a nastavφme jejφ vlastnost DataSet na Table1 (vybereme v rozbalovacφm seznamu). Datov² zdroj je nynφ spojen s datovou mno₧inou Table1. Na formulß° takΘ p°idßme komponentu DBGrid a zm∞nφme jejφ vlastnost DataSource na DataSource1. Tφm je m°φ₧ka p°ipojena k datovΘmu zdroji a tedy nep°φmo k datovΘ mno₧in∞. U komponenty Table nynφ zm∞nφme vlastnost Active na true a data mßme zobrazena v tabulce.
    Na formulß° p°idßme jeÜt∞ komponentu DBImage, zm∞nφme jejφ vlastnost DataSource na DataSource1 a vlastnost DataField na BMP (tato polo₧ka tabulky Animals.DBF obsahuje obrßzek). Na formulß° umφstφme komponentu DBNavigator a nastavφme vlastnost DataSource na DataSource1.
    Nynφ ji₧ program m∙₧eme spustit a pomocφ tlaΦφtek Navigßtora prochßzet zßznamy tabulky. To vÜe bez zßpisu °ßdku k≤du. Komponenty datovΘho p°φstupu jsou pou₧ity pro p°ipojenφ k databßzi a k jistΘ tabulce v databßzi. Komponenta Table je pou₧ita pro p°φstup k databßzovΘ tabulce. Je to nejjednoduÜÜφ zp∙sob zp°φstupn∞nφ dat v tabulce. Komponenta Query zp°φstup≥uje data tabulek pomocφ p°φkaz∙ SQL. Komponenta StoredProc umo₧≥uje zp°φstupnit databßzi prost°ednictvφm ulo₧en²ch procedur. Ulo₧enß procedura je kolekce databßzov²ch p°φkaz∙, kterΘ provßd∞jφ jednu nebo vφce akcφ v databßzi. Ulo₧enΘ procedury se obvykle pou₧φvajφ pro °adu databßzov²ch p°φkaz∙, kterΘ se Φasto opakujφ.
  7. TDataSet je p°edch∙dce t°φd TTable, TQuery a TStoredProc. V∞tÜina vlastnostφ, metod a udßlostφ t∞chto t°φd je definovßna v TDataSet. Zßkladnφ vlastnosti TDataSet jsou popsßny v nßsledujφcφ tabulce:

  8.  
    Vlastnost Popis
    Active Otevφrß datovou mno₧inu p°i nastavenφ na true a uzavφrß ji p°i nastavenφ na false.
    AutoCalcFields UrΦuje zda jsou vypoΦφtßvßny poΦitatelnΘ polo₧ky.
    Bof Vracφ true, pokud kurzor je na prvnφm zßznamu v datovΘ mno₧in∞ a false nenφ-li.
    CachedUpdates P°i nastavenφ na true, aktualizace jsou dr₧eny ve vyrovnßvacφ pam∞ti na klientsk²m poΦφtaΦi dokud celß transakce nenφ kompletnφ. P°i nastavenφ na false jsou vÜechny zm∞ny zapisovßny ihned do databßze.
    CanModify UrΦuje, zda u₧ivatel m∙₧e modifikovat data v datovΘ mno₧in∞.
    DataSource Komponenta DataSource p°i°azenß k tΘto datovΘ mno₧in∞.
    DatabaseName JmΘno souΦasn∞ pou₧φvanΘ databßze.
    Eof Vracφ true, pokud kurzor je na poslednφm zßznamu a false nenφ-li.
    FieldCount PoΦet polo₧ek v datovΘ mno₧in∞. Proto₧e datovß mno₧ina m∙₧e b²t dynamickß (nap°. v²sledek dotazu), poΦet polo₧ek se m∙₧e m∞nit.
    Fields Pole objekt∙ TFields, kterΘ obsahujφ informace o polo₧kßch v datovΘ mno₧in∞.
    FieldValues Vracφ hodnotu specifikovanΘ polo₧ky souΦasnΘho zßznamu. Jednß se o datov² typ Variant.
    Filter V²raz urΦujφcφ, kterΘ zßznamy mß datovß mno₧ina obsahovat.
    Filtered P°i nastavenφ na true datovß mno₧ina je filtrovßna.
    FilterOptions UrΦuje, jak je filtr pou₧it.
    Found UrΦuje zda operace Find je ·sp∞Ünß.
    Handle Madlo kurzoru BDE datovΘ mno₧iny. Pou₧φvß se pouze p°i p°φmΘm volßnφ BDE.
    Modified Indikuje, zda souΦasn² zßznam byl modifikovßn.
    RecNo ╚φslo souΦasnΘho zßznamu v datovΘ mno₧in∞.
    RecordCount Vracφ poΦet zßznam∙ v datovΘ mno₧in∞.
    State Vracφ souΦasn² stav datovΘ mno₧iny (dsEdit, dsBrowse, dsInsert apod.).
    UpdateObject UrΦuje komponentu TUpdateObject pou₧φvanou pro odlo₧enΘ aktualizace.
    UpdatesPending Je-li true, pak vyrovnßvacφ pam∞¥ odlo₧en²ch aktualizacφ obsahuje zm∞ny, kterΘ nejsou aplikovßny na datovou mno₧inu.

    DalÜφ tabulka obsahuje popis zßkladnφch metod TDataSet.
     

    Metoda Popis
    Append Vytvß°φ prßzdn² zßznam a p°idßvß jej na konec datovΘ mno₧iny.
    AppendRecord P°idßvß zßznam s dan²mi daty na konec datovΘ mno₧iny.
    ApplyUpdates Povoluje databßzi aplikovat odlo₧enΘ aktualizace. Aktualizace nejsou zapsßny, pokud nenφ volßna metoda CommitUpdates.
    Cancel ZruÜφ vÜechny zm∞ny provedenΘ v souΦasnΘm zßznamu.
    CancelUpdates ZruÜφ odlo₧enΘ aktualizace.
    ClearFields ZruÜφ obsah vÜech polo₧ek souΦasnΘho zßznamu.
    CommitUpdates Aplikuje odlo₧enΘ aktualizace a vyprßzdnφ vyrovnßvacφ pam∞¥ odlo₧en²ch aktualizacφ.
    Close Uzavφrß datovou mno₧inu.
    Delete RuÜφ souΦasn² zßznam.
    DisableControls Zakazuje vstup do datov²ch ovladaΦ∙ p°i°azen²ch k datovΘ mno₧in∞.
    Edit Povoluje editaci souΦasnΘho zßznamu.
    EnableControls Povoluje vstup do datov²ch ovladaΦ∙ p°i°azen²ch k datovΘ mno₧in∞.
    FetchAll Zφskßvß vÜechny zßznamy od kurzoru do konce datovΘ mno₧iny a uklßdß je lokßln∞.
    FieldByName Vracφ ukazatel TField na jmΘno polo₧ky.
    FindFirst Hledß prvnφ zßznam odpovφdajφcφ filtrovacφm kritΘriφm.
    FindNext Hledß dalÜφ zßznam odpovφdajφcφ filtrovacφm kritΘriφm.
    FindLast Hledß poslednφ zßznam odpovφdajφcφ filtrovacφm kritΘriφm.
    FindPrior Hledß p°edchßzejφcφ zßznam odpovφdajφcφ filtrovacφm kritΘriφm.
    FreeBookmark RuÜφ d°φve nastavenΘ zßlo₧ky pomocφ GetBookmark a uvol≥uje pam∞¥ alokovanou pro zßlo₧ky.
    GetBookmark Nastavuje zßlo₧ku na souΦasn² zßznam.
    GetFieldNames Zφskßvß seznam jmen polo₧ek v datovΘ mno₧in∞.
    GotoBookmark Umφs¥uje kurzor na zßznam urΦen² specifikovanou zßlo₧kou.
    Insert Vklßdß zßznam a uvßdφ datovou mno₧inu do editaΦnφho re₧imu.
    InsertRecord Vklßdß zßznam s dan²mi daty do datovΘ mno₧iny.
    Last P°esouvß ukazatel na poslednφ zßznam v datovΘ mno₧in∞.
    Locate Hledß v datovΘ mno₧in∞ jist² zßznam.
    Lookup Lokalizuje zßznam a vracφ data obsa₧enß v zßznamu.
    MoveBy P°esouvß kurzor o specifikovan² poΦet zßznam∙.
    Next P°esouvß kurzor na nßsledujφcφ zßznam.
    Open Otevφrß datovou mno₧inu.
    Post Zapisuje modifikovanß data do databßze nebo je uklßdß do vyrovnßvacφ pam∞ti odlo₧en²ch zm∞n.
    Prior P°esouvß kurzor na p°edchßzejφcφ zßznam.
    Refresh Aktualizuje data v datovΘ mno₧in∞ z databßze.
    RevertRecord Kdy₧ jsou pou₧ity odlo₧enΘ aktualizace, pak tato metoda zruÜφ d°φve provedenΘ zm∞ny na zßznamu, ale nezapφÜe je do databßze.
    SetFields Nastavuje hodnoty pro vÜechny polo₧ky v zßznamu.
    UpdateStatus Vracφ souΦasn² stav aktualizace p°i povolenΘ odlo₧enΘ aktualizaci.

    V poslednφ tabulce jsou uvedeny zßkladnφ udßlosti TDataSet:
     

    Udßlost Popis
    AfterCancel Generovßna po zruÜenφ editace zßznamu.
    AfterClose Generovßna po uzav°enφ datovΘ mno₧iny.
    AfterDelete Generovßna po zruÜenφ zßznamu v datovΘ mno₧in∞.
    AfterEdit Generovßna po editovßnφ zßznamu.
    AfterInsert Generovßna po vlo₧enφ zßznamu.
    AfterOpen Generovßna po otev°enφ datovΘ mno₧iny.
    AfterPost Generovßna po odeslßnφ zm∞n do databßze.
    BeforeCancel Generovßna p°ed zruÜenφm editace zßznamu.
    BeforeClose Generovßna p°ed uzav°enφm datovΘ mno₧iny.
    BeforeDelete Generovßna p°ed zruÜenφm zßznamu.
    BeforeEdit Generovßna p°ed uvedenφm datovΘ mno₧iny do editaΦnφho re₧imu.
    BeforeInsert Generovßna p°ed vlo₧enφm zßznamu.
    BeforeOpen Generovßna p°ed otev°enφm datovΘ mno₧iny (mezi nastavenφm Active na true a Φasem skuteΦnΘho otev°enφ datovΘ mno₧iny).
    BeforePost Generovßna p°ed odeslßnφm zm∞n do databßze.
    OnCalcFields Generovßna, kdy₧ jsou provßd∞ny v²poΦty poΦitateln²ch polo₧ek.
    OnDeleteError Generovßna v p°φpad∞ n∞kter²ch chyb p°i ruÜenφ zßznamu.
    OnEditError Generovßna v p°φpad∞ n∞kter²ch chyb p°i editaci zßznamu.
    OnFilterError Generovßna p°i zp°φstup≥ovßnφ novΘho °ßdku, kdy₧ Filtered je nastaveno na true.
    OnNewRecord Generovßna p°i p°idßnφ novΘho zßznamu do datovΘ mno₧iny.
    OnPostError Generovßna v p°φpad∞ n∞kter²ch chyb p°i zßpisu aktualizace zßznamu.
    OnUpdateError Generovßna v p°φpad∞ n∞kter²ch chyb p°i zßpisu odlo₧en²ch aktualizacφ do datovΘ mno₧iny.
    OnUpdateRecord Generovßna, kdy₧ odlo₧enΘ zm∞ny jsou aplikovßny na zßznam.
  9. Potomci TDataSet (TTable, TQuery a TStoredProc) umo₧≥ujφ pou₧φvat b∞hem nßvrhu Editor polo₧ek. Tento Editor umo₧≥uje vybrat polo₧ky, kterΘ chceme vlo₧it do datovΘ mno₧iny. K zobrazenφ Editoru polo₧ek zvolφme v mφstnφ nabφdce komponenty Table, Query nebo StoredProc volbu Fields Editor. Editor polo₧ek je nejprve prßzdn², co₧ znamenß, ₧e do datovΘ mno₧iny jsou ulo₧eny vÜechny polo₧ky. Po₧adovanΘ polo₧ky m∙₧eme p°idat do datovΘ mno₧iny volbou Add field v mφstnφ nabφdce. Volbou New field v mφstnφ nabφdce lze takΘ vytvß°et novΘ polo₧ky.

  10. Po p°idßnφ polo₧ek k datovΘ mno₧in∞, lze n∞kterou polo₧ku vybrat a modifikovat jejφ vlastnosti (v Inspektoru objekt∙). Lze m∞nit formßt zobrazenφ, omezenφ a dalÜφ charakteristiky polo₧ky.
  11. Odlo₧enß aktualizace umo₧≥uje urΦit, zda zm∞ny jsou provßd∞ny ihned v databßzi. Odlo₧enß aktualizace je °φzena vlastnostφ CachedUpdates. Kdy₧ odlo₧enß aktualizace je povolena, pak provedenΘ zm∞ny nejsou zapsßny do databßze, ale jsou ulo₧eny ve vyrovnßvacφ pam∞ti na lokßlnφm poΦφtaΦi. Zde jsou ulo₧eny dokud je metodou ApplyUpdates nezapφÜeme do databßze. Pro zruÜenφ zm∞n ulo₧en²ch ve vyrovnßvacφ pam∞ti volßme metodu CancelUpdates. ZruÜenφ zm∞n proveden²ch na souΦasnΘm zßznamu provedeme volßnφm RevertRecord.

  12. Pokud odlo₧enß aktualizace je zakßzßna (CachedUpdates je false), pak vÜechny provedenΘ zm∞ny v souΦasnΘm zßznamu jsou zapsßny do databßze, kdy₧ kurzor opustφ zßznam. Je to vhodnΘ °eÜenφ pro lokßlnφ databßze, ale z mnoha d∙vod∙ to nenφ vhodnΘ pro databßze typu klient/server. Pou₧itφ odlo₧enΘ aktualizace nap°. sni₧uje p°enos dat po sφti.
    Mnoho databßzφ typu klient/server vracφ jako v²sledek dotazu v²sledkovou mno₧inu urΦenou pouze pro Φtenφ. Jednou z v²hod odlo₧enΘ aktualizace je to, ₧e klient m∙₧e pracovat s lokßlnφ kopiφ datovΘ mno₧iny (urΦenΘ pouze pro Φtenφ), modifikovat ji podle pot°eby a potom zapsat vÜechny provedenΘ zm∞ny do databßze najednou. To je mo₧nΘ, proto₧e databßzov² server zpracuje aktualizace, vklßdßnφ a ruÜenφ zßznam∙ z datovΘ mno₧iny urΦenΘ pouze pro Φtenφ. Lokßlnφ databßze mß uzamΦeny zßznamy, kdy₧ jsou editovßny. Pokud je zßznam uzamΦen, pak ostatnφ u₧ivatele databßze k tomuto zßznamu nemohou p°istupovat. Pou₧itφ odlo₧enΘ aktualizace zkracuje Φas uzamΦenφ zßznamu.
    DalÜφ v²hodou odlo₧enΘ aktualizace je to, ₧e u₧ivatel m∙₧e provΘst n∞kolik zm∞n na datovΘ mno₧in∞, a potom vÜechny tyto zm∞ny zapsat nebo je vÜechny zruÜit (pokud nenφ mo₧no zapsat vÜechny zm∞ny, pak je vhodnΘ vÜechny zruÜit). Nev²hodou odlo₧enΘ aktualizace je to, ₧e umo₧≥uje n∞kolika u₧ivatel∙m najednou m∞nit stejn² zßznam. Tento problΘm je mo₧no omezit implementacφ technik v klientskΘ aplikaci, kterΘ testujφ, zda zßznam nemodifikoval jin² u₧ivatel.
  13. Komponenta Table (reprezentovanß t°φdou TTable) poskytuje rychl² a jednoduch² p°φstup k tabulce. Obvykle pou₧φvßme komponentu Table p°i prßci s lokßlnφmi databßzemi a komponentu Query p°i prßci s databßzov²mi SQL servery.

  14. T°φda TTable p°idßvß ke svΘmu p°edkovi TDataSet n∞kolik vlastnostφ a metod. Nap°. metody LockTable a UnlockTable slou₧φ k uzamykßnφ a odemykßnφ tabulky. U t∞chto metod, je nßm ji₧ z jejich jmΘna jasnΘ, co d∞lajφ. TotΘ₧ je mo₧no °φci o metodßch CreateTable, DeleteTable a RenameTable.
  15. DatabßzovΘ aplikace Φasto pot°ebujφ filtrovat tabulku. Toto je hlavn∞ pou₧φvßno pro lokßlnφ databßze. U databßzφ typu klient/server je v²hodn∞jÜφ namφsto filtru pou₧φt dotaz SQL. Co je to filtr? P°edpoklßdejme, ₧e mßme tabulku s mnoha zßznamy, ale zajφmß nßs pouze malß podmno₧ina tΘto tabulky (pouze n∞kolik °ßdk∙). M∙₧eme tedy zadat filtr, kter² propustφ pouze po₧adovanΘ °ßdky.

  16. Filtry v komponent∞ Table jsou realizovßny dv∞ma zp∙soby: prost°ednictvφm vlastnosti Filter nebo udßlostφ OnFilterRecord. Nejprve si °ekneme n∞co o vlastnosti Filtered. Tato vlastnost urΦuje, zda tabulka je filtrovßna. Mß-li tato vlastnost hodnotu true, pak na tabulku je aplikovßn filtr (obsa₧en² ve vlastnosti Filter nebo v²sledek obsluhy udßlosti OnFilterRecord). Mß-li Filtered hodnotu false, pak obsah vlastnosti Filter je ignorovßn a udßlost OnFilterRecord nenφ generovßna. Vlastnost Filter zapisujeme jako jmΘno polo₧ky, operßtor a hodnotu. Nap°.
    FirstName = 'Bob'
    Tento p°φkaz nßm °φkß: Zobraz vÜechny zßznamy, ve kter²ch k°estnφ jmΘno je Bob. Filtry takΘ mohou obsahovat slo₧it∞jÜφ podmφnky. Nap°.
    CustNo = 1384 AND ShipDate < '1.1.94'
    Ve jmΘnech polo₧ek a v operßtorech nenφ rozliÜovßna velikost pφsmen, u textov²ch konstant rozliÜovßnφ velikosti pφsmen je urΦeno hodnotou vlastnosti FilterOptions.
    V p°φkazech filtr∙ mohou b²t pou₧ity nßsledujφcφ operßtory (pozor nejednß se o operßtory C++):
     
    Operßtor V²znam
    < menÜφ ne₧
    > v∞tÜφ ne₧
    = rovno
    <> nerovno
    >= v∞tÜφ nebo rovno
    <= menÜφ nebo rovno
    () zm∞na priority jednotliv²ch operßtor∙
    [] pou₧φvß se okolo jmen polo₧ek, kterΘ obsahujφ mezery
    AND, OR, NOT logickΘ operßtory
  17. Hodnotu vlastnosti Filter lze nastavit v Inspektoru objekt∙ p°i nßvrhu nebo p°i°azenφm °et∞zcovΘ hodnoty za b∞hu. Ukß₧eme si to na jednoduchΘ aplikaci. ZaΦneme s v²vojem novΘ aplikace a na formulß° umφstφme komponenty Table, DataSource a DBGrid. U komponenty Table zm∞nφme vlastnost DatabaseName na adresß°, do kterΘho jsme si ulo₧ili databßzovΘ soubory sta₧enΘ na zaΦßtku tΘto kapitoly, vlastnost TableName zm∞nφme na ORDERS.DB a Active na true. U komponenty DataSource nastavφme vlastnost DataSet na Table1. Komponentu DBGrid zv∞tÜφme na cel² formulß° a zm∞nφme jejφ vlastnost DataSource na DataSource1. V m°φ₧ce se zobrazφ data a m∙₧eme se zaΦφt zab²vat jejich filtracφ. U komponenty Table zadßme jako hodnotu vlastnosti Filter

  18. CustNo = 1384
    a nastavφme vlastnost Filtered na true. Nynφ tabulka zobrazuje pouze objednßvky pro zßkaznφka 1384. M∙₧eme chvφli experimentovat s podmφnkou filtru a postupn∞ pou₧φt nßsledujφcφ hodnoty:
    CustNo = 1510
    CustNo = 1384 and ShipDate < '1.1.94'
    CustNo = 1384 and ShipDate > '1.1.94'
    OrderNo > 1100 and OrderNo < 1125
    Na formulß° p°idßme jeÜt∞ tlaΦφtko a obsluhu jeho stisku bude tvo°it p°φkaz:
    Table1->Filter = "CustNo = 1510";
    Takto lze m∞nit filtr za b∞hu aplikace. Pokud Filtered je nastaveno na true a vlastnost Filter je prßzdnß, pak zφskßme celou datovou mno₧inu.
  19. Jin²m zp∙soben filtrovßnφ tabulky je pou₧itφ udßlosti OnFilterRecord. Obsluha tΘto udßlosti m∙₧e obsahovat k≤d pro filtr tabulky. Nejprve vytvo°φme filtr, kter² nßm propustφ zßznamy s Φφslem zßkaznφka 1384 (jako v p°edchozφm p°φkladu). Tentokrßt ale k filtrovßnφ pou₧ijeme udßlost OnFilterRecord namφsto vlastnosti Filter. U komponenty Table vytvo°φme obsluhu udßlostφ OnFilterRecord s nßsledujφcφm obsahem:

  20. void __fastcall TForm1::Table1FilterRecord(TDataSet *DataSet,
                                               bool &Accept)
    {
      int Hodnota = Table1->FieldByName("CustNo")->Value;
      Accept = (Hodnota == 1384);
    }
    KlφΦov²m prvkem je zde parametr Accept. Tato udßlost je generovßna pro ka₧d² °ßdek v tabulce a pokud parametr Accept je nastaven na true, pak °ßdek je zobrazen. V naÜem p°φpad∞ parametr Accept je nastaven na true pro zßznamy, ve kter²ch polo₧ka CustNo mß hodnotu 1384. Pokud bychom cht∞li nahradit dalÜφ podmφnky filtr∙, pak m∙₧eme pou₧φt v obsluze OnFilterRecord:
    Accept = Table1->FieldByName("CustNo")->Value == 1510;
    nebo
    Accept = Table1->FieldByName("CustNo")->Value == 1510 &&
      Table1->FieldByName("ShipDate")->AsDateTime < TDateTime("1.1.94");
    atd. Pou₧φvßnφ OnFilterRecord znamenß vφce prßce, ale poskytuje v∞tÜφ mo₧nosti ne₧ vlastnost Filter.
    Vlastnost FilterOptions urΦuje, jak filtr bude aplikovßn. Tato vlastnost je typu mno₧ina a m∙₧e obsahovat prvky foCaseInsensitive a foNoPartialCompare. Implicitn∞ se jednß o prßzdnou mno₧inu, tzn. p°i filtrovßnφ se rozliÜuje velikost pφsmen a je povoleno ΦßsteΦnΘ porovnßvßnφ. P°i povolenΘm ΦßsteΦnΘm porovnßvßnφ je mo₧no ve filtru pou₧φt hv∞zdiΦku, nap°.
    LastName = "M*"
    V tomto p°φpad∞ hledßme vÜechny zßznamy u nich₧ p°φjmenφ zaΦφnß pφsmenem M.
  21. Jist² zßznam v tabulce lze hledat n∞kolika r∙zn²mi metodami. VÜechny zde uvedenΘ postupy je mo₧no aplikovat na potomky TDataSet a nejen na TTable. Pro databßze typu klient/server je op∞t v²hodn∞jÜφ pou₧φvat dotazy SQL. Pro hledßnφ ve filtrovanΘ datovΘ mno₧in∞ pou₧φvßme metody FindFirst, FindNext, FindPrior a FindLast. Tyto metody bezpeΦn∞ hledajφ zßznamy odpovφdajφcφ filtru, proto₧e filtr je aplikovßn v₧dy p°i volßnφ t∞chto metod (jsou nalezeny i modifikovanΘ zßznamy, kterΘ odpovφdajφ podmφnce filtru).

  22. Jin² zp∙sob hledßnφ v tabulce vyu₧φvß metody FindKey a GotoKey. Tyto metody vy₧adujφ index v tabulce. Metoda FindKey hledß polo₧ku primßrnφho klφΦe pro jistou hodnotu. Pokud je pou₧it i sekundßrnφ klφΦ, pak takΘ m∙₧e b²t zapojen do hledßnφ. Nßsledujφcφ p°φklad nastavuje sekundßrnφ klφΦ a potom hledß zßkaznφka Φφslo 1384:
    Table1->IndexName = "CustNo";
    if (!Table1->FindKey(&TVarRec(1384), 0))
      MessageBox(Handle, "Zßznam nenalezen", "Zprßva", MB_OK);
    T°etφ zp∙sob hledßnφ v tabulce pou₧φvß metody Locate a Lookup. V²hodou t∞chto metod je to, ₧e nevy₧adujφ klφΦ. Tyto metody se liÜφ. Metoda Locate vyu₧φvß nejrychlejÜφ dostupnou metodu pro hledßnφ v tabulce (pokud je tabulka indexovanß, pak se index pou₧ije). Metoda Lookup provede hledßnφ a vracφ hodnoty specifikovan²ch polo₧ek v nalezenΘm zßznamu. Ob∞ metody umo₧≥ujφ specifikovat prohledßvanou polo₧ku nebo polo₧ky a hledanou hodnotu. Nßsledujφcφ p°φklad ukazuje pou₧itφ metody Locate:
    TLocateOptions Options;
    Options << loPartialKey;
    if (!Table1->Locate("CustNo", "1384", Options))
      MessageBox(Handle, "Zßznam nenalezen", "Zprßva", MB_OK);
    Pokud zßznam je nalezen, pak Locate vracφ true a kurzor je p°esunut na nalezen² zßznam.
  23. Nastavenφ vzßjemnΘho vztahu master/detail komponent Table je snadnΘ. Mßme tabulku Customer, kterß obsahuje informace o naÜich zßkaznφcφch. Tato tabulka mß vytvo°en index na polo₧ce CustNo. Dßle mßme tabulku Orders, kterß obsahuje seznam vÜech objednßvek naÜich zßkaznφk∙. Tato tabulka mß takΘ polo₧ku CustNo, kterß identifikuje zßkaznφka. Chceme prohlφ₧et tabulku zßkaznφk∙ a p°i v²b∞ru n∞kterΘho zßkaznφka, chceme prohlφ₧et jeho objednßvky.

  24. ZaΦneme v²vojem novΘ aplikace a na formulß° vlo₧φme komponentu Table a nastavφme u nφ tyto vlastnosti: DatabaseName na adresß° obsahujφcφ naÜe databßzovΘ soubory a TableName na CUSTOMER.DB. Na formulß° jeÜt∞ vlo₧φme komponentu DataSource a nastavφme jejφ vlastnost DataSet na Table1. Na formulß° vlo₧φme druhou komponentu Table a druhou komponentu DataSource (vlastnost DataSet nastavφme na Table2). U druhΘ komponenty Table nastavφme DatabaseName op∞t na adresß° s databßzov²mi soubory, TableName na ORDERS.DB a MasterSource na DataSource1. Dßle klikneme na tlaΦφtko se t°emi teΦkami u vlastnosti MasterFields. Je zobrazeno dialogovΘ okno Nßvrhß°e spojenφ polo₧ek. V hornφ Φßsti tohoto okna je kombinovan² ovladaΦ Available Indexes. Zde vybereme CustNo. Nynφ majφ oba seznamy (Detail Fields i MasterFields) polo₧ku CustNo. Vybereme tuto polo₧ku v obou seznamech a stiskem tlaΦφtka Add vytvo°φme vzßjemn² vztah tabulek. Stiskem OK okno uzav°eme. Na formulß° vlo₧φme dv∞ komponenty DBGrid, jednu spojφme s DataSource1 a druhou s DataSource2. Nynφ ji₧ staΦφ u obou komponent Table zm∞nit vlastnost Active na true. Aplikace je hotova, m∙₧eme ji vyzkouÜet. Propojenφ tabulek je provedeno pomocφ spoleΦnΘ polo₧ky (CustNo).
13. DatabßzovΘ aplikace I