Download as pdf
Download as pdf
You are on page 1of 592
Marco Cantu Delphi 7 Mesteri szinten Il. kétet ic Abkiadviny a kévetkez6 angol eredeti alapjan késaiilt: Marco Canta: Mastering Delphi 7 Copyright © 2003 by SYBEX Inc. All rights reserved! No part of this book, including interior desing, cover design, and icons, may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. ‘Trademarked names appear throughout this book. Rather than list the names and entities that ‘own the trademarks or insert a trademark symbol with each mention of the trademarked name, the publisher states that it is using the names for editorial purposes only and to the benefit of the trademark owner, with no intention of infringing upon that trademark. Aszerz5k és a kiad6 a leheté legnagyobb koriltekintéssel jar el e kiadviny elkészitésekor. Sem a szer76, sem a kiad6 nem vallal semminemd felelésséget vagy garanciét a kényv tartal- aval, teljességével Kapesolatban, Sem a szer26, sem a kiadé nem vonhats felelésségre bat- milyen baleset vagy kéresemény miatt, mely kézvetve vagy kézvetlentil kapesolatba hozhats kiadvénnyal Forditis és magyar valtozat © 2003 Kiskapu Kft. Minden jog fenntarwwa! ‘Translation and Hungarian edition © 2003 Kiskapu Kft. All rights reserved! Felel6s szerkes7t6: Szy Gysrgy Lektor: Rézmifves LaszI6 Forditas: Antal Ferenc, Déczt Rrisztidn, Gilicze Balint ‘TOrdelés: Kis Péter Miszaki szerkesat6: Csuiak Hoffinann Levente Felelés kiad6 a Kiskapu Kft. Ggyvezetd igazgat6ja © 2003 Kiskapu Kft 108] Budapest, Népszinhaz u. 31., |. emelet, 7. “Telefon: (+36-1) 477-0443 Fax: (+36-1) 303-1619 hutp://kiado.kiskapu.hu/ e-mail: kiado@kiskapy.hu ISBN: 963 9301 67.1 IL, kétet 963 9301 65.5.6 Osszesité Késziilt a debreceni Kinizsi Nyomdaban FelelGs vezet6: Boras Janos Andrea Gnesutta, az olasz Delphi-kdzosség baratja emlékére, aki oly fiatalon hagyott itt minket. Tartalomjegyzék 13. fejezet A Delphi adatbézis-architaktdrdja Adatbdzis-elérés: dbExpress, helytad adatok és segye Tehewisége oo 640 A dbExpress konyvtdr ...... A Borland Database Engine Az InterBase Express... .. ‘A MyBase és a ClientDataSet komponens dbGo az ADO motorhoz Egyéni adatbézis-komponensek MyBase: OnAll6 ClientDataSet 00.0.0... Csatlakoz4s Iétez6 helyi uiblthoz ..... A Midas DLL kényvtért6l a Midaslib egységig Az XML és a CDS formatum .... Uj helyi tabla meghatdroz4sa. 20... 0... 647 Indexelés fees = 649 Satirés . - 650 Rekordok keresése 651 Az Undo €5 a SavePoint parancs 651 A naplézis ki- és bekapcsolisa 652 Az adatfelismer6 vezérldk haszndlata 653 ‘Tablaban lévé adatok « A DBNavigator és az adathalmazon végrehajthato miveletek Szbveg alapti adatfelismeré vezérldk rn Lista alapt adatfelismeré vezéridk Keres6 vezérlék hasznaiata . Grafikus adatfelismeré vezérlok . A DataSet komponens .... Az adathalmaz Allapota .... . Az adathalmazok mez6i ‘MezGobjektumok hasznalata . A mez6osztélyok hierarchidja Szimitott mezé6 felvétele Keres6 mezék ...... Null értékek kezelése mezGeseményekkel Mozgis az adathalmazban A tabla egy oszlopanak dsszege Kényvjelz6k haszndlata . A tabla egyik oszlopénak médositasa Az adatbazistabla testreszabasa .... Rajzolas az adatrécsra ... . : Tabb rekord kijelWlés6t IehetGvé tev6 tabla... Tablaba hizds ...... bees Szabvinyos vezé:l6ket hasznlo adatbazis-kezel6 alkalmazisok ...... ‘A Delphi adatfelismerd vezéri6inek uténzsa . . wes Kérelmek kildése az adatbazisba . Csoportositis és Ssszesités Csoportositis ...... Osszesitések meghatérozisa . Mester-részlet tipust felépitések ... Mester-részlettipusi felépités ClientDataSet komponensekel Az adatbazis-hibak kezelése bicceees Hogyan tovabb?.... 14. fejezet dbExpress iigyfét-kiszolgalé rendszerek Ugyfél-kiszolgalé rendszerek Az adatbazistervezés clemei Egyedek és reléciok .... Az elsdleges kulcsoktél az sols Tovabbi megszoritésok . Egyiranyt kurzorok Az InterBase ‘Az IBConsole haszndlata oo... KiszolgSl6 oldali programozis az InterBase-zel A dbExpress kényveér ‘Munka egyirinyé kurzorokkal Rendszerek és adatbazisok . . A meghajtk valtozatair6l és a * besayazo cwystacrcl : ‘A dbExpress komponensek ..... .. Az SQLConnection komponens A dbExpress adathalmaz- -komponenset Az SQLMonitor komponens . . Néhdny dbExpress bemutatéprogram . Egy komponens —tébb komponens ............0.4 79 Az adatbizisok metaadatainak elérése a SetSchemainfo segitségével .. 733 Paraméteres lekérdezések ceeteetees BA Amikor egy irany is elég: adatok nyomtatésa 736 A csomagok és az dtmeneti tar we 739 Frissitések kezelése . . 740 Az adatok frissitése .., . + 742 ‘Tranzakciok haszndlata . 745 Az InterBase Express haszndlata . 749 Az IBX adathalmaz-komponensei 749 Az IBX feliigyeleti komponensei 750 TBX példaprogram készitése .. 751 Bld lekérdezések készitése 752 Az InterBase Express figyelése 757 ‘Tovabbi rendszeradatok kiolvasisa . : Programozis a gyakorlatban . . 759 Generstorok és azonositék . » 759 Kis- és nagyberdket nem meghtilonboztets keresés cece TOL Helyek és személyek kezelése 00... wee 763 Felhasznél6i feliilet ki 765 Feliratkozas ..... . - 768 Keresési parbeszédablak késcitése | 772 Form tetszéleges Iekérdezés megadasara .... 1.774 Hogyan tovabb?..... ve det tents teeter eeeees 1.775 15. fejezet Az ADO hasznélata ‘Az MDAC (Microsoft Data Access Components) ... . . tee . 778 OLE DB szolgdltatdk . -.779 A dbGo komponensek haszndlata , .. 781 Egy gyakorlati példa .... . : Az ADOConnection komponens . Adatcsatolasi faj! nee . Dinamikus tulajdonsagok... .. - 785 Sémaadatok kinyerése - 786 A Jet adatbazismotor haszndlata - 788 A Paradox és a Jet .. _ 789 Az Excel ésa Jet ... 790 +791 793 Aszbvegiéjlok és a Jet . Import és export . . Kurzorok haszndlata .. . CursorLocation (kurzorhelyzet) . . . CursorType (kurzortipus) ‘Tipusok automatikus felilbirdlésa Arekordok sz4mar6l . Ugyfélindexek Klénozas . . Tranzakcidk feldolgozisa Bedgyazott tranzakci6k . . ‘Az ADOConnection Antibutes tlds Zéroldsi tipusok Azadatok frissitése . Kétegelt frissités Optimista zérokis : A frissitési OtkOzések feloldésa . Levalasztott rekordhalmazok . . Kapcsolatok kézds kezelése . Maradand6 rekordhalmazok Az aktataska modell. Par sz6 az ADO.NET-161 Hogyan tovabb? 16. fejezet TabbrétegG DataSnap alkalmazasok A hatom réteg — a Delphi toménetének tiikrében .. ‘A DataSnap technikai alapjai Az lAppServer felillet. Kapesolati protokollok Adatcsomagok : ‘A Delphi dgyfél oldali komponensei ‘A Delphi kiszolg4lé oldali komponensei Egy egyszerd program elkészitése ......... Az els6 alkalmazas-kiszolgal6 Az els6 vékony tigyfél . . Megszoritasok hozzdadiisa a kiszolgalohox - Mez6- és tablamegszoritasok ‘Mez6tulajdonsagok haszndlata Mez6- és tablaesemények ..... : Az tigyfél kiegészitése tovabbi selgteokal : A frissitési folyamat : Adatok frissitése . : ‘A DataSnap tovabbi lehetdségei . Paraméteres lekérdezések . Egyéni tagfliggvényhivasok Mester-részlet kapcsolatok . .. A ConnectionBroker komponens ...... Az adatszolgdltat6 tovabbi lehetdségei . . A SimpleObjectBroker emponens vee teen ee ees 843 Objektumbélesnzés ..... ce 843 Adatesomagok testreszabasa .. 843 Hogyan tovabb? . : 845 17. fejezet Adtbzis-kornponensek Ks készitése ‘Az adatkapesolat : A TDataLink osztdly Seixmaztatott adatkapesolati osztélyok vee Mez6kézpontd adatftiggd komponensek készitése . Csak olvashaté ProgressBar : {rhaté-olvashat6é TrackBar ... . Egyedi adatkapesolatok készitése Egy rekordnézegeté komponens A DBGrid komponens testreszabasa = 863, Egyedi adathalmazok készitése ... . 867 Az osztilyok meghatarozasa 868 1. szakasz: kezdeti beéllitsok, megnyités és bezéris 871 Il, szakasz: mozgatas és konyvjelz6-kezelés oe 876 IL, szakasz: rekordtirak és mezGkezelés . - 880 TV. szakasz: a tarakbdl a mezdkbe 884 A folyam alapé adathalmaz tesztelése 886 KOnyvtir az adathalmazban 887 Lista abrazolasa adathalmazként . 888 A kényvtar tartalmanak megjelenitése . .. . - 889 Adathalmaz, objektumokbél 893 Hogyan tovabb? oo... cece cee eee cette nee 997 18. fejezat Jelentések készitése a Rave segitségével ARAVE occ eee etter etree eee eee 900 ‘A Rave: virualis elenteskészit6 komyezet - 900 Az RvProject komponens haszndlata +903 Megjelenitési formatumol = 905 ‘Adatkapesolatok ......... 906 A Rave Designer komponensei cee ees 908 Alapkomponensek ...... ce seen wees 909 Adatelérésre hasznalt objeto foes - cece QL Terliletek és sivok .... coe bec ee eens 912 Adatliiggé komponensele 914 Rave szolgiltatésok haladéknak 917 Mestet-részlet jelentések . . 917 Jelentéskészités parancsfijlokkal ..........+---- oe 919 Tukdzés ‘Tovabbi szmitasok . . Hogyan tovabb?...... 19, fejezet Internetprogramozés: a foglalatok és az Indy Foglalatok haszndlata . . ‘A foglalatok programozisénak alapjai Az Indy TCP komponensek haszndlata . Adatb4zisok adatainak kiildése foglalatokon at Levelezés .e cae a Levelek kildése 6 fogadésa « AHTTP protokoll haszndlata TTP tarialom letéltése Sajat bongész5 ..... Egyszer HTTP kiszolgalé . HTML eldallitasa .. A Delphi HTML-készit 5 komponensei | HTML oldalak készitése .... Adatokat tartalmaz6 oldalak kés7itése HTML tablazatok készitése . Siluslapok haszndlata . Dinamikus oldalak coved Holl Hogyan tovabb? 20, ejezet_ Webprogramozis a WebBroker és a +a Websrop segs! Dinamikus weboldalak oo... 0002000000 cee eee ACGlittekintése .... Dinamilcus kOnyveérak haszndlata . A Delphi WebBroker megoldisa . Hibakeresés a Web App Debugger seaisegere . Tobbcéhi webmodul készitése Adatbazisok dinamikus elérése Lekérdezések és tirlapok Az Apache haszndlata Gyakorlati példak Webes talélatszimlalé ane Keresés webes keresémotorral . . . WebSnap ..... Tabb oldal kezelése Kiszolgal6 oldali parinesil Csatoldlke Fajlok keresése bees A WebSnap és az adatbazisok . ‘A WebSnap adatmodul ....... + : ‘A DataSetAdapter . ‘A formon lév6 adatok szerkesztése Le Mester-részlet kapcsolatok a WebSnap-ben . .. Munkamenetek, felhaszndlék 6s jogosultsgok . - 1001 Munkamenetek haszndlata .. 0... 2-445 4001 Bejelentkezés jelszéval 1003 Hogyan tovabb? 1005 21. fejazet Webes programozés az intraWeb segitségével ‘Az IntraWeb bemutatésa 00.00.02. cece ee eee es boveeerees . 1008 ArwebhelyektGl a webes alkalmarasokig. . 1009 ‘Az els6 pillantas a szinfalak mégé . : 1012 ‘an InteaWeb szerkezeti felépitésének valtozatai - 1014 IntraWeb alkalmazasok létrehozisa . 1015 ‘Webes adathazisokat kezel6 alkalmazasok 22.0.6... 1027 Hogyan tovabb? oo... 06s cecee eee ERTS (1 22, fejezet XML megoldésok haszmdlata ‘Az XML. ismertetése » 1038 ‘Az alapvet6 XML nyelvtan . - 1039 A jélformalt XML k6d 1040 ‘Az XML haszndlata...... = 1041 XMI. dokumentumok kezelése a Delphiben . - 1043 Programozas a DOM segitségével 21044 XML dokumentum fa nézetben - 1045 Dokumentumok késuitése a DOM segiségével - 1048 XML adatcsatolé felilletek . feeeeee 1053 A SAX API haszndlata 1088 XMleképerés ftalakitas vijan - 1062 ‘Az XML és az Internet Express 1067 ‘Az XMLBroker komponens . . 1068 JavaScriptramogatés ...... 1069 Mintaprogram készitése 1070 Az XSLT haszndlata . 1075 ‘Az XPath hasznilata .. . . 1076 Az XSLT a gyakorlatban . . 1077 Az XSLT és a WebSnap . 1078 Kézvellen XSL-dtalakités a DOM segitségével 1080 Nagy XML dokumentumok feldolgozasa . . 1082 ClieotDataset komponensbél XML dokumentmba 1082 1084 XML dokumentumbél ClientDataSet komponensbe . Hogyan tovabb? beens cence 23. fejezet A webszolgéltatésok és a SOAP AP protokol Webszolgiltatisok ...... sees fe ee eee ee es + 1088 ASOAP é a WSDL - ] : beeen - 1088 ‘A BabelFish Translations fordits szolgéltatas |. ventas - 1089 Webszolgiliatasok készitése - 1092 Valutavah6 webszolgaltatas . vette 1093 Adatbazisban lév6 adatok lekérése 6.0. 0c eee 1097 A SOAP fejlécek hibakeresése ..... cee - 1101 Mar meglév6 osztily bejegyzése webszolgtisn cones 1103 DataSnap SOAP protokollal : . 1103 A DataSnap SOAP kiszolgalé elkésrhtése 1104 A DataSnap SOAP tigyfél elkészitése ...... . - 1106 A SOAP és a tobi DataSnap kapcsolat Ssszehasonlitisa .. 1106 A mellékletek kezelése con .. 107 Az UDDI témogatésa 1109 Mi az az UDDP? ween 1110 Az UDDI a Delphi 7-ben.......... ween ceceeeee MIL Hogyan tovabb? 1114 24. fejezet A Microsoft .NET a Delphi szemszigébél nézve A Delphi for NET Preview telepitése + 1116 A telepitett program ellenérzése . . . 1118 {SAPPTYPE CONSOLE} . . 1118 A Microsoft .NET feliilete 1120 ‘A k6z6s ayelvi infrastruktira (CLD severe 1120 A kdzbs nyelve futisidejtt omyezet COIR) eee eee 1122 Szerelvények . bene 1124 A kézvetitonyelv . 1125 127 1128 Feliigyelt és biztonsigos kd A kézis tipusrendszer Szemétgyaites ...... 431 Szemétgytiités és hatkonysig 1136 Telepités és valtozatok : 1137 Hogyan tovabb? .... 1140 25. fojezet Delphi for NET Preview: ye ie Komytr Elavult nyelvi szolgaltarasok a Delphiben ....... 00. 00cee eres eens «1142 Elavult tipusok ... 1142 Karakterléncok és egyéh tipusok - 1142 Elavult szolgdltatdsok : - 1143 A Delphi Gj nyelvi szolgaltarasai -1144 Egység-névterek .. 1144 Bévitett azonositsk . ». 1147, A final és a sealed kulesszavak . LW A lathatosdg és hozziférés Gj szinted + 1148 Statikus osztilytagok ....... 1148 Beagyazott tipusok 1149 ‘Tébb tipussal rendelkez6 események 1149 Egyedi tuladonsigok . 1151 Osztdlysegitk . - 1152 A futdsidejt kGnyveér 65 a VCL. «1153 Osatalysegitdk a futdsidejt ktnyvtdrhoz 1153 AVCL ee cece cece eee eee ees 1154 Betekintés a VCLNET forriskodjaba . 1155 ‘Tovabbi VCL mintaprogramok 1157 Microsoft konyvtérak haszndlata 1158 (Az ASP.NET és a Delphi nyelv . - 1165 Hogyan tovabb?......... 1168 A. fiiggelék Tovabbi Debian a sees A CanTools varazslok 1169 VelToChx atalakitéprogram .. 1171 Object Debugger . 1172 Memory Snap .. 1173 Engedélyek és hozzajérulisok . M74 B. fiiggelék | Tovébbi Delphi-eszkézdk més forrésokbél Elére telepitett ayilt forraskédd Delphi-komponensek .... cence MTS Tovabbi nyilt forraskédi projektek wees coe weve L175 Project JEDI... 2.0.0.0 0 065 cece ee wee cece eee HG GExperts . vtec vee e ees fees . -.. 76 A Delphree webhaly 1177 Dunit 177 C. fiiggelék Tovabbi ingyenes s konwek a Delish Essential Pascal . Essential Delphi...... be cec eet ete ete eca eres Delphi Power Book ............ cee veces eee ees 1180 KOszOnemyilvanitas oe eee 1181 TArgymUtate eee cece eee e eects e eet e eee nes 1183 A Delphi adatbazis-architektdraja A Delphi programozasi krnyezet egyik kulesszolgéltatasa, hogy tamogatja az adatbazis- kezel6 alkalmazisokat, Sok programoz6 idejének legnagyobb részét azzal tolti, hogy adathozzaférési k6dokat ir, amelyek az adatbazis-kezel6 programok legerdteljeselsb részét képerik. Ez a fejezet a Delphi kiterjedt adathazis-programozasi tamogatésaba nyijt bete- kintést, Ami nem iallhaté meg ebben a fejezetben, az az. adathézis-tervezés elméletének ismerte- tése, Azt feltételezem, hogy mér ismerjik az adathdzis-tervezés alapjait, és mar megtervez- tak legalabb egy adatbazis szerkezeti felépitését. Az adatbdzis-kezeléssel kapesolatos problémékra sem térek ki—a célom az, hogy segitsek megértetni azt, hogy a Delphi ho- gyan tmogatja az adatbazis-elérést. Els6k€nt azokat a lehetségeket ismertetem, amelyeket a Delphi az adatbazis-clérés terén ajénl, majd a Delphiben hasélhat6 adatb4zis-komponensekr6l nytjtok dttekintést. A feje- zet a helyi adatok elérésére és a VCLient DataSet komponensre Ssszpontosit, az gyfél- kiszolgdl6 tipusti adatbazis-elérést teljes egészében a 14, fejezetre hagyva. A fejezetben olvashaté még a TDataSet osatily révid Attekintése, a TFie1d komponensek részletes elemzése, valamint az adatfelismers (adatitiggS) vezérlOk haszndlatinak lefrésa, Az ezt kO- vet6 fejezetben a halad6 adatbézis-programozasi eszkézdkrdl lesz majd 76, kilnds tekin- temel a dbExpress konyvtar (€s az InterBase Express komponensek) haszndlataval torén6 igyfél-kiszolgal6 tipust programozasra. Végezetiil jegyezaitk meg, hogy a fejezetben targyalt témak tobbsége rendszerfiiggetlen. A mintaprogramok Atvihet6k CLX és Linux rendszerekre is, csak tijra kell forditani Sket, valamint a megfelel6 mappakban lév6 CDS féjlokra mutat6 hivatkozésokat kell létrehozni Ez a fejezet a kévetkezé témakkal foglalkozik: * A Delphi adatbazis-komponensei * Adlatbazis-clérési lehetdségek + Azadatfelismeré vezérlék hasznatata ° =A DBGrid vezérlé + Atablamez6k kezelése * Szabvanyos vezérléket haszn4l6 adatbizis-kezel6 alkalmazisok Adatbazis-elérés: dbExpress, helyi adatok és egyéb lehet6ségek A Delphi els6 valtozatai — amelyeket a fejlesztok azonnal elkezctek adatbazisprogramok készitésére is haszndlni— csak a Borland Database Engine (BDE, Borland adatbézis-kezelé motor) segitségével tudiik elémi az adatbazisokat. A Delphi 3-as viltozatétél kezdve a VCL- nek az adatbézisokhoz kapesol6d6 részét tigy szerkeszteiték at, hogy tbb adatbazis-clérési méd haszmilatat is lebet6vé tegye — jelenleg ezek az ADO, a sajét InterBase komponensek, a dbExpress konyvtr és a BDE. Most mar sok mas cég is ajénl més adatbazis-elérési megol- dasokat kiildaféle adatformatumokhoz (amelyek egy része Borland komponensekkel nem éthets el), és olyan megoldasokat is, amelyek a Delphi VCL-jéhez kapesolédnak. A Kylix fejlesztbkirnyezetben az dltaldinos kép némikipp eltér6. A Borland tigy donot, hogy nem viszi at a régi BDE-technolégiat a Linucra, ehelyett inkabb egy tj, igy BY 3 igh Iyett vékony adatbazis-elérési rétegre, a dbExpressre dsszpontositott. Egy masik lehetség egyszerti alkalmazisok esetében a Delphi ClientDataSet kompo- nensének haszndlata, amely képes tablakat helyi fajlokba menteni — ezt nevezi a Borland MyBase-nek. Jegyezzilk meg, hogy a Paradox tablakon alapulé jellegzetes egyszert Delphi-alkalmazisok a BDE hidinya miatt nem vihetk at a Kylix fejlesztokornyezetbe. A dbExpress kényvtar Az ut6bbi években a Delphi egyik legfontosabb 6j szolgdltatasa a dbExpress adatbazis- kényvtar (DBX) bevezetése volt, amely raadasul Linux és Windows rendszeren is elérheté. Szandékosan mondtam kényutarat és nem adaibazis-kezelé motort, mivel a tébbi megol- dast6l chérden a dbExpress egy kOnnyedebb megkizelitést haszndl, és tulajdonképpen semmi olyan bedllivast nem igényel, amelyet a felhasznal6 szimitogépén kellene végre- ajtani. A dbExpress két legfontosabb jellemvondsa a kis méret és a hordozhat6sig. A Borland ezen okok miatt verette be a Kylix fejlesztOkérnyezet kifejlesztése soran. A tobi erSmi- vel dsszehasonlitva a dbExpress képességei erdsen behataroltak, Csak az SQL kiszolgil6- kat képes elémni (a helyi fajlokat nem), nem tud gyorstarat haszndlni, csak egyiranya hozzaferést tesz lehet6vé az adatokhoz, valamint alaphelyzetben csak SQL lekérdezéseket tud haszndini, és nem képes eldallitani a megfelelé frissitési SQL utasitésokat. Els6 ranézésre azt gondolhatnank, hogy ezek a korlatozasok haszndlhatatlanné teszik a knyvtarat. De épp ellenkezdleg: pont ezek a szolgaltatisok teszik érdekessé. Ha ter- mékjelentéseket kell készitentink olyan HTMi. oldalakat létrehozva, amelyek az adatbézis tartalmét mutatjak, pontosan a kézvetlen frissités nélktili egyirainyit adathalmazokra van sziksségiink. Ha azonban valamilyen felhasznél6i feliiletet szeretnénk Iétrehozni az adatok médositésahoz, a Delphi tartalmaz olyan célirinyos komponenseket (ezek név szetint a ClientDataSet és a Provider), amelyck segitségével lehetdség lesz. a gyorstrhaszné- latra és a lekérdezések felolddsira. Ezek a komponensek sokkal nagyobb mértékt iranyi- {ast tesznek lehetdvé a dbExpress alapt alkalmazis szdméra, mint egy 6ndillé (monolitikus) adatbiizis-kezel6 motor, amely végrehajt helyemiink bizonyos miveleteket, de gyakran nem Ggy, ahogy mi szeretnénk, hanem tigy, ahogy 6. A dbExpress segitségével olyan programot ithatunk, amely a kilonféle SQL-nyelyjarasok okorta gondokt6l eltekintve kiléndsebb kédmédositis nélkiil hozzéférhet sokféle adatba- zis-kezel6 motorhoz. A Delphi 7-ben timogatott SOL kiszolgdl6k a Borland sajat InterBase adatbazisa, az Oracle adatbazis-kiszolgal6, a MySQL (amely f6leg Linuxon nagyon nép- szerit), az Informix adatbazis, az IBM DB2-je és a Microsoft SQL Server. A dbExpress és a kapesoléd6 VCL komponensek részletesebb leirésa, valamint a hasznélatukat bemutat6 sedmos példa a 14. fejezetben taldlhato, Jelen fejezet az adatbazisok szerkezeti elepité- sének alapjaira ésszpontostt Az, hogy a Delphi 7-ben elérhet6 a Microsoft SQL Serverhex vale dbExpress illesztOprogram, jelentés hidnyossdgot siintet meg. Ezt az adatbazist Windouson sokan haszndiljak, é azoknak a fejleszt6knek, akilenek olyan megoldasra volt saiikségitk, amely Atvihets egyik adatbazis-kiszolgdlérol a masilera, gyakran maguknak kellett kialakitaniuk @ témogatdst a Microsoft SOL Serverhez. Most egy okkal kevesebb, hogy a BDE-hez ragasz- kodjunk, A Borland kiadou egy frissitést a dbExpress Delphi 7-ben talalhat6, SQL Server- hez val ileszt6programjahoz, amely szamos hiba javitasdt tartalmazza A Borland Database Engine A Delphit a gyart6 tovabbra is a BDE adatbazis-kezel6 motorral széllitja, amely lehetGvé teszi a helyi adatbazis-formatumokhoz (amilyen a Paradox vagy a dBase) €s az SQL kiszol- géldkhoz valé hozzéférést egyardnt, valamint minden olyan adatbazishoz is képes hozzé- fémi, amely ODBC illeszt6programok segitségével érhet6 el. A Delphi korai valtozataiban ez volt a szabvanyos adathdzis-kezelési megoldas, de a Borland ma mér elavulinak tekinti, Ez kitlondsen igaz arra az esetre, ha a BDE motort SQL kiszolgalk SQL Links illeszt6prog- re haszndljuk, A BDE helyi tablak elérésére torténd haszndlardt hivatalosan még ma is tamogatja a cég, pusztin azért, mert a Borland az ilyenfajta alkalma- zasokhoz nem biztosit kézvetlen Attérést Egyes esetekben a helyi tabla helyettesithet6 a Client DataSet komponenssel (MyBase), kilénésen ideiglenes és kis mérentt indextéblak esetében. Ez. a megoldas azonban a na- gyobb méretti helyi cablékndl nem haszndlhat6, mert a MyBase azt igényli, hogy a teljes tabla be legyen téltve a meméridba akkor is, ha csak egyetlen rekordjéhoz szeretnénk hoz- zaliémni, A megoldas: a nagyobb tablakcat at kell helyezni egy, az iigyfélgépre telepitett SQL kiszolgdléra. Ebben a helyzetben az InterBase az idedlis megoldas. Az ilyen tipust Atrérés megnyitja el6ttink a Linux kapuit is, amelyben a BDE nem hasznélhat6. ‘Tetmészetesen ha olyan programjaink vannak, amelyek a BDE motort haszndljék, tovébb- ra is haszndlhatjuk azokat. A Delphi komponenspalettajinak BDE lapjan még megtalélha- tok a Table (Tabla), Query (Lekérdezés), StoredProc (Térolt eljérds) és mas BDE kom- ponensek, de nem batoritok senkit arra, hogy Gj programokat ezzel a régi médszerrel fejlesszen, amelyet mar a gyéstoja is csak alig-alig tamogat. Ha programjaink hasonlé szerkezeti felépitést kivannak meg (vagy ha régebbi adath4zis-fijlformatumokkal valé egyiittmikédésre van sziikségiink), elébb-ut6bb mas gyart6 Altal készitett motorok uvén kell nézntink, hogy kivaltsuk a BDE motort. ENE ex az oka annak, hogy a konyy jelenlegi kiaddsdbol eltavoltiotiam a BDE-vel kapcsolatos minden lefrést. Ez a fejezet régebben foleg a Table és a Query komponen- seket ismertetie, de tijrairtam, hogy a ClientDataSet komponenst haszndlé adatbazis- programok szerkezeti felépitését mutassa be. Az InterBase Express ‘A Borland egy mésik adathizis-elérési komponenskészletet is elérhetdvé tet a Delphihez: ez a7 InterBase Express (IBX). Ezeket a komponenseket kiln a Borland sajét InterBase kiszolgaléjahoz alakitorik ki. A dbExpresst6l eltérden ez nem kiszolgaldfiiggetien adatbi- zis-kezelS motor, hanem egy adott adatbazis-kiszolgal6 elérésére haszndlhaté kompponens- készlet. Ha egy InterBase adatbazist csak mint hattéradatbazist szeretnénk hasznalni, a megfeleld komponensek segitségével szélesebb kért feliigyeletet kaphatunk a kiszolgil6 J6tt, biztosithatjuk a legjobb teljesitményt, valamint beallithatjuk és karbantartharjuke a kiszolgalét egy egyéni tigyfélprogcambél. Az InterBase Express hasmndlata rdvildgit az adathdzisfiigad egyéni adathal- ‘mazok esciére, amelyek— més gydrtdk termékeikint ~ szdmos kiszolgdlohoz beszerezhetik. (Az InterBase adatbazishoz tdbb adatbazis-bezel6 komponens elérhet6, épp tigy, mint az Oracle-héz, a helyi és megosztott dBase fajlokhox és masokhoz.) Az IBX (vagy mas ezzel dsszehasonlithaté komponenskészlet) hasznalatén akkor érdemes elgondolkodni, ha biztosak vagyunk abban, ogy nem fogjuk megvéltoztatni az adathézist, és a legjobb teljesiuményt és feliigyeletet szeretnénk elérni a rugalmassg és a hordozhat sig krdra. Ennek az a hatultitéje, hogy az igy nyert «bbletteljesiunény és feliigyelet korl4- tozott lehet és azt is meg kell tanulnunk, hogy egy adott viselkedésit komponenskéstletet hasznaljunk, ahelyett hogy egy altalanos motor kezelését sajatitanank el, és ezt a tudasun- kat alkalmaznank kilonféle helyzetekben. A MyBase és a ClientDataSet komponens ACLientDataSet a meméridban tarolt adatok elérésére hasznalhat6 adathalmaz, ‘A memé6riéban lév6 adatok lehetnek ideiglenesek (amelyeket a program hoz létre, és ame- lyek a program bezérdsakor elvesznek), helyi féjlb6l bewltttek és oda visszamentettek vagy egy mésik, a Frovider (Szolgdltaté) komponenst hasznalé adathalmaz 4ltal beolva- sottak. ‘A Borland jelzi, hogy a Client DataSet komponenst egy MyBase nevi fajlhoz rendelve kell haszndlni, hogy jelezzitk, hogy az helyi adatbazis-megoldasként hasznalhat6. Nekem van egy kis bajom azzal, ahogy a Borland reklamszakemberei ezt a technolégiat reklamoz- tak, de ennek is megvolt az értelme, amint azt kicsit késbb ismertetem, Az adatok szolgaltatobél trténé elérése gyakori megoldas tgy az tigyfél-kiszolgtlé rend- szerekben (amint azt a 14, fejezetben majd léthatjuk), mint a Wbbrétegt rendszerekben (utébbival a 16. fejezet foglalkozik). A CLientbataset komponens kUl6nésen hasznos akkor, ha a hasznalt adathozzaférési komponensek korlatozott vagy semmilyen gyorstar- haszndlatot nem tesznek lehet6vé, mint példaul a dbExpress motor esetében, dbGo az ADO motorhoz Az ADO (ActiveX Data Objects, ActiveX adatobjektumok) a Microsoft magasszinti adatba- zis-elérési feliilete, amelyet a Microsoft OLE DB adatbazis-hozzAférési megoldasinak se- gitségével val6sitottak meg, és amely relaciés és nem relaciés adatbzisok, valamint elekt- ronikus levelezrendszerek, fajlrendszerek és egyéni dizleti objektumok elérését biztositja. Az ADO olyan motor, amelynek szolgaltatasai 6sszehasonlithat6k a BDE motor szolgalta- tésaival: fiiggetien adatbazis-kiszolgal6, amely tamogatja a helyi és az SQL kiszolgalékat egyanint, nagy teljesitményd motor, amely egyszertien beillithat6 (mivel nem kézpontosi- tot), A telepités (elméletben) nem okozhat gondot, mert a motor része a Windows jelen- Jegi valtozatainak, Az ADO kul6nféle valtozatai kozOtti korldtozott ésszeferhetdség, azon- ban felveti annak szikségességét, hogy a felhasznal6k szimftogépeit ugyanazon ADO- valtozatra frissitstik, amelyet a program fejlesztése sordin haszndltunk. Az operdciés rend- szet nagy részét frissit6é MDAC (Microsoft Data Access Components, Microsoft adathozza- férési komponensek) puszta telepitési mérete kévetkeztében azonban ez a mtivelet kézel sem mondhat egyszertinck. Az ADO motor hatérozott eldnyt jelent, ha Access vagy SQL Server programot akarunk: hasznélni, mivel a Microsoft sajat adatbazisaihoz készftett illesztSprogramjai jobb mindsé- gtiek, mint az atlagos OLE DB szolgaltat6k. A Delphi ADO komponenseinek hasznalata kailénésen az Access adatbizisok esetében szamit j6 megoldésnak, Ha més SQL kiszolga- Iokat szeretnénk haszndlni, el6sz6r ellenérizziik, hogy van-e abhoz j6 mindségd illeszt6- programunk, kulénben érhet minket par meglepetés. Az ADO nagyon hatékony eszk6z, de meg kell tanulni egytitt élni vele — a program és az adatbazis kozon helyezkedik el, és szolgaltatésokat nydijt, de esetenként nem egészen azokat a parancsokat adja ki, mint amelyekse szdmiunk, Kifejezett hatrinya, hogy ha a jévében rendszerfiggetlen fejlesmést terveztink, gondolnunk sem szabad az ADO haszndlatéra, mivel ez a Microsoft-megoldas Linuxon és més operiiciés rendszereken nem all rendelkezéste, Réviden Ssszefoglalva: ha csak a Windows rendszeren terveziink dolgozni, és Access vagy mas Microsoft dltal készitett adatbazisokat akarunk haszndlni, hasznéljuk nyugodtan az ADO motort, vagy mindegyik haszndini kivant adathazis-kiszolgaléhoz (ezek kézé je- lenleg nem sz4mithat6 be az InterBase és sz4mos més SQL kiszolgilé sem) keressiink egy j6 OLE DB szolgaltatét. ‘Az ADO komponensek (amelyek a Borland altal dbGo-nak nevezett csomag részei) a kome ponenspaletta ADO lapjén talilhat6k, A hérom alapkomponens az ADOConnect ion (adat- bazis-kapcsolatolthoz), az ADOCommand (SQL utasitésok végrehajtasira) és az ADODataSet (credményhalmaz visszaadisét eredményez6 lekérdezések végrehajtiséra). Van még hérom, a ségi programokkal valé egylttmakodést segité komponens is — az ADOTable, az ADO- Query és az ADOStoredProc -, amelyek a BDE alapti alkalmazdsok ADO motorra t6rténé Atvitelére haszndlhat6k, végezetiil pedig az RDSConnect ion komponens t4voli tbbrétegi alkalmazisokban lév6 adatok elérését teszi lehetdvé. A 15. fejezet részletesen ismerteti az ADO motort é a hozed kapcsoléd6 megolddsokat. Megjegyzendé, hogy a Microsoft manapsdg az ADO motort anak .NEF-es valtozatara cserél, amely ugyanazokra az alapelvekre pul, tehat az ADO haszndilata 6 megoldas lehet a NET alkalmazasok felé vezetd titon (bar a Borland tervezi a dbExpress Aitvitelet e feltiletre is). Egyéni adatbazis-komponensek Amisik lehetéség, hogy mi magunk készitiink egyéni adathalmaz-komponenseket, vagy valasztunk a rengeteg elérhet6 ajanlat kéziil. Az egyéni adathalmaz-komponensek fejles tése a Delphiben tortén6 programozis egyik legbonyolultabb része, amellyel a 17. fejezet foglalkozik. A fejezeret elolvasva megtanuljuk még a Thataset osztdly belsé mitkédését is MyBase: éndllé ClientDataSet Ha egyfelhasznal6s adatbézisprogramot szeretnénk itni a Delphiben, 2 legegyszertibb médszer a ClientDataSet komponens hasznélata és hozzarendelése egy helyi fajthoz. A helyi fijthoz val hozzarendelés eltér 2 hagyoményos médszert61, amikor adatoksat ren- deltink egy helyi fajlhoz. A hagyomAnyos médszert haszndlva rekordonként olvastattuk be a fajle, és éltalaban volt egy masik fail is, amely az indexeket térolta. A CLientDataset egy teljes tablat (és ba lehet, akkor egy mester-részlet tipust felépitést) rendel a féjlhoz, mint egészhez. Amikor a program elindul, a teljes fajl bet6ltdik a memérifba, és mentés- kor is mindent egyszerre ment a program, BEL 2 megmazyariizza, miért nem lehet ext a mddszert tsbbfethasendlés vagy 1ébbalkalmazdsos helyzeiben haszndlni. Ha két program vagy ugyanazon program ét példanya ugyanazi a ClientDaiaSet fajlt tilti be a meméridba, majd médositja az adatokat, az wioljéra meniett tabla feltitinja a ibbi program vagy programpeldény dltal végrehajtott médosttasokat. Ezt.a ClientDataSet tartalmanak fennmaradésat szolgal6 timogatast néhany évvel ezel6it hozak létre az. igynevezett taska modell egyik megvalésitési formajaként. ‘A felhasznal6 le tudta (és tovabbra is le tudja) t6lteni az adatokat az adatbazis-kiszolgalé- 161 az tigyfélgépre, képes azok egy részét menteni, kapcsolat nélkilli dllapotban dolgozni (példéul amikor hordozhat6 sz4mitégépen dolgozik utazis kozben), majd Gjeacsatlakozas utén képes érvényesiteni az dltala végrehajtott médosttésokat. Csatlakoz4s I6tez5 helyi tablahoz AClientDataSet komponenst annak FileName tulajdonsigét bedllitva lehet egy helyi féjlhoz csatlakoztatni. Egy minimalis program létrehozdsahoz (ennek a neve a példaban MyBasel) nines sziikségiink masra, mint egy CDS fajlhoz kapesolt Client DataSet kom- ponensre (ilyen fajlb6l talélhaté néhany a \Program Files\Common Files\Borland Shared mappa Data almappijéban), egy DataSource komponensre és egy DBGrid vezérldre. A ClientDataSet komponenst kapcsoljuk a DataSource komponenshez az utobbi Dataset tulajdonsdgén keresztiil, és a DataSource komponenst a DEGrid vezérl6héz a tabla DataSource tulajdonsagan 4t, amint az a 13.1. kodszévegben kathat6, Ezen a ponton kapesoljuk be a Client DataSet: komponens act ive tulajdonsagat, és egy olyan programot kapunk, amely mar tervezési idében is mutatja az adatbazist, Ezta 13.1, abran tekinthetjtik meg, 13.1, k6dsz6veg A MyBasa1 mintaprogram DFM féjlia. object Forml: TFormt ActiveControl = DBGridl Caption = 'MyBasel' OnCreate = FormCreate object DEGrid]: TDEGria DataSource = DataSource! end object Datagourcel: TDataSource Dataset = cds end, object cds: TClientDataset FileName = ‘C:\Program Files\Common Files \Borland Shared\Data\customer. cds" end end 15) Mere Oven the VI Thebes Chm 1359 Be Some ee 13.1, abra A példaként szolgdl6 helyi tabla tervexési idoben is aktty a Delphi fejleszidkirnyezetben. Ha megvahoztatunk valamilyen adatot, majd berArjuk az alkalmazast, a program automati- kusan menti a médositisokat a fajlba. (A méretesokkentés érdekében esetenként Erdemes kikapcsolni a médositésnapl6zést, amint azt majd késGbb kifejtem.) A komponensnek sésze egy SaveToF ile és egy LoadFromFi le tagfiiggvény is, amelyeket felhasznalhatunk a kédban, Végrehajtottam még egy valtoztatast: tervezéskor kikapesoitam a C1 ient Dataset komponenst, hogy ne Keriiljin be a bene lév6 ésszes adat a program DEM féjljaba és a leforditott végrehajthat6 féjlba, mivel az adatokat egy kiilén fajlban szeretném tarolni Ehhez tervezési idében, az ellendrzés utin zarjuk be az adathalmazt, és vegyiink fel egy sort a form OnCreate eseményéhez az adathalmaz megnyitésihoz: procedure TForml.FormCreate (Sender: TObject) ; begin cds.Open; end; A Midas DLL kényvtértél a MidasLib egységig A CLientDataSet komponenst haszndl6 barmely program futtatésthoz telepitentink kell amidas. 11 dinamikus kényvtérat, amelyre a DSInt £ .pas egység hivatkozik. A Client- DataSet. komponens alapkédja nem kézvetlen része a VCLnek, és forrdskéd forméjaban nem All rendelkezésre. Ez nem til szerencsés, mert sok fejlesztd hozzaszokott ahhoz, hogy bibakeresés utén a VCL-forriskédot hasanalja végs6 referenciaként. ] nom Amidas.dll kdnyvtdr neve nem tartalmaz verziészdmot, ha tehdt a szd- mitdgépen egy régebbi viltozat taldlhato, a program késaségesen futtatni fogja, de ellfor- dulhat, hogy nem a vart mitkédést kapjuk. ‘A Midas C ayelven irott konyvtar, de a Delphi 6-0s valtozata ota kozvetleniil is egy végre- ajthat6 fajlhoz csatolhats az erre a célra szolgilé MidasLab egységet beiktatva (amely egy, a C forditéprogram Altaf el6altitort kiilénleges DCU). Ebben az esetben nem kell a kGnyvtirat DLL formétumban mellékelni a programhoz. Az XML és a CDS formétum AClientDataSet komponens két eltéré adatéramlisi format timogat: a sajat formatumat és az XML alapG formatumot. A korébban mar emiitett Borland Shared\Demo mappiban megtalalhat6 sz4mos tébla mindkét formatumban elkészitett valtozata. A MyBase alapértel- mezés szerint XML formatumban menti az adathalmazokat, A SaveToF ile tagfiiggvény- nek van egy olyan paramétere, amely lehetGvé teszi, hogy mi valasszuk ki a formatumot, a LoadFromPile tagftigavény pedig automatikusan hasznélhat6 mindkét formatumhoz. Az XML formétum haszndlatanak megyan az az elOnye, hogy az dlland6 adatok szerkesz- tdvel is hozzférhet6k, és més olyan programokkal is, amelyek nem a ClientDataset komponensen alapulnak. Eza médszer azonban az adatok oda-vissza tOrtén6 Atalakita- saval jar, mert a CDS formatum kézel all a komponens aital mindkét formatum esetében azonosan hasznélt memorién beltili megjelenéshez. Emellett az XML nagy fajlok létreho- zésat eredményezi, mert széveges alapt. Egy MyBase XML fajl mérete dtlagban kétszer akkora, mint az ugyanazon adatokat térol6 CDS fale. Amikor egy CLientDataSet homponens be van iélive a meméridba, az AULData Mulajdonsdg segitségével az XML-megjelenités kinyerhet6 az adatok mentése nélkiil is, A Rovetkezd példdban ezt a megoldast iiltetjiik at a gyakorlatba. Uj helyi tabla meghatdrozésa AClientDataSet komponens amellett, hogy megengedi, hogy egy helyi fajlban tarolt adatbazistabl4hoz kapesolédjunk, tj tablak egyszert létrehozas4ra is médot ad. Nem is kell mst tenniink, mint a komponens F ie1dDefs tulajdonsaganak segitségével megha- t4rozni az Gj tabla felépitését. Miutdn ezzel megvagyunk, a Delphi fejleszt6kornyezetben_ aClientDataSet komponens helyi mentijében lévé Create DataSet (Adathalmaz létre- hozdsa) parancesal vagy a CreateDataSet tagfiiggvényt futésid6ben meghivva hozhat- juk létre fizikailag is a fajle. Ime az a részlet a MyBase2 mintaprogram DFM {4jljabél, amely egy Gj helyi adatbzistabla meghatérozisat szemlélteti: object ClientDataset1: TClientDataset FileName = ‘mybase2.cds' FieldDefs = < - item Name = ‘one’ Datatype = ftstring Size = 20 end item Name = 'two' feSmallint StoreDefs = True end Felhivndm a figyelmet a StoreDe#s tulajdonsigra, amely automatikusan ‘true (gaz) értékre van Allitva, amikor a mezék meghatarozAsainak gyGjteményeét szerkesztjiik. Alapértelmezés szerint a Delphiben az adathalmazok metaadataikat betéltik a meméridba, miel6tt megnyiindnak. Ezeket a metaadatokat a program csak alkkor hasznlja, ha helyi meghatirozis van a DFM fajlban tarolva (ha a mezdadatokat is a DEM fajlba mentjiik, az szintén hasznos lehet ezen metaadatok gyorstarba helyezésthez az tgyfél-kiszolgalé felépitésti rendszerekben). Hogy kénnyebb legyen megérteni a nem kételez6 jellegit adathalmaz-létrehozast, a naplé- 24s kikapcsolisat (err61 késbb még 826 lesz) és a Memo verérl6ben lévé kezdeti adatok XML véltozatinak megjelenitését, a program formosztilya a kévetkez6 OnCreate esemény- kezel6vel rendelkezik: procedure TForm!.FormCreate (Sender: Tobject}; begin if not PileExists (cds.PileName) then cds .CreateDataSet; cds-Open; cds .MergeChangeLo: cds.LogChanges := False; Memol.Lines.Text := StringReplace ( Cds.XMLData, '>', '>' + sLineBreak, [rfReplaceall]); end; Az utols6 ulasitisnak része egy StringReplace hivas, amely egy szegényes XML-forma- zasi szikségmegoldist biztosit: a kéd felvesz egy ti sort minden XML-K6d utan, oly médon, hogy tj sort vesz fel a znd kacsacs6r utin. A tabla par rekordjat tartalmazé ilyen XML-for- matumbeli megjelenitést lathatunlk a 13,2. abran. Az XML Delphiben térténé haszndlatéré) bévebb tudnivalékat a 22, fejezetben tal4lunk. 13.2. dbra A CDS fajl XMI-formatumbeli megjelenitése a MyRase2 mintaprogramban. A tibla felépttésée a program hatérozza meg, amely az els6 végrehajtdsakor létrehoz egy fajlt az adathalmaz tarolasara, Indexelés Miutan betdltéttink egy ClientDataSet komponenst a meméridba, sz4mos miiveletet hajthatunk vele végre. A legegyszerdibbek ezek kéziil az indexelés, a sztirés és a rekordok keresése, a bonyolultabbak pedig a csoportositis, az Osszesitett ériékek meghatérozisa és a médositasi napl6 kezelése. A kivetkezkben csak a legegyszeriibb megoldasokkal foglalkozom, a bonyolultabbakra majd a fejezet végén keriil sor. A CLientDataSet sairése az, IndexPieldNames tulajdonsig bedllitésaval valésithaté meg. Ezt gyakran hajtjék végre olyankor, amikor a felhaszndl6 a DBGrid komponensben a mez6 cimére kattint (clinditva ezzel az OnTitleClick eseményt), amint az a MyBase2 mintaprog- ramban lathato: procedure TForml.DEGrid1TitleClick(Colum: ?Column) ; begin cds.IndexPieldNames := Column.Field.PieldName; end; Mas helyi adatbazisokt6l elrérden a ClientDataget komponensben ilyenfajta dinami- kus indexelés az adatbizis barmiféle bedllitésa nélkiil hasznalhat6, mivel az indexeket a memérian behil szamitja ki a program, A komponens a szamitott mezdk alapjan létrehozolt indexek haszndlatat is tdmogaija, féleg a belssleg kiszamolt mexok esetében, amelyel csak ehhex az adathal- mazhoz dlinak rendelkezésre (amint a fejezet egy késGbbi részében majd részletesebben is kifejtem). A szokésos szdmitott mez6Rtél eltérden, amebyeket a program minden alkalom- mal ijra kiszémol, amikor a mez6t haszndlja, a belsoleg kiszdmolt mezbk ériéheit csak egyszer szdmolja ki, és azutan a memériaban tarolja, emiatt az indexek ezeket a szami- lott mexbhet is egyszerdi meztknek tekintik, Indexet nemesak tigy hatrozhatunk meg, hogy Gj értéket tendeliink az IndexPieldNames tulajdonsighoz, hanem az IndexDefs tulajdonsag segitségével is, Ect az eljarast koverve tObb indexet is meghatirozhatunk és tarolhatunk a meméridban, és ily médon sokkal gyor- sabban valthatunk egyikrdl a masikra. Ha névelu6 helyett csokkend indexet szevetnénk térolni, anak egyetlen médja egy Ondllé index meghataroxtisa, Saiirés Mint mds adathalmazok esetében megszokhattuk, a Fi Iter tulajdonség segitségével adhatjuk meg, mely adatrészek, amelyekhez a komponens két6dik, kertiljenek az adat- halmazba. A satirés a memériaban torténik az dsszes rekord betdltése utén, tehdt ez arra egy megoldas, hogy a felhaszn4i6 elit kevesebb adat jelenjen meg, nem arra, hogy csdkkentsiik nagy helyi adathalmaz esetén a meméridban keletkez6 lenyomatot. “Amikor nagy mennyiségd adatot kériink le egy kiszolgal6r6l (iigyfél-kiszolgal6 rendszer- ben), meg kell probalnunk megfelel6 lekérdezést haszndlni, hogy ne egy nagy adathalmazt kapjunk az SQL kiszolgal6tél. Altalaban érdemes elsé lépésként a mér a kiszolgdlén toté- nG elszirést valasztanunk, Helyi adatok esetében érdemes elgondolkodnunk azon, hogy a nagyszémé rekordot tab kiilénbéz6 fajlhalmazra osszuk, igy csak azokat kell betdtte- niink a meméridba, amelyekre sziilcségiink van, nem az dsszeset. AClientDataset komponensben trténé helyi sztirés hasznos lehet, ktiléndsen azért, mert az ezen komponens esetében haszndlhat6 sziirdkifejezések szama sokkal nagyobb, mint a més adathalmazoknal hasznflhat6ké, Hasznalhaték példaul az alabbiak: * Aszabvanyos dsszehasonlit6 és logikai mtiveleti jelek, péld4ul: Nepesseg > 1000 and Terulet < 1000 + Ariumetikai miveleti jelek, példdul Nepesseg / Terulet < 10 * Karakterlanc-figgvények, péld4ul substring (Keresztnev, 1, 2) = 'Ka' + Datum- és idéfiggvények, péld4ul Year (Szamla_Datum) = 2002 + Egyebek, példdul a Like fiiggvény, a helyettesit6 karakterek és az Tn miivelet A sailrési IchetOségeket kimeritden ismerteti a VCL stigéja. Keressiik a TClientDataset osttily Filter tulajdonsagat lefré lapon a Limiting what records appear (A megjelenitett rekordok korlétozdsa) lapra mutat6 hivatkozdst, de eléshetjik a lapot a stgé tartalomjegy- zékén keresztiil is, az alabbi aton: Developing Database Applications (Adatbazis-kezel6 alkalmazasok fejlesztése), Using client datasets (Ugyfél-adathalmazok haszndlata), Limiting what records appear (A megielenitett rekordok korlétoz4sa). Rekordok keresése Aszérés a program felhasznaldja eldtt megjelené rekordok sz4mAnak korlétozAsat teszi lehet6vé, de sokszor szereinénk az dsszes rekordot megjeleniteni, Am csak egy adott rekordra szereinénk ugrani. A Locate tagfliggvény ebben segit. Ha még sohasem haszndltuk, a sig6 elsé lavésra nem segit uilzottan. Az dtlet az, hogy meg kell adni azon oszlopok listajat, amelyekben keresni szeretnénk, és egy éréklistat — minden oszlophoz egy extéket, Ha csak egy mezét szeretnénk igy megkeresni, az értéket kOzvetlentil atadja a program, mint eben az.esetben (ahol a keresési karakterlanc az EditNeme kompo- nensben taldlhaté): procedure TForml.btnLocateClick (Sender: TObject) ; begin if not cds.Locate (‘LastName’, EditName.Text, {]) then MessageDlg (‘"' + EditName.Text + '" not found’, mtError, [mbOk], 0); end; Ha tébb mez6t is kerestink, egy valtoz6témbot kell atadnunk, amely a keresett értékeke listajat tartalmazza. A valtoz6tomb létrehozhat6 Alland6témbbél a VarArrayOF fiiga- vénnyel, vagy a semmibél a VarArrayCreate hivassal. ime egy pici kdrészlet: cds.Locate (‘bastName; FirstName’, VarArrayOf ({ ‘Cook’, 'Kevin'l}, (1) Végezetiil hasznélhatjukk ugyanezt a médszert rekordok keresésére is, még akkor is, ha csak a keresett mezé els6 par karakterét ismerjiik. Nem kell mast tenntink, mint hozz4- adni a loPart ialKey jelz6t a Locate hivas Options (harmadik) paraméteréhez. Alocate hivis hasendlatinak akkor van értelme, ha helyi tabldkat hasend- lun, reoyfél-hiszoledl6 allealmazasokra nem vihet6 dt j6l. SOL kiszolgdiokon a hasonté ‘figyfél oldali megoldasok elds26r dtviszik az ésszes adatot az iigyfélprogramba (ami mar alapjdban véve rossz dtlet), és csak azutdn kezdik el keresni a kivéint rekordot. Az adato- kat korldtozott SQL utasitdsokkal kell megkeresni. A Locate hivds a korldtozott adathal- maz lekérése utdn is haszndihat6. Kikereshetink példaul egy tgyfelet a neve alapian azutan is, miutdn kijeléltiik az egy adott vdroshan vagy régioban 616 tigyfeleket, igy mar eleve koridtozott méretti eredményhalmazt kapua. Errél bévebben a 14. fejezetben olvas- hatunk, amelyet teljes egészthen az tigyfé-kiszolgdlé tipusts fejlesztéseknek szenteltem. Az Undo és a SavePoint parancs Amikor a felhasznal6 médositja a ClientDataSet komponensben lév6 adatokat, a valtoz- tatisokat egy Delta (4tmeneti) nev memériéban tarolja a rendszet. Annak oka, hogy a felhasznalé Altal végrehajtott médositasokat tartja nyilvan a rendszer, és nem az azok eredményeként kapott tablat tarolja, az a médszer, ahogy a frissitések kezelése az ilyen felépitésd rendszerekben torténik. Ebben az esethen a programnak nem kell visszaktilde- nie az egész tablat a kiszolgiléra, elég, ha csak a felhasanals altal végrehajtott mdositisok listajat Intldi vissza (megfeleld SQL utasttasok segitségével, amint azt majd a 14. fejezetben Vatni fogiuk). Mivel a Client Dataset komponens a viltoztatasokat tartja nyilvan, ezeket a valtozta- tsokat vissza is vonharjuk, eltavolitva a bejegyzéseket az dtmeneti memériateriiletrél. ‘A komponensben erre a célra az UndoLastChange tagfilggvény szolgal, amelynek Fol lowChange paramétere lehetOvé teszi a visszavon4si miivelet kévetését ~ az tigyfél- adathalmaz arta a rekordra ugrik, amelyet a visszavondsi miivelettel helyredllitottunk, ime az a kéd, amelyet az Undo (Visszavonas) gombhoz kapesolédashoz hasznalhatunk: procedure TForml.ButtonUndoClick(Seader: TObject}; begin ede.UndoLastChange (True); end; A visszavonas tamogatasinak kib6vitése az a lehetGség, hogy a médositési naplo helyzetét a pillanatnyi dllapotot) egyfajta konyvjelz6ként menthetjik, és késdbb ezt az dllapotot visszaAllithatjuk, eltavolitva az dsszes késGbbi médositést. A valtozésok napléba mentésére és egy régebbi dllapotnak a napl6 alapjan torténd visszadllitaséra egyarint a SavePoint tulaidonsdg hasznalhato, de a médositési nap\6 alapjan esak eltévolitani tudunk rekordo- kat, visszahelyezni nem. Mas szavakkal, a SavePoint. tulajdonsag a napl6 egyik pontjara hivatkozik, azaz csak egy olyan allapotra tudunk visszadllni, amikor még kevesebb rekord volt! Ez a napl6beli pont egy médositassz4im, ha teat mentjiik a pillanatnyi helyzetet, visszavonunk par médositast, majd elvégziink néhany tjabb médositast, akkor nem tudunk visszatérni a konyvjelz6vel megjelétt allapotla, us A Delphi 7-ben van egy tj szabvanyos mivelet, amely a ClientDataset. Undo miiveletéhez van hozzdrendelve. Tovabbi tj mtiveletek a Revert (Visszadltttas) é az Apply (Alkalmazas), amelyekre akkor van szilkség, amikor a komponens egy adat- bazist elérd adathalmazhoz kapesolédik. A naplézés ki- és bekapesolésa A médositésok nyilvantartasinak akkor van értelme, ha a frissitett adatokat vissza kell Kcil- deniink a kiszolgalon lévé adatbazisba, Helyi alkalmazésok esetén a MyBase fajllban tarolt adatok mellett sziikségtelen ennek a naplonak a vezetése, csak feleslegesen emészti 2 me- mériat, ezért a naplézds a LogChanges tulajdonsag segitségével kikapesolhat6. Igaz, ezzel a miveletek visszavonasa is lehetetlenné valik, Hasznélhatjuk viszont a MergeChangestog tagfligavényt, amelynek segitségével az dsszes aktudlis médositast eltavolithatjuk a naplobél, és j6vahagyhatjuk az eddig végrehajtott médositasokat. Ennek altkor van értelme, ha egy munkameneten beliil szeretnénks vezetni a visszavonisi napl6t, majd mentjiik a végleges adathalmazt, de utdna a modositisi napl6t nem tartjuk meg. naplézdst. Bzt a kédot eltdvoliiva tijra engedélyezhetjak a naplézdst, hogy az adatok mo- dositésa uttin léthassuk a GDS fajl és az XML szdvegfajl méretében bekivetkezett eltérést. ‘Az adatfelismeré vezérlék hasznélata Miutan bedllitottuk a megfelelé adathozzaférési komponenseket, létrehozhatunk egy fel- hasznaléi feliletet, hogy lehet6vé tegyik a felhasznal6k szdméra az adatok megtekintését, 6s végs6 soron a médositésukat. A Delphiben sok olyan komponens van, amely a szoki- sos vezérlOkre emlékeztet, de felismeri az. adatokat. A DEEdit komponens példaul hasonlit az £4it komponenshez, és a DBCheckBox komponens is megfelel a CheckBox komponensnek, Ezeket 2 komponenseket 2 komponenspaletta Data Controls (Adatve- zérl6k) Japjan talalhatjuk meg. A komponensek a megfelel6 tulajdonsag, a DataSource segitségével kapcsolédnak egy adatforrishoz. Egy részik a teljes adathalmazra vonatkozik, példdul a DBGrid és a DBNavigator komponens, més résziik pedig az adatforras egy-egy mezdjére hivatko- zik, amint azt a Data¥ ied tulajdonsag jelzi. Ha kijeldltiik a DataSource tulajdonsagot, a DataField tulajdonsagszerkeszt6 a valaszthato értékek listdjat jeleniti meg. ‘Az adatfelismeré komponensek (adatflggé Komponense&) egyike sincs kapcsolatban az adathozzaférési méddal, feltéve, hogy az adathozzaférési komponens a TDataSet osztilyb6l 6rdkl6dik. Igy a felhasznal6i feliilet létrehozasiba fektetett energia megténil, amikor megvéltoztatjuk az adathozzaférés médjat. A keresési komponensek némelyi- kének 6s a DBGr id kiterjedt haszndlatinak (sok adat megjelenitése) azonban esak akkor van értelme, amikor helyi adatokkal dolgozunks, igyfél-kiszolgal6 rendszerekben dlta- Miban érdemes keriilni a haszndlatukat (lasd a 14. fejezetet). Tébléban lév6 adatok A DaGrid (adatracs) egy olyan tablazat, amely képes egyszerre megjeleniteni egy teljes adattablit. Lehetdséget ad a gorgetésre és a mozgisra, és médosithaté a tabla tartalma. Eza vezérl6 a tbbi Delphi tiblavezéri6 kibévitése. A DEGrid vezérlét az Opt ions tulajdonsaganak kulonféle jelz6it bedllitva és Columns gydjteményét médositva tudjuk testreszabni. A tabla lehetGséget ad a felhasznlonak azadatok kOzt a gorditésav segitségével térténd mozgasta és az dsszes fontosabb mivelet végrehajtésira. A felhasznalék kozvetlentil médosithatjak az adatokat, beszGrhatnak egy Oj rekordot a megadott helyre az Insnar billentyiit lenyomva, az utols6 rekordra Allva, majd lenyomva a Le nyilbillentytit hozzéfiizhetnek egy 6j rekordot a tabla végéhez, illetve tordlhetik a kijeldlt rekordot a Cra+Det billentyttkel. ‘AColumns tulajdonsag egy olyan gydjtemény, amelybél kivalaszthatjuk a table azon mezéit, amelyeket meg szeretnénk jeleniteni a tablaban, és beéllithatjulk minden mez6hoz az oszlop- és cimbulajdonsagokat (s7in, bentitipus, szélesség, igazitas, felirat stb.). A fejlet- iebb tulajdonsagok egyil-masika, példdul a Buttonstyle és a Dropbownkows segitsége- vel egyéni szerkeszt6programokat haszndlhatunk a tabla celldinak szerkesztésére, illewe egy lenyil6 listar6l valaszthatunk énékeket (ezt az oszlop PickList tulajdonsaga jelzi), A DBNavigator és az adathalmazon végrehajthaté miveletek ADENavigator olyan gombok gyiijteménye, amelyeket az adathazisban valé mozgisra és killonféle adatbazis-miiveletek végrehajtisira hasznaihatunk. A DBNavigatox vezérlé gombjainak egy részét letilthatjuk oly médon, hogy az elemek némelyikét eltavolitjuk a Visiblezuttons tulajdonsigbél. A gombok alapmtiveleteket hajtanak végre a kapesolod6 adathalmazon, ezért egyszertien le tudjuk azokat cserélni a sajat eszkéztérunkra, kiiléndsen akkor, ha a Delphi altal bizto- sitott, el6re meghatarozott adatbazis-mtiveleteket tartalmaz6 Act ionhist komponenst hasznaljuk. Eben az esetben megkapjuk az dsszes szabvinyos viselkedést, de léthatjuke a kildnféle gombokat is, amelyek csak akkor érhet6k el, ha az dltaluk végrehajtott mtive- let szabilyszertl, A mtiveletek haszndlaténak elénye, hogy aban az elrendezésben jelentt- hetjk meg a gombokat, amelyik a sziviinknek a legkedvesebb, dsszevegyithetjik Sket az alkalmazés mas gombjaival, és haszndlhatunk tbb tigyfélvezérl6t is, kOzitik f6- és el6ugré menitket. Ha a szabudnyos mitveleteket haszndljuk, elkerilhetjitk, hogy éssze kelljen hétni azokat egy adoit DataSource komponenssel, & a miiveleteket arra az adathal- mazra alkalmazza a program, amoly a bemeneti fokuszt éppen birtoklé vizudlis vexéri6- hoz kapesolddik. My médon egy eayszert eszkézidr haszndlhate a formon megjelentiett tobb adathalmazhor is, ami nagyon zavaré lehet a felhaszndlé sedméra, ha nem jérunk el elég gondosan. Széveg alapd adatfelismeré vezérlék Tob szdveg alapti komponens is van: pptext Egy olyan mezé tarvalmat jeleniti meg, amelyet a felhaszn4lé nem médosit- hat. Ez egy adatfelismeré Label (Cimke) grafikus vezérl6, Bizonyos esetekkben nagyon hasznos lehet, de a felhasznal6k dsszekeverhetilc ezt a vezérl6t a sima cimkékkel, amelyek az egyes mez6 alap6 vezérl6k tartalmat jelzik. DBEGit Azt teszi lchetdvé, hogy a felhaszn4lé médosithassa a mezét (meg tudja val- toztatni annak aktudlis értékét) egy Edit vezérlével. Idénként érdemes letiltani a md- dositast, és dgy haszndlni a DBEdit komponenst, mintha DBText lene, de kiemelve azta tényt, hogy ezek az adatbazisbél sz4rmaz6 adatok. DBMemo Azt teszi lehetdvé, hogy a felhasznalok megickinthessenek és médosithassa- nak egy nagy szévegmez6t, amely téiténetesen egy jegyzet vagy BLOB (binary large object, nagy bindris objektum) mezdben térol6dik. Ez a Memo Komponensre emlékez- tet, és teljes szetkesztési képességekkel rendelkezik, de a s26veg egyetlen betitipussal jelenik meg. Lista alapé adatfelismer6 vezérldk Ha azt szeretnénk engedélyezni a felhasznalék sz4mara, hogy egy elére meghatdrozott listar6l valaszthassanak értékeket (ami csékcenti a beviteli hibak lehetdségév), sok Ktlén- 626 komponenst haszndlhatunk. A DBList Box, a DBComboBox és a DBRadioGroup: hasonl6k — mindegyiktk egy karakterlanc-listat tartalmaz az Items tulajdonsagban -, de azért van kéztik némi eltérés: DBListBox Elére meghatdrozott elemek kéviili valasztist (zdrt kijeldlés) tesz lehers- vé, de nincs szévegbevitel, a listén viszont sok elem elhelyezhet6. Altalaban jobb csak legfeljebb hat-hét elemet szerepeltetni a list4n, hogy ne fogialjunk el tal sok helyet a képerny6n. DBComboBox. Hasznalhiat6 zArt kijeléléshez és felbaszndl6 éltali adatbevitelhez is A DBComboBox csDropDown stilusa azt teszi lehetvé, hogy a felhasznalé Uj értéket is megadhasson, de valaszthasson a listin szerepl6k kézil is. Ez a komponens kisebb teriiletet hasznal a formon, mivel a lenyilé lista dltaléban csak kérésre jelenik meg. DBRadioGroup Valasztégombokat jelenit meg (amelyek kéziil csak egyet lebet kiva- lasztani), kizdrdlag zirt kijelolést tesz lehetdvé, és csak korlatozott szamb lehetéseg kéziili valasztisra ad médot. A komponens egyik kellemes szolgaltatasa, hogy a meg- jelenitett ertékek lehetnek azok, amelyeket be szeretnénk satimni az adatbazisba, de valaszthatjuk a hozzarendelést is. A felhaszn4l6i feliilet értékeit (az. Tt eas tulajdon- sagban tarolt karakterlancokat) az adatbazisban larolt megfelel6 értékekhez rendeli a program (ezek szim vagy karakterlanc alapa kodok, amelyeket a Values tulajdon- sg sorol fel). Példéul a cégen beliili osztalyokat jelz6 szAmkédokat hozzérendelhetjilk néhény leir6 karakterlinchoz: object DERadicGroupl: TDBRadicGroup Caption = ‘Department’ DataField = ‘Department’ DataSource = DataSourcel Items.strings = ( ‘Sales’ ‘Accounting! "Product ion‘ ‘Management ") Velues.strings = ( ny ibe re a") end A DBCheckBox komponens némileg eltérs, mivel egy bedllitis ki- és bekapcsolas4ra hasz- nalhat6, a logikai mez6 értékétdl fliggden. Ez egy korlétozott lista, mert az elemei esak két | értéket vehemek fel, valamint a mezSk meghat4rozatlan allapotat null értékkel. A kompo- nens ValueChecked és ValueUnchecked tulajdonsagat bedllitva hatarozhatjuk meg, hogy a program mely értékeket kiildje vissza az adatbazisba. A DbAware mintaprogram A DbAware mintaprogram a DBRadi o@roup vezérl6nek az el6z6 részben tirgyalt beailité- sokkal val6 haszndlatanak médjat és a DBCheckBox vezérl6 hasznélatat teszi érthetvé ‘A program nem sokkal dsszetettebb, mint a kordbbiak, de egy mez6k6zponta adatfelis- meré vezérl6ket tartalmaz6 form van benne, nem egy tabla foglalja magaba az. dsszes vezérlét. A program formjét a 13.3, abrén léthatjuk tervezési id6ben. 13.3, abra A DbAware mintaprogram adaifelismerd vexéridt tervezési idében a Delphiben. Amint a MyBase 2 programban mér Kithattuk, a ClientDataSet komponens Fieldpefs gytittulajdonsaga segitségével az alkalmazas hatérozza meg sajat tablajanak szerkezeti felépitését. A 13.1, vablézat a meghatérozott mezdk révid dsszefoglalasat tartalmazza, A program véletlenszerti émékekkel talti fel a tablat. Kédja unalmas és nem is tal bonyolult, tehat itt nem is foglalkozom vele részletesebben, de akit érdekel, megrekinthet’ a forris- kodat. 13.1. tablézat_ A A Dbaware mintaprogram mezéi LastName vezetkngy) fiString 20 FirstName (Uténév) fiSuing 20 Department (Osztaly) ‘ftSmallint Branch (Iroda) fistring 20 Senior (Rangids) fiBoolean HireDate (A felvétel dituma) fate Keres6 vezérlk hasznélata Ha az értéklistat egy masik adathalmazb6l nyerjiik ki, akkor a DBLi st Box és a DBCombo~ Box verérl6 helyett a megfelelé DBLookupList Box vagy DBLookupCombobox kompo- nenst kell hasznalnunk. Amikor egy mezOh6z olyan értéket szeretnénk valasztani, amely egy mésik adathalmaz. vala- melyik rekordjinak felel meg (és nem egy mésik rekordot vélasztunk ki megjelenitésre!), minden alkalommal ezeket a komponenseket kell hasznalnunk. Ha példaul egy szabvanyos Grlapot hozunk Iétre megrendelések elfogadasira, a megrende- léselcet tartalmaz6 adathalmazhoz dltalaban tartozik egy olyan mez6, amelyben a megren- delést felad6 Ugyfelet azonosit6 szam talélhaté. Ha kézvetlentil az iigyfélazonosité szémmal dolgozunk, az az emberek szémara nem természetes, a legtébb felhasznal6 jobban szereti az tigyfelek nevét haszndlni, Az adatbazisokban azonban az tigyfelek neveit egy masik tabla tartalmazza, hogy az azonos tigyfél dltal feladott tbb megrendelés esetében elkeriiljvk az tigyfél adatainak tobbszdréz6dését, E helyzet megoldaséhoz helyi adatbaxisoknal és kis méretii indextablékndl haszndlhaté a DBLockupComboBox vezérld, (Ez a megoldas nagy indextablakkal rendelkez6 tigyfél-kiszolgal6 rendszerekre nem vihet6 At valami jél, amint az a kévetkez6 fejezetb6l majd kideril.) A DBLookupComboEox komponens egyszerre két adatforréssal kapesolhat6 dssze: az egyik forrés tartalmazza az adatokat, a masik a megjelenitend6 adatokat. Készitettem egy szabva- nyos Urlapot a Delphi mintaadatokat tartalmaz6 mappajéban lév6 orders . cds fajlt felhas7- ndilva. Az Grlapon tébb DBEALt vezérl6 is taldlhatd, Az iigyfélazonositéhoz kapcsolédé szabvanyos DBEdit komponenst el kell tvolitanunk, é5 egy DBLookupComboBox komponenssel kell helyettesitentink (valamint egy DBText. komponenssel, hogy tkéletesen megeénsiik, mi is trténik itt), A keres6 komponens (ésa DBText) a megrendelés miatt a DataSource komponenshez kapesol6dik, 2z0n. belal is a CustNo (Ugyfélazonosité) mezGhéz. Ha meg szeretnénk engedni, hogy a keresé 3 i : komponens mutassa a mésik féjlb6l (customer .cds) kinyert adatokat, fel Iell venniink egy misik ClientDataSet komponenst is, amely a fijra hivatkozike, valamint egy tj adatforrést. Ahhoz, hogy program mikodj6n, be kell dllitanunk a DBLookupComboBox1 komponens néhiny tulajdons4gat is. ime a sztikséges értékek listéja: object DBLookupComboBox1: THBLOckupComboBox DataField = ‘CustWo' DataSource = DataSourceOrders KeyField = 'Custwo* ListField = 'Company;CustNo' ListSource = DataSourceCustomer DropDownlWidth = 300 end Az els6 ket tulajdonsig szokas szerint a {6 kapcsolatot hatarozza meg, a kovetkez6 négy | pedig a csatlakozashoz hasznalt mez6t (KeyFie1d), a megjelenitend6 adatokat | (GistPield) és a masodiagos forrést (List Source). A megielenitend6 adatoknél megadhatjuk akér tbb mez6 nevét is, amint én is tettem a mintaprogramban. A kombindlt listaban lév6 szdvegként csak az els6 mez6 tartalma lathat6, de ha a DropbowaWidth tulajdonsig énékeként nagy értéket adunk meg, a listaban tSbb oszlopnyi adat is megje- lenik. Az eredmény 2 13.4, 4brin kithat6. 13.4, Abra A CustLookup mintaprogram futtatdsanak eredménye. A DBLookupComboBox mezoben Teves lenyil6 listdin tibb tablamex6 tartalma is megjelenik. Ha a megrendelési adatokat tantalmaz6 CLientbataset. komponens IndexF ieléNames tulajdonsaganak értékeként a Company mez6 van bedltitva, a lenyil6 lista az dgyfélazonosit6 szamok felsorolasa helyett a megrendel6 cégek nevét mutatja bettirendben. Eben a példdban én e2t tettem. Grafikus adatfelismer6 vezérlék ‘A Delphi egy grafikus adatfelismerd vezérl6t is tartalmaz: e7 a DBImage. Ez nem mas, mint az Image komponens kiterjesztése, és egy BLOB mez6ben tarolt képet jelenit meg, feltéve, hogy az adatbazis olyan grafilcus formatumot hasznal, amelyet az Tmage kompo- nens ismer — ilyen példdul a BMP és a JPEG (ha felvessziik a JPEG egységet a uses kiké- tések kGzé). Ha olyan téblnk van, amelyben a komponens Altal ismert grafikus formétum6 képet 14rol6 BLOB talalhat6, akkor a komponenssel térténé ésszekapcsolas rendkivil egyszert. Ha a grafikus formatum valamilyen egyéni Atalakitast kivin meg anak érdekében, hogy meg lehessen jeleniteni, egyszertibb megoldés lehet, ha egy szabvanyos, nem adatfelisme- 16 Image komponenst hasznélunk, és irunk egy k6dot, hogy a képet minden alkalommal frissitse a program, amikor az aktudlis rekord megvéltozik, Miel6tt azonban kifejteném exta témakért, jobban meg kell ismerniink a TDataset osztélyt és az adathalmaz-mez6k osztlyait. A DataSet komponens Miel6tt tovabbmennénk egy adott adathalmaz képességeinek ismertetésével, jobbnak tartom, ha elébb némi teret dldozok a TDataSet osztaly szolgaltatasainak Altalénos bemutatésdra, amelyet kOzdsen haszndl az dsszes Srdk6It adathozzAférési osztaly. A DataSet komponens nagyon ésszetett, az Osszes képességét tehat fel sem sorolom, kizérlag csak az alapelemeit ismertetem. A komponens sz4mos olyan rekordhoz enged hozzaférést, amelyet valamilyen adatfor- rasb6l olvas ki a rendszer, majd bels6 atmeneti tarakban térol (teljesitményndvelési okok- bOD, és amelyeket végs6 soron a felhasznal6 médosit, és lehetdség van arra is, hogy visszairjuk a valtozasokat az dlland6 téroloba. Ez a megoldas elég dltalanos ahhoz, hogy ms t{pusti adatokra is alkalmazzuk (akr még nem adatbézisban tarolt adatokra is), de be kell tartanunk par szablyt « Egyidében csak egy rekord lehet aktiv, tehat ha tb rekordban lév6 adatokat kell elémiink, mindegyikre at kell lépniink, be kell olvasnunk az adatokat, majd 4tlépni a kévetkezdre, és igy tovabb. A Mozgas az adathalmazban cimt részben taldlunk egy ezt és a kapcsolodé megoldasokat bemutaté mintapéldat. * Csak az aktiv rekordot lehet médositani: egyidében nem lehet tb rekordot is médositani, mint a rel4ciés adatbazisokban. * Azakity 4tmeneti tirban lév6 adatokat csak azutén lehet médositani, miutén az adat- halmazra az Edit parancsot kiadva egyértelmien bejelentettiik, hogy zt szeretnénk tenni, Uj, tires rekord létrehoz4s4ra az Insert parancsot, a besziirds és a szerkesztés lezdrasara a Post parancsot haszndlhatjuk. ‘Az adathalmaz tovabbi érdekes, a kovetkez6kben bemutatott elemei az adathalmaz Allapota (és a2 dllapotot megvAltoztaté események), az adathalmazon beliili mozgas és 2 rekcordok dlhelyezkedése, valamint a mez6objektumok szerepe. A DataSet komponens képessé- geinek dsszefoglaldsaként a 13.2. k6dsréveghen mellékeltem az osztély nyilvanos tagfige- vényeit (a kédot az értherdség kedvéért dtszerkesztettem és megjegyzésekkel lattam el.). Ezek koziil a tagfiiggvények kézill nem hasznéljuk mindegyiket minden nap, de a listén mindet feltiintettem, 13.2. kbdszbveg A TDataSet osztély nyilvénos felitete (kivonatolva). TDataset = class (TComponent, IProviderSuppert) public // igtrehozds és megsemmisités, megnyitds és bezdrés constructor Create (AOwner: Component}; override; destructor Destroy; override; procedure Open; procedure Close; property BeforeOpen: TDataSetNotifyfvent read FSeforeOpen write FBeforeOpen; property AfterOpen: DatagetNotifyBvent read FAfterOpen write FAfterOpen; property BeforeClose: TDataSetNot ifyBvent read FSeforeClose write FaeforeClose; property AfterClose: TDataSetNotifysvent read FAfterClose write FAfterClose; Jf Allapotinformécidk function IsEmpty: Boolean; property Active: Boolean read GetActive write SetActive default False; property State: MataSetState read FState; function ActiveBuffer: PChar; property IsUniDirectional: Boolean read FIsUniDirectional write FIeUniDirectional default False; function Updatestatus: TUpdateStatus; virtual; property RecordSize: Word read GetRecordsize; property ObjectView: Boolean read FObjectView write SetObjectViewr property FecordCount: Integer read GetRecoxdcount; function IsSequenced: Boolean; virtual; funetion IslinkedTo(DataSource: TMataSource): Boolean; J) adatforrés property DataSource: TDataSource read GetDatasource; procedure DisableControls; procedure EnableControls; function ControlsDisabled: Boolean; JJ mez6k, beleértve a blobokat, részleteket, szdm{tott mezdket és \ egyebeket function FieldzyName(const FieldName: string): TPield; function FindField(const FieldName: string}: TField; procedure GetFieldlist (List: Tist; const FieldNames: string); procedure GetPieldNames(List: TStringa); virtual; // a Delphi 7 dta ws virtudlis property FieldCount: Integer read GetFieldCount; property Ficldbefs: TFieldDefs read FFieldDefs write Set¥ieldDefs; property FicldDefList: 1FieldbefList read FFieldDefList; property Fields: TFieclds read FFields; property FieldLiat: TFieldList read FFielduist property FieldValues[const FieldName: string]: Variant read GetPieldvalue write SetFieldvalue; default; property AggFields: TFields read PAggFields; property DataSetField: ‘TataSetField read FDataSe:Field write SetDatasetPield; property DefaultFields: Boolean read FDefaultFields; procedure ClearFiclds; function GetBlobFicldData (FieldNo: Integer; var Buffer: TBlobByteData): Integer; virtual; function CreateBlobStream(Field: Field; Mode: TBlobStreanMode): TStrean; virtual; function GetFieldData (Field: TField; Buffer: Pointer): Boolean; overload; virtual; procedure GetDetailDatasets{List: Thist); virtual; procedure GetDetailLinkPields (MasterFields, DeteilFiclds: TList); virtual; function Get¥leldbata (FieldNo: Integer; Buffer: Pointer): Boolean; overload; virtual; function GetFieldData (Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload; virtual; property AutoCalcFields: Boolean read FAutoCalcFields write FAutoCalcFields default True; property OnCalcFields: ThataSetNotifysvent read FOnCalcFields write FOnCalcFields; // elhelyezkedés, mozaés procedure CheckRrowselode; procedure First; procedure Last; procedure Next; procedure Priox; function MoveBy (Distance: Integer): Integer; property RecNo: Integer read GetRecNo write SetRecNo; property Hof: Boolean read FROF; property Eof: Boolean read FEOF; procedure CursorPosChanged; opto Sane property BeforeScroll: TbataSetNotifyEvent read FBeforeScroll write FEeforescroll; property AfterScroll: TDataSetNotifysvent zead FAfterScroll write FAiterSeroll; Lf konyvjelz6k procedure FreeBookmark (Bookmark: TBookmark); virtual; function Gethookmark: TBookmark; virtual; function BookmarkValid (Bookmark: TBookmark): Boolean; virtual; procedure GotoBookmark (Bookmark: TBookmark) ; function CompareBooknarks (Bookmark1, Bookmark2: TBookmark): Integer; ‘> virtual; property Booknark: TBookmarkStr read GetRookmarkStr we write SetRooknarkstr; Jf keresés, hely keresése function FindPirst: Boolean; function Findiast: Boolean; function FindNext: Boolean: function FindPrior: Boolean; property Found: Boolean read GetFound; function Locate(const KeyFields: string; const KeyValues: Variant; options: TLecateOotions): Boolean; virtual; function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; virtual; 1 s2teés property Filter property Filtere: default False; property FilterOptions: TFilterOptions read FFilterOptions write SetFilterOptions default []; Property OnFilterRecord: TFilterRecordEvent read FOnFilterRecord write SetOnFilterRecord; string read FFilterText write setFilterText; Boolean read FFiltered write setFiltered // frissités procedure Refresh; property BeforeKefresh: MataSetNotifyBvent read FBeforeRefresh write FBeforeRefresh; property AfterRefresh: ThataSetNotifyBvent, read FAfterkefresh write FafterRefresh; procedure UpdateCursorPos; procedure UpdateRecord; function GetCurrentRecord (Buffer: PChar): Boolean; virtual; Procedure Resync(Mode: TResyncMode); virtual; // szerkesztés, beszirds, adathazisba kildés és térlés property CanModify: Boolean read GetCanModity; property Modified: Boolean read FModified; procedure Append; procedure Edit; procedure Insert; procedure Cancel; virtual; procedure Delete; procedure Post; virtual; procedure AppendRecord (const Values: array of const); procedure InsertRecord(const Values: array of const): procedure SetFields(const Values: array of const); / a@ szerkesztéshez, beszirdshoz, adatbazisha kildéshez és we cdriéshez kapcsolddé események property BeforeInsert: TDataSetNotifyEvent ‘ read FBeforeinsert write FBeforelnsert; property Afterinsert: TDataSetNotifyavent, \ read FAfterInsert write FAfterInsert; property BeforeFdit: TDataSetNotifyzvent ‘ read FBeforekdit write Fbeforezdit; property AfterEdit: TDataSetNotifyEvent \ read FAfterEdit write FAfterEdit; property BeforePost: TDataSetNotifyevent, read FEeforePost write FBeforePost; property AfterPost: TDataSetNotifyBvent ww read FAfterPost write FAfterPost; property BeforeCancel: TDataSetNotifyRvent \ read FReforeCancel write FBeforeCancel; property AfterCancel: TDataSetNotifyBvent \ read FAfterCancel write FAfterCancel; property BcforeDelete: ThataSetNotifysvent ‘ read FBeforeDelete write FEeforeDelet: property AfterDelete: ThataSetNotifyzvent \» read FAfterDelete write FAfterDelete; property OnDeleteBrror: MataSetErrorEvent \ read FOnDeleteHrror write FOnDeleteZrror; property OnEditError: TDataSetErrorBvent \ read FOnEditError write FOaEditError; property GnNewRecord: TDataSetNotifyzvent ‘ read FOnNewRecord write FOnNewRecord; property GnPostError: TDataSetErrorivent ‘ read FOnPostError write FOaPostError; J) témogatd segédfagovények function Translate(Src, Dest: PChar: ToOem: Boolean}: Integer; virtual; property Desicner: ataSetDesigner read Fhesigner; property BlockReadSize: Integer \ read FSlockReadSize write SetBlockReadsize: property SparseArrays: Boolean ‘ read FeparseArrays write SetSparseArrays; end; Az adathalmaz dllapota Amikor adathalmazzal dolgozunk a Delphiben, ktlénbéz6 dllapotokat hasznélhatunk. Az dllapotokat @ State tulajdonsag jelzi, amely tobb kiilénbéz6 értéket vehet fel. dsBrowse Azt jelzi, hogy az adathalmaz normal béngészési tizemmédban van. Azadatok megtekintésére és a rekordok pasztazasara hasznalhato. askdit Aztjelzi, hogy az adathalmaz szerkesztési tizemmédban van, Az adathalmaz akkor keri ilyen dzemmédba, amikor a program az F4it tagftiggvényt hivja meg, vagy amikor a DataSource komponens Aut oEdit tlajdonséga True (igaz) ériékére van allitva, és a felhasznalo elkezd médositani egy adatfelismeré vezErl6t, amilyen példaul a D8Grid vagy a DBEALt. A megvaltozott rekord adatbazisba kiildése utén az adathalmaz kilép a dsEaiit Allapotbél dsInsext Aztjelzi, hogy Uj rekordot vesztink fel az adathalmazba, Ezt tigy tehetjiik meg, hogy az Insert. vagy az Append tagfiggvényt hivjuk meg, a DBGrid utolsé sordra ugrunk, vagy a DBNav igator komponens megfelels parancsat haszndljuk. dsInactive Azt jelzi, hogy az adathalmaz be van zirva. dsCaleFields Aztjelzi, hogy mez6sz4mitas van folyamatban (amikor az OnCalc- Fields eseménykezelét hivuk meg). dsNewValue, dsOldvalue és dsCurValue Azt jelzik, hogy a gyorstar frissitése zajlik. asFilter Azt jelzi, hogy az adathalmazra sziiré van bedllitva (amikor az OnFilter~ Record eseménykezelét hivtuk meg). Az egyszertf mintaprogramokban az éllapotok kéz6tti atmeneteket automatikusan kezeli a program, de fontos, hogy megértsilk ezeket, mert sok esemény hivatkozik az allapotat- menetekre — péld4ul minden adathalmaz eseményeket indit ¢l barmilyen dllapotvaltozis el6tt és utdn, Amikor a programnak Edit miveletre van szilksége, a komponens kézvei- lenill a szerkesztési tizemmédba lépés el6tt elindit egy BeforeEdit eseményt (ez egy olyan miivelet, amelyet egy kivételt létrehozva allithatunk le), Kézvetlentil a szerkesztési dizemmédba lépés utin az adathalmaz egy AfterRdit eseményt kap. Miutdn a felhasz- ndilo befejezte a szerkesztést, és a Post. parancsot kiadva az adatok mentését keri, az adathalmaz elindit egy BeforePost eseményt (amelyet a bevitt adatoknak az adathé- zisba kildés el6tti ellendrzésére lehet felhaszndlni), a mtivelet sikeres befejezése utan pedig egy AftexPost eseményt. Egy mésik, az elébbinel dltakinosabb Allapotvéltoz4s-kévet6 megoldas a Datasource komponens OnStateChange eseményének kezelése. A pillanainyi dllapotot példaul egy ilyen k6ddal lehet megmutatni: procedure TForml.DataSourceiStateChange (Sender: Object); var strStatus: string; begin ease cds.State of dsBrowse: strstatus ‘Browse’; dsBdit: strStatus tedit'; deInsert: strStatus := ‘Insert’; else strStatus :- ‘Other state’; end; StatusBer.Panels[0].ext := strStatus; Ez.akéd esak az adathalmaz-komponens hérom leggyakoribb Allapotat veszi figyelembe, az inaktiv Allapotot és az egyéb kulénleges eseteket figyelmen kivil hagyja Az adathalmazok mezéi Mint korabban mar emlitettem, az adathalmazban egyszerre csak egy rekord lehet aktiv. Ezt a rekordot egy 4tmeneti tarban (,pufferben”) tarolja a program, és néhany dltalanos tagfligavénnyel hajthatunk végre rajta kiil6nféle miveleteket, de a rekord adatainak eléré- séhez az adathalmaz mez6objektumait kell hasznainunk. Ez megmagyarizza, hogy a mezékomponensek (amelyek a TField os7télyb6l sz4rmaztatott osztélypéldanyok) miért jatszanak ennyire alapveté fontossgtt szerepet minden Delphi adatbazis-kezel6, allsalmazasban, Az adatfelismeré vezérl6k kOzvetlentil kapcsolédnak ezekhez a mez6ob- jektumokhoz, amelyek az adatlazis mez6inek felelnek meg. Alapértelmezés szerint a Delphi futésid6ben, automatikusan hozza létre a TField kompo- nenseket, minden alkalommal, amikor a program megnyit egy adathalmaz-komponenst. Ez azutén torténik meg, hogy a program elolvasta az azzal a tablaval vagy lekérdezéssel krapcsolatos metaadatokat, amelyre az, adathalmaz hivatkozik. A mez6komponensek az adathalmaz Fields tmbtulajdonségaban tirolédnak. Ezeket az értékeket (a tombot kézvetlentil elérve) szém szerint vagy (a FieldByName tagfiiggvényt haszndlva) a nevilk alapjan lehet elérni, Mindegyik mez6 hasandlhat6 a2. aktuilis rekord adatainak olvasdséra és médositséra, ehhez vagy a mez6 Value tulajdonsigat vagy olyan tulajdonsigokat kell hasznalni, mint az AsDate, AsString, AsInteger stb, var strName: string; begin strName := Cds.Fields[0].AsString strName := Cds.FieldByName (‘LastName’) .AsString ‘A Value egy variant (valtoz6) tipust tulajdonsig, ezért a tipusfiigg6 hozzaférési tulajdon- sAgok haszndlata kicsit jobb hatisfolsi, Az adathalmaz-komponensnek van egy gyorsit6 tulajdonsdga is, amely a mez6k valtoz6 tipusd értékeinek elérését segiti: az alapértelme- zelt FieldValues tulajdonsig. Az alapérielmezett tulajdonsag ant jelenti, hogy ezt akét ki is hagyhatjuk a k6dbél, és a szdgletes zirdjeleket alkalmazharjuk kézvetlentil az adat- halmazra: strName := Cds.FieldValues ['LastNeme']; strName := Cds [ 'LastName'); ‘Az, hogy egy adathalmaz létrehozdsakor minden alkalommal létrejénnek a mezdkompo- nensek, csak egy alapértelmezett viselkedés. Ehelyett valassthatjuk azt is, hogy tervezési id6ben hozzuk Iétre a mezSkomponenseket a Fields Bditor (Mezészerkesz16) segitségével (ha makédés kézben szeretnénk létni a mezészerkeszt6t, kattintsunk duplin valamelyik adathalmazra, vagy hivjuk el6 az adathalmaz. vagy az objektumfa nézet helyi mentijét, és ott kattintsunk a Fields Editor parancsra), Miutin létrehoztunk egy mez6t a tébla LastName osdlopaban, a mez6 értékére az Aokxx tagfiggvények valamelyikét a megfelelé mezdob- jektumra alkalmazva hivatkozhatunk: strName :- CdsLastName.AsString; ‘Azon kiviil, hogy a mez6 értékéhez val6 hozzitérésre haszn4ljuk, mindegyik mezGobjek- tumnak vannak az érték vizualis megjelenésének és médositasdnak — ide értve az értéktar- toményt, a maszkok szerkes“tését, a megjelenitési formatumot, a korlitozisokat és szimos egyebet — szabilyozasara szolgalé tulajdonsdgai, Ezek a tulajdons4gok természetesen a mez6 tipusat6l — azaz.a mezGobjektum adott osztalyat6l ~ Riggnek. Ha allandé mez6ket honk létre, egyes tulajdonsagokat beallithatunk tervezési idében, nem kell futasidében kédot immunks (példaul az adathalmaz Aft erOpen eseményében). Bar a mezbszerkeszt6 hasonls a Delphi dltal haszndlt gytijteményszerkeseid programokhoz, a mezék nem a gytijtemények részei, hanem olyan komponensek, ame- Iyeket tervezési iddben hozunk létre, a formosztdly kézzétett részében vannak felsorolva, és az Object Inspector tetején lév6 lenyil6 listaban érhetdk el. Amikor a mez6szerkes7tét megnyitjuk egy adathalmaz médositasdhoz, tiresnek tinik. Nektink kell eldhivni a szerkesztprogram vagy az objektumfa nézethen talalhaté Fields (Mez6k) Alcsomépont helyi menijét, hogy haszndlni tudjuk a szerkeszt6program szolgalta- tasait, A legegyszerdbb miivelet az Add (Felvétel) parancs haszndlata, amelynek segitségé- vel barmilyen mezét felvehetink 22 adathalmaz mezOlistéjara. A 13.5. abra az Add Fields (Mez6k feivétcle) parbeszédablakot mutatja, amelyben a tabla jelenlegi mezéi vannak felsorolva. Ezek az adatbazistabla azon me76i, amelyek mar nem jelennek meg a szerkes2- téprogramban Iévé mezélistn, 13.6. abra A meziszerkesxt6 és az Add Fields parbeszédablak. A mezészerkes76 Define (Meghatdroz4s) paranesa 6j sz4mitot mez6, keres mez6 vagy médositott tipusd mezé felvételét teszi lehet6vé. Eben a parbeszédablakban adhatunk felhasn4lobarat nevet a mez6nek. A névben lehetnek sz6k6z0k is. A Delphi egy belsé haszndlat nevet Allit el6 ~ e7 lesz a mezGkomponens neve -, amely azutan testreszab- hat6, A kovetkez6 lépés: valasszuk ki a mezé adattipusit. Ha sz4mitott mezot vagy keres6 mez6t hoztunk létre, és nem pusztan lemasoltunk egy mezét, amelyet aztan stalaksitottunk mas adattipus haszndlatira, jeluljk be a megfelelé valastogombot. A sz4mitott mez6 meghatérozdsanak médjit a Szmitott mez6 felvétele, a keres6 mezéét a Keres6 mez6k cimtt részb6l tudhatjuk meg. ATPield komponensnek van Name é FieldName tulajdonsdga is. A Name iulajdonsag a szokasos komponensnév, a FieldName tulajdonsdg pedig vagy az adatha- zistdbla oszlopénak neve, vagy a szémitott mezének dltalunk adott név. Ez sokszor t6bbet mond, mint a Name tulajdonsdg, & hasznalhaick benne szokéz0k is. A'TPie14 kompo- nens PicldName tulajdonsagdt a program alapértelmezés szerint bomasolja a Display~ Label tulajdonsagba. A mezinév a szabélyoknak megfelelé barmilyen saévegre lecserél- hei, és tobbek kozbtt arva haszndijak, hogy a tbataset osztdly FicldByNane tagfiigg- vényében megkeressenck a segitségével egy mezit, de haszndt veherpilk a tombjelblésele haszndlatakor is. Az dsszes Altalunk felvett vagy meghatérozott mez6 megjelenik a mez6szerkeszt6ben, és haszndthatjak az adatfelismerd vezérldk, illetve megielenithet6k egy adatbazistéblaban, Haa fizikai adathalmaz valamelyik mez6je nem szerepel a listén, az nem lesz elérhetS a kés6bbiekben. A Fields Editor haszndlata sorin a Delphi a haszndlhat6 mez6k deklaracié- jat hozzdadja 6j komponensekként a form osiélyahoz (nagyjab6l Ggy, ahogy a mentiterve- 26 adja hozz4 a TMenuIt em komponenseket a formhoz). A TF ield osztaly komponensei (vagy pontosabban fogalmazva alosztilyai) a form mez6i, és ezekre a komponensekre hivatkozhanink kézvetlentil a programkédban, ha meg szeretnénk valtoztatni a tulajdonsé- gaikat futdsid6ben, vagy ha le szereinénk kérni vagy be szeretnénk dllitani az értékeiket. A mez6szerkeszt6ben a mez6k sorrendjét a mezSket a megfelelé helyre hazva lehet megvaltoztatni. A megfelelé mezdsorrend kiiléndsen fontos akkor, amikor olyan tablat hatarozunk meg, amelynek az oszlopai ebben a sorrendben helyezkednek el. A mezbket a szerkesziGprogrambél a formra is dt lehet hileni, aml azt teszi lehetGvé, hogy a feflesctdhirnyezet vizudls komponenseket hozzon Iéire helyettink. Ez nagyon hasznos szolgdltatds, amellyel adathdzisokhoz kapcsolddé formok kévzttésekor rengeteg id6t takarithatunk meg. Mez6objektumok hasznélata Mielétt rétéménk egy példara, fussuk at a ‘TPield osztély hasznalatat. Ne becstiljk alé e komponens fontossagét: bar gyakran csak a hattérben hasznaljuk, az adatbazisprog- ramokban létfontossigt a szerepe. Mint korabban mar emlitettem, még ha nem is hatéro- zunk meg ilyen tipusti objektumokat, a Fields témbtulajdonsig, a Fielavalues inde- xelt tulajdonsag vagy a FieldByName tagfiggvény segitségével mindig hozz4férhetiink egy tabla vagy lekérdezés mez6ihez, Mind a Fields tulajdonsdg, mint a FielapyNane fiigevény egy TField tipust objektummal tér vissza, igy néha az as miiveletet kell hasz- nalnunk, hogy ezen alosztélyok adott tulajdonsagainak elérése eldit dttegyuk ezeket az eredményeket a megfelel6 (példaul a TFloat Field vagy a TDateField) ipusra, A FieldAcc mintaprogram egy olyan Grlapot tartalmaz, amelyen hérom gyorsgomb van az eszkéztarpanelen, amelyek segitségével futdsid6ben killinb6z6 mezdtulajdonségokat Iehet elérni. Az els6 gomb a tibla Population (Népesség) oszlopinak formézését valtoztatja meg — ennek végrehajtasihoz hozz4 kell férntink a DisplayFormat tulajdon- saghoz, amely a TFloatPield osztily egyik tulajdonsiga: procedure Form? SpeedButtoniclick (sender: Tobject); begin (cés.FieldByName (‘Population’) as UPloatField) .DisplayFormat 988, BH, BE; end; Amikor a bemené vagy kimen6 adatokhoz kapcsoléd6 mez6tulajdonsagokat allitjuk be, a médosttésokat a tabla minden rekordjéra alkalmazza a program, Amikor azonban a mez6 értékéhez. (value) kapesolods tulajdonsigokat Allitjuk be, mindig, csak az altu- lis rekordot médositjuk. A kévetkez5 kéddal megjelentthetjiik példaul a kijeldit orszag Jakosséganak szimat egy tizenetablakban: procedure TForm2.SpeedButton2Click(Sender: Topject) ; begin ShowMessage {string (cds [‘Name']) +‘: ‘+ string (cds ['Population']}); end; Amikor egy mez6énékhez fériink hozz4, haszndlhatunk tb egymds utdni As-tulajdonsé- got a mez6 pillanatnyi énékének kezelésére egy adott adattipust haszndlva (ha hasznalhat6 ilyen adattipus; egyébként egy kivétel j6n létre): AsBoolean: Boolean; AsDateTime: TDateTime; AsPloat: Double; AsInteger: LongInt; asstring: string; asVariant: Variant; Ezek a tulajdonsigok a mez6 énékének olvasiséra és megvaltoztatiséra haszndlhatk. Amez6 értékének megvaltoztatés4ra csak akkor van méd, ha az adathalmaz szerkesztési iiemmédban van, Az As-tulajdonsdgok haszndlata helyett a mez6 Value tulajdonsdgaval is hozzaférhetiink a mez6 értékéhez. Ez a tulajdonsag vari emt-ként van meghatérozva. A TFie1d komponens egyéb tulajdonsagainak tobbsége, példdul az Alignment, a DisplayLabel, a Displaywidth és a visible a mezé6 felhaszn4l6i feliiletének ele- meit mutaija, és a ktilénféle adatfelismer6 vezérik haszndljék Sket, killonésen a DEGrid. A FieldAcc mintaprogramban a harmadik gyorsgombra kattintva megvaltozik minden mez6 Alignment tulajdonsiga. oe: fee 13.6. dbra A FleldAce mintaprogram kimenete a Center és a Format gombra kattintds utan. a procedure TForm2.SpeedButton3Click (Sender: Tobject) ; var I: Tnteger; begin for I := 0 to cds.Fieldcount - 1 do cds.Fields{i].Alignment := taCenter; end; Ez a valtozas az eszkéztarra Altalam felvett DBGrid és a DBEdit vezérlé kimenetét érinti, amely egyébként az orszg nevét jeleniti meg. Ennek hatisa az 6j megielenitési form’- tummal egyiitt a 13.6, abran lathaté. ‘A mezBosztélyok hierarchigja AVCL szimos mez6osztily-tfpust tartalmaz. A Delphi automatikusan haszndlja ezek egyi- két az adatbézisban megadott adatmeghatérozAst6l ftigg6en, ha megnyitunk futdsidoben egy tablét, vagy amikor tervezési idében a Fields Editor szerkeszt6programot hasznailjuk. A 13.2, tablizat a TField osztély alosztélyainak teljes listajat tartalmazza. 13: 2. ‘éblézat A TField osztaly alosztaly epee eee ee TADIField PObjectField ADT (Abstract Data ‘Type, elvont adat- tipus).mez6, az objektummezdnek felel meg az objektumrelicids adatbizisokban, TAggregateField TFiela Karbantartott Ssszesitést jelképez, AClientDataSet komponensben haszndljak, amint azt a 14. fejezetbol megtudhatjuk, vArrayrield TObjectFiela — Objektumokat tartalmaz6 tomb az objektumreliciés adathxdzisokban. TAutoIncField TIntegerField Pozitiv egész szim, amely egy Paradox tabla automatikus ndvelé mezéjével van ésszekapesolva. (Ez egy kiilénleges me- 26, ami automatikusan 6j értéket kap i minden rekordhoz.) Itt megiegyezném, hogy a Paradox AutoIne mezéi nem mindig mikédnek t5kéletesen, Ciasd a 14. fejezetet.) TBCDField TWumericField — Valés szim, amelyben adott szAma tizedesjegy All a tizedespont utén, TBinaryField TPield Altalaban nem hasznaljak kézvetleniil, Eza kévetkez6 ket osztily alaposztilya. “pslobField Méretkorlat nélkul binaris adat (a BLOB a binary large object, azaz.a nagy binaris objektum kifejezés réviditése), Az elmé- leti legnagyobb méret 2 GB mBooleanField TField Logikai érték. ppytesField TBinaryField Nagy, de régzitett méreti (legfeljebb 64 KB-nyi karakter) tetszSleges adat. TCurrencyField TFloatField Pénzénék a Real adattipussal azonos tartomannyal TpatasetField TObjectFiela — Objektumrelaciés adatbazisokban éndll6 tablinak megfelelé objektum. TDateField ToateTimerield Datumérék. TDateTimeField trield Datum. és id6enék. TFloatField TNumericField Lebeg6pontos szém (8 bajt). TRMTBCDField TNumericField — (tj mezétipus a Delphi 6-0s valtozat- ban.) Val6di bindrisan k6dolt decimélis szam (BCD sz4m), szemben a mar létez6 TSCDField tipussal, amely dtalakitona a BCD-énékeket Currency (Pénz) tipu- siva, Ezt a mez6tipust csak a dbExpress adathalmazok hasznaljak automatikusan. TGraphicField TBlobField ‘Tetszdleges nagysgt Abra. TGuidField TStringField COM Globally Unique Identifier (GUID, globilisan egyedi azonosit6) azonosit6t jelképez6 mez6 (az ADO-tamogatas része). TIDispatehField TinterfeceField IDispatch COM leillletekre mutaté mutatat jelképezé mezé (az ADO- tdmogatis része), TIntegerField TNumericField A hosszti (32 bites) egész sz4mok tarto- minyéba es6 egész szam. TInterfacedField TPield Altalaban nem haszndljak kézvedentil, Ez az alaposatilya azoknak a mezOknek, amelyek adatként tartalmaznak felile- tekre mutat6 mutatékat (1Unknown), ThargeTntField TintegerField Nagyon nagy (64 bites) egész szam. ‘TMemoField TBlobField Tetszdleges hossalisigs sziveg TobjectField ReferenceField ‘SmallIntPield ‘TSQLTimestampField TstringField ‘tTimeield TvarbytesField qVariantField ‘WidestringField TWordField TField TObjectField TintegerField TField oField ‘TDaterimerield TBytesField TPiela TStringField TintegerField on Altalaban nem hasznaljak kézvetleniil Ez az dsszes numerikus mezGosztdly alaposzidlya, Altalaban nem haszndljak kézvetlenil. Ez az alaposztilya azoknak a mez6k- nek, amelyek tamogatjak az objektum- reldci6s adatbazisokat. ‘Objektumra hivatkoz6 mutat6 objektum- reliciés adatlbazisokban. Az egész szamok tartomanyaba es6 egész szdm (16 bites). (Gj mez6tipus a Delphi 6-0s valtozaté- ban.) A dbExpress illeszt6programokban hasznélt datum- és id6megjelenitést témogatja Régaitett (legfeljebb 8192 bajt) hosszi- sigd szdveges adat, 1dGénék, Tetszdleges karakteradat, legfeljebb 64 KB-nyi hosszban. Nagyon hasonlé a TBytesField alaposztélyhoz. Variant adattipust jelképez6 mez6 (az ADO-témogatis része). Unicode karakterlancot (karakterenként 16 bit) jelkepez6 mez6. A szavak vagy el6jel nélkilli egész sz4- mok tartomanyaba es6 pozitiv egész sz4m (16 bites) Barmely mezétipus elérhetOsége és az adatmeghatéroz4soknak valé megfelelése a hasz~ ndlatban lév6 adatbazist6l fgg. Ez kiiléndsen igaz azon mezétipusok esetében, amelyek tamogatjak az objektumreléci6s adatbazisokat, Szémitott mezé6 felvétele Most, hogy a TFie1é objektumokat mar ismerjiik, és lattunk példat furdsidében torténd haszndlatukra is, nézziink egy mintaprogramot, amiben a mezdobjektumokat a mezdszer- keszt6vel, tervezési idében vezetjtik be, majd felvesziink a programba egy szémitott mezét. A country.cds mintaadathalmazban megtalathaté minden orszég lakoss4ganak szama és teriilete ~ ezen adatok segitségével kiszAmithatjuk példaul a népstirdséget. Az Gj, Calc nevi mintaprogram elkészitéséhez az alabbi képéseket kell végrehajtanunk: + Vegyiink fel egy formra egy ClientDataSet komponenst. * Nyissuk meg a Fields Editort. A szerkeszt6programban kattintsunk jobb gombbal, a helyi meniib6l valasszuk az Add Field (Mez6 felvétele) parancsot, majd jeldljiink ki néhany mezét. (En mindet kijeldltem.) * Valasszuk a New Field (Uj mez6) parancsot, és adjunk megfelel6 nevet az tott mezének, és adjuk meg a mez adattipusat (legyen ez mondjuk Float —lebe- g6pontos sim —, ami a TFloatField-et jel6li), amint azt a 13,7, abran latharjuke 13,7. abra Szdmitott mez6 meghatdrozasa a Cale mintaprogramban. Mivel néhdny mezSkomponenst tervexési idoben hozunk létre a mextszer- keszitGvel, nyiludnvald, hogy azokhoz @ mez6khéz, amelyeket dtugrunk, nem tartozik majd objektum. Amint kordbban mar emlitettem, az dtugrott mezok futdstdében sem lesznok elérhetdh a Fields vagy a Piel dByName tulajdonsdggal. Amtkor egy program ‘futdsidcben megnyitja valamelyiletablat, 6 nincsenck tervexési idGben kialakitott mezé- komponensek, a Delphi a tabla meghatarozasa alapjén hoz létre mezGobjektumokat, de ha van néhany tervexési idéhen létrehozott mexé, a Delphi azokat haszndilja, és nem vesz fel tovabbi mexbobjektumokat Az ti mez6 tartalma kiszémitésinak médjat természetesen meg kell adnunk, Ezt 2 szamitast a ClientDataSet komponens OnCaicFields eseménye segitségével hajthatjuk végre, amelynek a kévetkez6 a kédja (legalabbis els6 valtozatban): procedure TForm.cdsCalcFields (DataSet: Thataset); begin cdsPopulationDensity.Value := cdsPopulation.Value / cdsArea.Value; end; A szdmitott mezdk tartalméd a program dltalaban minden rekord esetében kisztimolja, és minden alkalommal tijraszdmolja azt, amikor a rekordot betéltjitke egy belsé atmeneti tarba, iijra é ujra meghivea az OnCalcFields eseményt. Emiatt ezen esemény exeményhezel6jének rendkividl gyorsan végrehajthatonak kell lennie, é a killon- bozé rekordokhor hozzaferve nem vdltoztathatja meg az adathalmaz dllapotét. A sxamt- ott mezbk egy gazdasdgosabh idéfethasenalasi (de gazdasdgralanabb memériafelhasz- néldsii) valtozatat belsoleg kiszdmolt mezok titjdin biztositja a Client Dataset: kompo- nnens: ezcket a mezéeet csak egyszer éribkeli ki a program ~ betbltéskor ~, 6 az eredménys a membriaban tarolja a késGbbi felhaszndlas végett. Minden rendben? Hat egyaltalin nem! Ha Gj rekordot visztink be, és nem Alfijukk be a Po- pulation (Népesség) és az Area (Teriilet) mezOk értékét, vagy ha véletleniil nullara Allitjuk az Area mez6t, az osztas eredményeként kivételt kapunt, amely megneheziti a program tovabbi hasznalatat, Egy masik megoldas, ha az osztasi kifejezés eredményeate minden kivételt kezelink, 6s az igy kapott értékcet nulléra allitjuk: try cdsPopulationDensity.Value := cdsPopulation.Value / cdsArea.Value; except on Exception do cdsFopulationDensity.Vvalue := 0; F end; Van azonban ennél jobb megoldis is. EllenGrizhetjiik, hogy az Area mez6 ériéke meg van-e adva — ha nem nulla -, és hogy nem nulla van-e megadva az énékek€nt. Jobb a kivételek haszndlatat elkeriini, ha el6re szmitani lehet valamilyen lehetséges hiba bekivetkezésére: if not cdsArea.IsNull and (cdsArea.Value <> 0) then cdsPopulationDensity.Value := cdaPopulation.Value / cdsArea.Value else cdsPopulationDensity. Value A cdsCalcFields tagfiiggvény kédja (mindharom valtozatban) kézvetlenil fér hozza néhiny mez6hdz, Ezt azért tudja megtenni, meri a mezOszerkeszt6t haszndltuk, és az automatilusan létrehozta a megfelelé mezédeklaraciokat, amint az a form feltiletdek- laraciéjanak alabbi kivonataban is léthat6 type TealcForm = class (Form) cds: TClientDataset; cdsPopulationDensity: TFloatField; cdsArea: TFloatPield; cdsPopulation: TFloatPield; cdeName: TStringField; edsCapital: TStringPield; cdsContinent: TstringField; procedure cdsCalcFields (DataSet: TDataset}; Minden alkalommal, amikor mezGket vesziink fel a Fields Editorba vagy tavolitunk el abbél, azonnal lathatjuk 2 mtivelet eredményét, ha a tabla szerepel a formon (ez esak akkor nines fgy, ha sajat oszlopobjektumok vannak meghatarozva a tablhoz - ilyenkor gyakran semmilyen valtor4st nem latunk). A sz4mitott me26k értékeit tervezési idében természete- sen nem létjuk, ezek esak futisidében érhetdk el, mivel a leforditott Delphi nyelvi kéd futtatdsdnak eredményeként jonnek létre, Mivel meghatéroztunk komponenseket a mezOkhéz, hasznalhatjuk azokat a tabla egyes vizudlis elemeinek testreszabisira, Ha példéul olyan megjelenitési formatumot szeretnénk bedllitani, amely egy vessz6t vesz fel a szimok ezres tagolisihoz, viltoztassuk ##* #00 fosmatumtira az Object Inspectorban a kivant mezékomponensek DisplayFormat tula donsagat. Ennek a valtoztatasnak azonnal, mar tervezési idében lathat6 a hatsa a tablin. A fentobh emlltent (6 az ele mintaprogramban hasendlt) megjelentiést for- mdium a Windous terileti bedllitdsais haszndilja a kimenet formdzdsara. Amikor a Delphi ditalakitia @ mez6 sadménbhér sxéveggé, a formdzé karakterlinchan lévs vesszit a megfe- elo ThousandSeparator (ezres elvdlaszié) haraklerre cseréli a program. Emiatt a prog- ram kimenete automatikusan illeszti magat a hillonféle tenileti bedlitésokhoz. A magyar bedllitdsokat haszndilé véltozatban példdul a vess6 helyett szok6zbket hasznal a program az exres elvdlasztdshoz. Miutin végeztink a tébla komponensein és mezdin végzett munkéval, sajat Columns tulajdonsdgszerkeszidjével szabjuk testre a DBGrid komponenst. A PopulationDensity (Népstirdiség) oszlopor irdsvédettre allitjuk, az oszlop But tonSty le tulajdonsdgat pedig cbsELlipsis értékre, hogy egyéni szerkeszt6programot biztositsunk, Ha ezt az értéket allitjuk be és a felhasznalé megprobalja médositani a tabla cellajat, egy kis gomb jelenik meg, amelyen harom pont lathat6, A gombra kattintva a DEGrid OnEditButtonClick eseménye indul el procedure TCalcForm.DBGri@igditButtonClick (Sender: TObject); begin MegsageDlg (Format ( "Phe population density (#.2n)'¥13 + lis the Population (#.0nj ‘#13 + ‘divided by the Area (8.0n). ‘#13813 + ‘Edit these two fields to change it.’, [edsPopulationDensity.AsFloat, cdsPopulation.AsFloat, cdsArea.AsFloat]), mtInformation, [mbOK], 0); end: Igazi szerkesztSprogramot nem mellékeliink, csak egy Uzenetet, amely t4jékoztat arr6l, hogy mi a helyzet, amint az 4 13.8, 4brén is lithat, amely a szdmitou mez0k étékeit mutatja, Ha szerkeszt6programot szereménk Iétrehozni, készithettink egy masodik formot a bevitt adatok kezelésére, 277815, se Sumnito| 1830) jogmieo) eRe 13.8, abra A Cale mintaprogram kimenete, Figyeljiak meg a szdmitott Population Density (Népsiiriiség) oszlo- pot & az annak médositasakor megjelen6 gombot a hérom pontial. Keresé mezok A BBLookupComboBox komponens formra helyezése helyett (amirél korabban mar volt 826 a fejezetben) meghatarozhatunkk egy keres6 mezét is, amely egy DRGrid komponens belsejében egy lenyilé keresdlistival jelenithetd meg. Azt mar lattuk, hogy ha egy rgzitett kijelolt részt szeretnénk felvenni a DBGria komponensbe, ahhoz médosithatjuk a Columns tulajdonség PickList altulajdonsdgit, Ha ,€16” kereséssel szeretnénk testreszabni a tablat, meg kell hatéroznunk egy keres6 mez6t a Fields Editor segitségével. Példaként elkészitettem a FieldLookup programot, amely egy olyan tablt tartalmaz, amely a megrendeléseket jeleniti meg. Ebben van egy keresé mez6, amely a megrendelést felveve alkalmazott nevét jeleniti meg, nem a kédszamat. E szolgaltatishoz felvettem az adatmodul- ba egy ClientDataset komponenst, amely az employee. cds adathalmazra hivatkozik. Ezutin megnyitottam a mez6szerkeszt6t a megrendeléseket tartalmaz6 adathalmazok mo- dositésdhoz, és felvettem bele az dsszes mez6t. Kijeldltem az EmpNo mez6t, és a Visible tulajdonsigat False érékre dllitottam, hogy eltévolitsam a bléb6l (teljesen nem lehet eltavolitani, mert az alkalmazotti adathalmaz megfelelé mez6jével kialakitott kereszthivat- kozas létrehozaséra is ezt hasznalja a program). Most mar ideje meghatarozni a keres6 mez6t. Ha végrehajtottuk az elz6 lépéseket, hasz- nilhatjuk a mez6szerkesztdt a megrendeléseket tartalmaz6 adathalmazhoz. A New Field (Gj mez6) parbeszédablak megnyit4sihoz hasznaljuk a New Field parancsot. Az itt meg- adott értékek érinuik a tiblaba felveu tj 27 ield oszily tlajdons4gait, amint azt a mezé DEM-e szemiéiteti: 7 A Delph adaibés ar object cds2imployee: TStringField FieldKind = fkLookup FieldName = '‘Employee' hookuphataget = cds2 nockupkeyFields = 'EmpNo! LookupResultField = ‘LastName’ keyFields = 'EmpNo’ size = 30 Lookup = True end Ez minden, amire a lenyil6 lista (13.9. abra) miikédéséhez szitkség van, és hogy terverési idében megtekinthessiik a kereszthivatkoz4si mez6 értékét is. Megjegyzem, hogy a tabla Columns tulajdonsagat nem kell testreszabni, mivel a lenyil6 gombokat és hét sor értékét alapértelmezés szerint hasznilja a program, Ez azonban nem jelenti azt, hogy ezt a tulajdon- ségot ne lehetne a tibla ezen és mas vizudlis elemeinek tovabbi testreszabasara hasznAlni. fo a nT asst 13.9. Abra A FieldLookup mintaprogram kimenete a tablan beliil egy mdsik adathazistablabol ett érrékeket megjelenité lenyité listaval. A programnak van egy masik sajétos szolgaltatisa is, A két Cl ientbataSet komponens és.a két DataSource komponens nem egy formon vannak, hanem egy adatmodul nevi, nem vizualis komponensek tirolasira haszndlhaté kilénleges taroléban (asd az Adatmo- dulok adathozzatérési komponenselchez cimd széljegyzetet). Az adatmodulokat a Delphi File (F4j) meniijének New (ti) parancsaval érhetjik el. Miutén komponenseket vettiink fel ré, a File meni Use Unit parancsa segitségével dsszekapcsolhatjuk azokat mas formo- kon lév6 vezérlékkel. eet coo az adatmodul ¢ = tarol6 térolot has: Null értékek kezelése mezSeseményekkel Néhdny érdekes tulajdonsig mellett a mezobjektumoknak van néhdny kulesfontossagi eseménye is. Az Onvalidate esemény egy mez6 értékének bévitett évényesttésére haszndlhat6, és ezt kell hasznélni minden olyan esetben, amikor olyan dsszetett szabalyra van sziikségiink, amelyet a mez6 Altal biztositott tartomanyok és korlétozdsok segitségével nem lehet kifejezni, Ezt az eseményt akkor inditja el a program, miel6tt beiena az adatokat a rekordtarba, az OnChange esemény pedig rgtén azutdn indul el, miutan az adatok beirdsa megtértént. abe Két tovabbi esemény ~ az OnGet Text és az OnSet'Text —a mez6 kimenctének testre- szabisara hasznathat6, Bz a két esemény rendkiviil hatékony. Azt teszik lehetdvé, hogy akkor is hasznalhassuk az adatfelismeré vezérldket, amikor egy megjeleniteni kivant mez6 megielenitési média eltér até, amit a Delphi alapértelmezés szerint haszndlna. Anull énékek kezelése j6 példa ezeknek az eseményeknek a haszndlatira, Amikor az SQL kiszolgélékon tires értéket tarolunk egy mez6 értékeként, az nem azonos azzal, mint amikor null értéket térolunk mezéértékként. Az ut6bbi altaléban pontosabb, de a Delphi alapértelmezés szerint tires értékeket hasznél, és ugyanazt a kimenetet jeleniti meg tires 5 null értéket tartalmaz6 mez6 esetében egyarint. Bar ez a visellkedés altalaban hasznos Iehet karakterlancok és szamok esetében is, igaz4b6l détumoknal rendkiviil fontos, ahol nehéz, bedilitani ésszert alapértelmezett értéket, és ahol ha tréljtik a mez6 értékét, ér~ vénytelen bemenetet kaphatunk. A NullDates program adot szdveget jelentt meg azokhoz a détumokhoz, amelyek null éxtéket tartalmaznak, és torli a mezét (null értékre Allitva azt), amikor a felhasznal6 tires karalsterlancot haszndl bemenetként, Ime a mez6 két eseménykezel6jének idevags kédia: procedure TForml.cdsShipDateGetText (Sender: TField; var Text: String; DisplayPext: Boolean); begin if Sender.TsNull then Text = '" else Text := Sender.Asstring; end; procedure TForml.cdsShipDateSetText (Sender: TField; const Text: String); begin af Text = '' then Sender.Clear else Sender AsString end; Text; A 13.10, abra egy példa a program kimenetére ~ a példaban egyes szallitasi détumok etéke meghatarozatlan érték (vagy nul), A Delphi 6-0s és 7-¢s valtozatéban a null értékek kezelésére kihathatnak a ,null variant”-ok mitkédéséhen létrejétt valtozdsok. Amint a 3. fejezetben is irtam, a null ériéket tartalmazé mexét egy masike mezével dsszehasonlita a Delphi legitjabb valtozata esctében mas eredményt kapunk, mint a korabbiakban. Amint ott kifeftettem, a Delphi 7-ben globdlis valtozdkat hasznalhatunk a variantok bevondsdval végzett dssze- hasonlitésok eredményének finombedl ‘ira. ist ot sures van a85 28/05 13.10. abra A NullDates mintaprogram az adatmeztle OnGetText & az OnSetText eseményének kezelésével null Entékek esetén egy adott kimenetet ad. Mozgas az adathalmazban Azt mar tudjuk, hogy az adathalmaznak csak egy aktiv rekordja lehet. Ez az aktiv rekord a felhaszndlok tenykedése kévetkeztében vagy az adathalmaznak adott bels6 parancsok hatasdra gyakran valtozik. Az adathalmazban val6 mozgasra és az aktiv rekord megwaltoz- latdsara a TDataSet osztily tagfliggvényeit haszndlhatjuk, amint azt a 13.2. kédszévegben lathattuk. Atléphetiink az l6z6 vagy a kévetkez6 rekordra, eldre- vagy hétraugorhatunk egy adott szimti rekorddal (a MoveBy segitségével), vagy egybél a7 adathalmaz els6 vagy utolsé rekordjéra ugorhatunk. Ezek az adathalmaz-mbveletek a DBNavi gator kompo- nensben, illetve a normal adathalmaz-milveletek kézatt érhetdk el, és nem nehéz megér- teni Gket, Ami nem egyértelmd, az az, hogyan kezeli az adathalmaz a széis6s6ges helyzeteket. Ha megnyitunk barmilyen adathalmazt a meliékelt navigatorral, azt léthatjuk, hogy amint rekordrél rekordra haladunk, a Next (Tovabb) gomb mokidéképes marad még az uiols6 rekord elérése utén is. A gomb csak alkor valik hasznalhatatlannd, amikor tovabblépiink egy, az utolsé rekord uténi helyre (és az aktualis rekordot kézben nem médositjule). Ennek oka, hogy az Hot (f4jl vége) ellen6rzés csak alskor fut le sikeresen, ha a kurzor 2x utols6 rekord utin egy adott helyen all. Ha a Iépegetés helyett azonnal a Last (Utols6) gombot hasznéljuk, azonnal a fajl végén taléljuk magunkat. Ugyanezt a visellkedést tapasz- talhatjuk az els6 rekord elérésekor (és a Bot ~ fajl kezdete ~ ellendrzés futtatasakor) is. Amint nemsokéra létni fogjuk, ez a megkézelités azért hasznos, mert végigpas7tizhatjuk az adathalmazt egészen addig, amig az Eof értéke igaz nem lesz, és ha elétjik ezt a pon- tot, biztosak lehettink aban, hogy az adathalmaz utols6 rekordat is feldolgoztuk. A rekordrol rekordra lépés és az adott szami rekorddal valé ugras mellett idGnként arra is saiikség Iehet, hogy egy adomt rekordra vagy helyre ugorjunk. Egyes adathalmazok vamo- galjak a RecordCount: tulajdonsdgot, és mégengedik, hogy a Reco tulajdonsag segitsé- gével az adathalmaz adott helyén lévé rekordra ugorjunk. Ezek a tulajdonsagok csak olyan adathalmazok esetében haszndlhat6k, amelyek alapértelmezés szerint tamogatjak a hely- megaddist, tehat ez tulajdonképpen az dsszes Ugyél-kiszolgal6 felépitésti rendszert kizarja, kivéve, ha lekérjiak az Gsszes rekordot egy helyi gyorstarba (ez olyan lépés, amit Altaléban Jehetdleg keriilni kell), és a gyorstarban mozgunkca rekordok koz6tt. A 14. fejezetben lati fogjuk, hogy amikor egy SQL kiszolgdlén inditunk el egy lekérdezést, csak azokat a rekor- dokat kéri le a rendszer, amelyeket haszndlunk is, igy a Delphi nem ismeri a rekordok svimat (egalibbbis nem el6re), ‘Az adathalmazban 1év6 rekordra hivatkozdsra két médszert hasznélhatunk, az adathalmaz- tipustél fiiggetlent: © Menthetiink egy hivatkozast az aktualis rekordra, majd az adathalmaz bejarasa utan visszaugorhatunk oda, Ezt konyvjelz6kx segitségével hajtharjuk végre, a TBookmark vagy a korszerdbb TRookmarksStr formon, Ezt a médszert a Konyvjelz6k hasznd- lata cimd rész ismerteti. * Alocate tagfilgevény segitségével olyan rekordot kereshettink az adathalmazban, amely adott feltételeknek felel meg. Ez a médszer, amelyet a kévetkez6 részben ismertetek, még akkor is hasznalhat6, ha bezarjuk, majd djra megnyitjuk az adat- halmazt, mert ilyenkor logikai (és nem fizikai) szinten dolgozunk. A tabla egy oszlopanak Gsszege A mintaprogramokban egészen iddig a felhaszndl6 megtekinthette az adathizistabla pilla- natnyi tartalmat, és ,kézzel” médosithatta az adatokat, illetve beszichatott tj rekordokat. Most azt fogjuk L4tni, hogyan iehet megvéltozeatni a t4bl4ban lév6 adatokat programkéd Stjén, Az alkalmazotak adatait tartalmaz6 adathalmazban, amelyet korabban mar haszndl- tunk, van egy Salary (Fizetés) mez6, hogy a vallalat vezetdje a tiblan végigmenve médo- sithassa barmelyik dolgoz6 fizetését. De mennyi a cég teljes bérkéltsége? Es mi van akkor, ha a (6ndk mindenkinek emelni (vagy csdkkenteni) akcarja 10 szazalékkal a fizetésé? A programban, amely egyben a szokésos adathalmaz-miveletek végrehajtiséra haszn4l- hat miiveletlista haszndlatat is szemlétteti, vannak olyan gombok, amelyek segitségével kisz@molhaté a jelenlegi bérek Ssszege, és médosithatk is a bérek. A rotal (Gsszeg) mitivelet az dsszes alkcalmazoit bérkéltségének kiszamitésat teszi lehetvé. Ehhez a prog- ramnak végig kell pasztaznia a tablat, és minden rekordbél ki kell olvasnia a cdsSalary mez6 énékét. Format (‘8m', (Total]), mtinformation, {mbOk], 0); end Eza k6d mOkédik — amint az a 13.11, abran léthaté eredménybél kidertil -, de van vele némi gond. Az egyik az, hogy a rekordmutat6 az. utols6 rekordta All, fgy elvész az az infor: mécio, hogy hol allt eredetileg. A mésik pedig az, hogy a felhasznaloi feliiletet til sokszor frissiti a program a mtivelet soréin. 13.11, ébra A Total mintaprogram futtatasdnak eredménye, amely az alkalmazottak teljes bérkbltséges mutatja. Kényvjelz6k hasznélata Ha ki szeretnénk kiiszbélni a fentebb emlitett két gondot, le kell titanunk a fiissitéseket, és mententink kell a rekordmutat6nak a bldban a miivelet megkezdése elétt elfoglalt helyét, majd a mavelet végeztével vissza kell azt dllitani. Eat a rablakonyyjelz6 segitségével tehetjtik meg. Ez egy olyan kiilénleges valtoz6, amely egy rekord adathazistéblaban elfog- lalt helyét térolja. A Delphi hagyomanyos médszere az, hogy bevezet egy TBookmark adattipusba tartoz6 valtoz6t, majd kezd6énéket ad neki, mikézben lekéri a pillanatnyi helyzetet a tablabol: var Bookmark: TBookmark; begin var Total: Double; begin Total t= 0; cds First; while not cds.SOF do begin Total := Total + cdsSalary.Value; cds .Next; end; MessageDlg (‘Sum of new salaries is ‘+ Bookmark := cds.GetBocknark; | Az Act ionTotal Execute tagftiggvény futtatésa utdn a kévetkez6 két utasitéssal Allithatjuk vissza a korabbbi helyzetet, és tordlhetjiik a kényvjelz6t (ezeknek egy finally blokkon be- Jal kell lennitk, hogy a mutaté meméridja biztosan fel legyen szabaditva): cds-CotoBookmark (Bookmark) ; cas.FreeBookmark (Bookmark) ; Egy jobb (és korszertibb) médszer, ha a TDataset osztily Bookmark tulajdonsagat hasz- naljuk, ami egy olyan kGnyvjelz6re hivatkozik, amelyet aztin automatikusan eldob a prog- ram. 622 a tulajdonsigot egy dtldtscatian karakterldnc formajaban valésitottak meg ~ ami egy olyan szerkezet, amelyet a karakterlénc élettartam-kezel6je kezel -, de ez val6jaban nem karakterldne, tehat a program nem feltételezi, hogy meg szeretnénk nézni a tartalmat,) Az cldz6 kédot gy kell médositani: var Bookmark: TBookmarkstr; begin Bookmark := cds.Bookmark; eds Bookmark := Bookmark; Ha ki szeretnénk ktiszbolni a program mellékchatasait (hogy ne lissuk a rekordok gorge- tését, amikor az eljérds végigbngészi az adatokat), ideiglenesen kikapcsolhatjuk a tibla- hoz kapesolédé vizualis vezérl6ket, Az adathalmazhoz tartozik egy Disablecontrols tagfliggvény, amelyet meghivhatunk, miel6t. még elindulna a while ciklus, és egy EnableContro1s tagfiiggvény, amelyet a mivelet végén, a rekordmutaté visszaillitasa el6tt kell meghivnunk. Az adathalmazhoz kapesolédé adatfelismeré vezérlék hosszan tarté miive- letek kéicbeni kikapcsoldsa nemcsak a felhaszndléi feltitet megjelenését javitja (azéltal, hogy @ kimenet nem véltozik dllandéan), de jelentésen fel is gyorstija a programot. A Jethaszndiéi felilet frissitésére forditott idé sokkal tobb, mint a szimolasi mitveletek uégrehajtésdra forditot. He ellendrizni szeretnénk ezt, megjegyzésjelekkel kapcsoljuk ki @ Total mintaprogramban a DisableControls és az EnableControls tagfitggvényt, és mar léthatjuk is a sebességhttlonbséget. Némi veszélyt jelentenek a tabla adatainak kiolvasasa kOzben jelentkez6 hibak,, kiiléndsen akkor, ha a program hélozaton kereszttil, egy kiszolg4lérdl olvassa be az adatokat. Ha bir- milyen gond lépne fel az adatok beolvasasa kézben, kivétel jon létre, a vezérldk tovaébbra is Kikapesolva maradnak, és a program nem tud vissza4lini normal mtikédésre. Ennek a hely- zetnek az elkeriilése érdekében basznaljunk try/final ly blokkot, sét, ha azt szeretnénk, hogy a program 100%-osan hibattré legyen, haszndljunk két egymésba agyazott try/fi- naily blokkot. A kéd ezelckel a médositésokkal a kévetkez6képpen ala! procedure TSearchForm.ActionTotalExecute (Sender: TObject}; var Bookmark: TBeokmarkstz; Total: Double; begin Bookmark := Cds.Bookmark; ery cds.Disablecontrols; Total := 0; try eds. First; while not cds.FOF do begin Total := Total + cdsSalary.Value; cds Next: end; finally cds. Enablecontrols; end finally cds.Bookmark := Bookmark; end; MessageDlg (‘Sum of new salaries is | + Format ('&m', [Totel]}, mbInformation, [mbOK], 0); end; Ezt a kSdot azért irtam, hogy megmutassam egy példan, hogy egy ciklussal hogyan lehet divizsgdini egy adatbazis artalmat, de van erre mas megoldas is, amely egy olyan SQL lekérdezésen alapul, amely a mez6k dsszegének ériékével tér vissza. Amikor SQL kiszolgdlot hasznalunk, az SQL hinds sebességheni elnye az dsszeg kiszdmitdsa sordin jelentés lehet, mert nem kell minden mez6 ésszes adatdt dtvinni a kiszolgalérél az tigyfélre. A kiszolgal6 csak a végeredményt kitldi el az tigyfélnek, Van azonban egy még ennél is jobb médszer: ha egy CLientDataSet komponenst haszndlunk, mivel egy oszlop adatainak éssveadasa az OsszesitOk dltal nytijtott szolgdltatdsok egyike (exekrél részletesebben a fejezet vége felé esik majd sz6). Itt egy dltalanos megoldast ismertettem, amely minden adathalmaz esetében hasznalhate A tabla egyik oszlopénak médositésa A ndvelési miivelet kédja hasonlé az eldbb latott miveletéhez, Az ActionIncrease~ Execute tagfiiggvény itt is atvizsgalja a tablat, és kiszAmolja a fizetések dsszegét, ahogy az elébbi tagfiiggvéay tette. Bar ebben a kédban csak kett6vel tbb utasitas van, van egy alapvet6 kilénbség: amikor emeljik a fizetéseket, megvaltoztatjuk a tablaban lév6 adato- kat. A két kulesfontossagii utasitas a while cikluson belil talalhate: i while not cds.B0F do begin cds. Bait; cdsSalary.Value := Round (cdsSalary.Value * Spin#ditl.value) / 100; gotal := Total + cdsSalary.Value; cds.Next ; end; Az els6 utasitas szerkesztési tizemmdédba Allitja az adathalmazt, hogy a mez6k madositasai azonnal érvénybe Jépjenek. A masodik utasitas kiszmitja az tj fizetést, megszorozza a tégi fizetést a SpinEdit komponens értékével (amely alapértelmezés szerint 105), majd closztja az eredményt 100-zal. Ez $ % béremelést jelent, bar az értékek kerekftve vannak alegkézelebbi egész dollérértékre. Ezzel a programmal bérmekkora mértékben megvéil- toztathatjuk a béreket egyetlen gombnyomédssal. BE iy eijitte meg, hogy az adathalmaz mindig szerkesztést tizemmédra dil dt, amikor lefut awhile ciklus. Ennek az az oka, hogy az adathalmazban szerkesztési mit- veletek eayszerre csak egy rekordon végezhetdk. A scerkesziési mitveletet be kell fejezxntink a Post tagfigguenyt meghivua, vagy dtlépve egy masik rekordra, mint az eltiz6 kédban Ezutdin egy masik rekord megualtoztatdsdhoz ijra be kell lépntink a szerkesotési tazem- médba ‘Az adatbazistébla testreszabaésa A legtébb adatfelismeré vezérl6tdl eltérden, amelyekben kevés beéilithat6 szolgaltatas talalhat6, a DEGrid vezérlének sz4mos beallitasi lehetdsége van, és a vezérl6 solckal ha- tékonyabb, mint gondolndnk. A kévetkez6 részek a DBGr id haszndlavaval végrehajthaté halad6 milveletek egynémelyikét ismentetik, Az els mintaprogram azt mutatja be, hogyan Iehet egy tdbl4ban (adatracsban) rajzolni, a mésodik azt, hogyan lehet tb rekordot kije- lolni egy tablaban, Rajzolas az adatracsra Sok oka Jehet annak, miért szeretnénk megvaltoztatni egy tabla kinézetét. J6 példa ere mondjuk adott mezék vagy rekordok kiemelése, illetve hogy megjelenitsiink olyan mez6- ket is a kimeneten, amelyek dltalaban nem jelennek meg a tablaban — ilyenek példaul a BLOB, az abrdk és a jegyzetmez6k Ha szeretnénk alaposan testreszabni egy DBGrid vezérl6 kinézetét, a Default Drawing tulajdons4got False értékre kell dllitani, és kezelni kell annak OnDrawColumiCeli cseményét. Ha a Default Drawing tulajdonsagot True értékre Allitva hagyjuk, a tabla a tagfiiggvény meghivasa elétti alapértelmezett kimenetet jeleniti meg. Ebben az esetben nem tudunk mast tenni, mint felvenni valamit a tabla alapértelmezés szerinti kialakitasdba (hacsak tigy nem dontink, hogy az adatrics f6lé rajzolunk, ami tovabbbi id6t vesz igény- be, és a kép villddz4sat eredményezheti). ‘A masik megoldés, hogy meghivjuk a tabla DeZau1tDrawColumnCel 1 tagfiiggvényét, mondjuk a hasznalt betttipus megvaltoztatésa vagy a kimeneti méret korkitozésa utdn. Az utdbbi esethen létrehozhatunk egy tovbbi abrat a celléban, és hagyhatjuk, hogy a komponens a fennmaradé helyet a szabvanyos kimenette] titse ki. A DrawData prog- ramban ezt valésitottam meg, Ebben a mintaprogramban a DBGrid vezérlének, amely a Borland Klasszikus Biolife tablajahoz kapesol6dik, a kovetkez6 tulajdons4gai vannak: object DBGridl: TDBGrid Align = alClient DataSource = DataScurcel DefaultDrawing = False OnDrawColumnCell = DEGrid1DrawColumncell end Az OnDrawColunnCel1 eseménykezelot a tabla minden celléjahoz meghivja egyszer a program . Az eseménykezeldnek tb paramétere is van, tobbek k6zt a cellnak megfe- lel6 téglalap, a még megrajzolandé oszlop indexe, maga az oszlop (a mezével, annak igazitasdval és egyéb altulajdonségokkal), valamint a cella Sllapota. Ha a megadott cellék szinét pirosra szeretnénk valtoztatni, ezt a kévetkez6 esetekben lehet megtenni procedure T¥orml .DRGridiDrawColumnCell (Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColuma; State: TGridprewState) ; begin J/ a betdszin legyen piros, he a szoveghossz > 100 karakter if (Column.Field = cdsLengthcm) and (cdsiengthom.AsInteger > 100} then DBGridl.Canvas.Font.Color := clRed; Jf az alapértelmezett rajz DBGridi.DefaultDrawDataCell (Rect, Columi.Field, State); end; A koverkez6 Iépés a jegyzet (memo) és a grafikus mez6k megrajzolsa. A jegyzet esetében megvalésithatjuk a mez6jének onGet'Text és Onget'Text eseményét. A tibla akkor is megengedi a jegyzetmez6 médositisat, ha a mez6 onSet‘Text eseményének értéke nem nil, A két eseménykezel6 kédja alabb lithat6, A ‘Trim utasitast az adatok utén All6, nem nyomtathat6 karakterek eltavolitisa végett haszndltam, amelyek kévetkeztében szerkesztés kézben a széveg ,iiresnek” ttinik: procedure TForml.cdsNotesGetText (Sender: TPield; var Text: String; DisplayText: Boolean); begin Text := Trim (Sender.AsString); end; procedure TForml.cdsNotesSetText (Sender: TField; eonst Text: String); begin Sender.Asstring := Text; end; A kép esetében a legegyszertibb médszer egy ideiglenes TBitmap objektum létrehozésa, a grafikus mez6 hozzarendelése ahhoz, majd a bitkép megielenitése a tabla Canvas kom- ponensén. Egy masik megoldsként eltavolithatjuk a grafikus mez6t a tablabol a talajdon- sgot hamis értékse Allitva, majd felvehetjak a képet a halfaj nevéhez. Ehhez a kévetkexs kiegészit6 k6dot kell felvenni az OnDrawColumnCel 1 eseménykezeldbe. var Picture: TPicture; OutRect: TRect; PietWidth: Integer; begin // az alapértelmezett kimeneti céolalap OutRect := Rect; if Colum.Field = cdsCommon_Name then begin (/ a kép megrajzoldsa Picture := TPicture.Create; try Picture.Assign(cdsGraphic) ; PictWidth := (Rect.Bottom - Rect.Top) * 2; OutRect Right := Rect.Left + Pictwidth: DBGridi.canvas.StretchDraw (OutRect, Picture.Graphic); finally Picture. Free; end; (/ 2 kimeneti téglalap visszadilitdsa, helyet hogyva az dbrénak OutRect zs Rect, OutRect Left end; OutRect Left + PictwWidth; // a bettszin piros szintre dilitdsa, ha a szdveghossz > 100 karakter (a kédot ldsd fentebb) (/ az alapértelmezett rajz DbGridl.DefaultDrawDataCell (OutRect, Column.Field, state); Amint ebb6l a kodbél léthat6, a program egy kis téglalapban jeleniti meg a képet a tabla- cella bal oldalén, majd az alapértelmezett rajzolas elinditésa elit megvéltoztatja a kimeneti téglalapot gy, hogy abban a fennmaradé teriilet jelenjen meg. Az eredmény a 13.12. dbrén lathaté SRE Cio ‘age ited Emperor “ef Giant Maori Winwee “GR vive Angelish ‘Gymaathorex mordex hiodon elongetue “ sota0 eet suian Cod 13.12, 4bra A DrawDaia program egy olyan tdblat jelenit meg, amelyben egy jegyzetmezd szdvege & @ Borland halat talathatck. Tébb rekord kijelélését lehet6vé tevé tabla A DEGrid vezérl6 testreszabési lehetdségeit bemutato masodik mintaprogram tébb rekoxd egyidejti kijeldlését szemlélteti. A DBGr id bedllithato gy is, hogy tb sort (azaz tobb rekordov) lehessen kijeldlni a tablaban. Ezt nem nehéz megesinalni, mivel nem kell mast tenniink, mint az adatrécs Opt ions tulajdonsaganak dgMultiselect elemét 4tallitani a masik lehetséges Allésba. Miutan ext a beallitast valasztottuk, a felhasznal6 a Crat. billen- tydt lenyomva tartva az egér bal gombjaval a vabla tb soréra kattinthat, sorban egymas utin kijeldlve azokat, amint az a 13.13. 4brén léthat6, 13.13, bra Az MitGrid mintaprogram egy olyan DBGrid vezéri6t tartalmaz, amely tObb sor kijelolését teszi leheivé. Mivel az adatbazistblaban csak egy rekord lehet aktiv, a tabla egy kényvjelz6lista segitsé- gével tartja nyilvan, hogy mely rekordok vannak kijeldlve. Ez a lista a Select edRows tulajdonsagban érhet6 el, amely PBookmarkList tipust. Azon kivill, hogy a Count tulaj- donsaggal megtekinthetjik a listén szerepl6 objektumok szémét, minden kényvjelz6hiz is hozzaférhetiink az Ttems tulajdons4ggal, amely az alapértelmezett tombtuljdonség, ‘A lista mindegyik eleme TBookmarkStr tipusti, azaz konyvjelz6mutatot jelképez, amely hozzarendelhet6 a tabla Bookmark tulajdonsagahoz, ATBooknarkStr egy kénpelmi szolgdltatdsokat nytijié karakterlancripus, de a benne lév6 adatokat atlatszatlannak és ideiglenesnek kell tekinieni. A kényujelzoérté- kekként tarolt adatok egyik szerkezeti felépitéschen sem szabad megbizni, & nem érdemes azokat til sokdig megtartani vagy kiilénalis fajlokban taroini. A kOnyujelzoadatok az adathizis-tllesztdprogramtél é& az indexbedllitast6l fiiggden viltoxnak, & haszndlhatat- lannd vilhatnak, amikor tj sorokat vesziink fel egy adathalmazba vagy sorokat térkiink abbl (vagy ha az adatbéizis mas felhasandlot tesetk e21). A fenti lépések Ssszegzéseként itt az MltGrid mintaprogram kédja, amelyet a gombra kattintva lehet elinditani, hogy a kijellt rekordok Name (Név) mez6jének énékér athe- lyezziik a listara: procedure TForml.ButtoniClick (Sender: Tobject): var I: Integer; BookmarkList: TBookmarkList; Bookmark: TBookmarkstr; begin // a jelenlegi helyzet tdroldsa Bookmark := cds.Bookmark; try d/ @ lista tartalménak torlése ListBoxt.Items.Clear; // a kijeléit sorok megszerzése a tdébldbdl BookmarkList := DbGrid1.SelectedRows; for I := 0 to BookmarkList.Count - 1 do begin // minden esetben ugrds a tabla adott rekordjéra oGs.Bookmark := BookmarkList (1); // a name (név) mezé tartalménak felvétele a listéra ListBoxl.Items.add (cds.FieldByName (‘Name’) .AsStxing); end; finally // vissea a kiinduldsi rekordra cds.Bookmark := Bookmark; end; end; Téblaéba hazés Egy masik érdekes megoldas az egérrel val6 hzds haszndlata a tablak esetében. Tébldbot hazni nem nehéz, mert tudjuk, hogy a felhaszndl6 melyik rekordot és oszlopot valasztorta ki, am a tabldba hizas trikkés programot kivan, Emlékezziink vissza, hogy a 3. fejezetben emiitettem a protected hack" megoldst ~ most ezt fogom hasznélni a tabléba hizas vég- rehajtasara is. A DragToGrid mintaprogram egy tablat tartalmaz, amely az, orszagok adatait tartalmazd adathalmazhoz kapesol6dik, egy szerkesziGmez6t, amelybe beirhatjuk a mez6 tj értéket, és egy cimkét, amelyet a tébla egyik cell4ja f6lé hGzhatunk, ha médosftani szereinénk a meglelelé mez6t. A gond az, hogyan hatérozzuk meg ezt a mez6t. A k6d csak par sorbél All, amint alébb lithat6, de rejtélyes, és nem Art hozad némi magyarézat, type TDBGHack = class (TDbGrid) end; procedure Trorndyag.DB¢ridipragbrop (sender, source: Tobject; wx, Ys Integer); var ge: TGridcoord; begin ge t= TDBGHack (DbGridl}-MouseCoord (x, y); Af (ac.y > 0) and {oc.x > 0) then begin DbGridl. DataSource. DataSet .Moveby (gc.y - TDBGHack(DbGridi) -Row) ; DbGridt.DataSource.NataSet .Bdit; DBCridi.columns.Items [gc.X - 1].Field.Asstring := BditDrag. Text; end; DRGridl. SetFocus: end; Az els6 miivelet azt a cellét mutatja meg, amely felett az egérgombot felengedtiik Az egérmutaté x és y koordinaedit hasznélva meghivhatjuk a védett MouseCoord tagfigg- vényt, hogy hozzaféshessiink a cella sordhoz és oszlopéhoz. Hacsak az athtizés célpontja nem az els6 sor (itt dltalaban a cimek talilhat6k) vagy az els6 oszlop (amely dltalaban a jelz6t tartalmazza), a program odébbhelyezi az aktualis rekordot a kivant sor (gc .y) és az aktiv sor (ez a tabla védet Row tulajdonsaga) k6zétti eltérésnek megfelel6 tavolsaggal. A kévetkez6 lépés szerkesziési tizemmédba helyezi az adathalmazt, lekéri a céloszlopban lev6 mezot (Columns Items [gc.X~ 1] Field), és megvaltoztatja annak srdvegét. Szabvanyos vezérldket haszndlé adatbazis-kezelé alkalmazdsok Bar dltalaban gyorsabb, ha adatfelismeré vezérl6ket felhaszndlva irunk Delphi alkalmaza sokat, ez nem megkeriilhetetlen megoldas, Ha egy adatbazis-kezel6 alkalmazas felhaszn: feliiletének pontos vezérlésére van sztikségiink, ajénlott testreszabni a mezSobjektumokbél a vizudlis vezérldkbe val6 adatatvitelt. Az én véleményem az, hogy esak kiilénleges esetek- ben érdemes igy eljamni, mert az adatfelismerd vezéridk a tulajdonsigok testreszabasaval és a mezGobjektumok eseményeinek kezelésével nagyon {61 bedllithatOk. Ha azonban meg- probélunk az adatfelismer6 vezérlok nélktil dolgozni, az segithet jobban megérteni a Delphi alapéstelmezés sverinti viselkedését. Anem adatfelismer6 vezérl6k6n alapulé alkalmazasok fejlesztése két eltéré modszer szerint t6rténhet: utanozhatjuk a kédban a Delphi szabvanyos viselkedését, amelyt6l néhény esetben valdszindleg el kell szakadnunk, vagy haszndlhatunk egy pontosabban testreszabott valtozatot. Az els médszert a NonAware mintaprogrammal, a mésodikat a SendToDb mintaprogrammal szemléltetem. A Delphi adatfelismeré vezérléinek utanzésa Ha olyan alkalmazAsokat szeretnénk késziteni, amelyek nem haszndlnak adatfelismerd verétléket, de mégis tigy viselkednek, mint egy szokvényos Delphi alkalmazis, irhatunk esernénykezeldket azokhoz a miiveletekhez, amelyeket az adatfelismerd vezérldk automa- tikusan végrehajtannak. Aiapjaban véve szerkesztési tizemmédba kell helyezni az adat- halmazt, amikor a felhaszn4l6 megvaltoztatja a vizudlis vezérl6k tartalmat, és frissiteni kell az adathalmaz mez6objektumait, amikor a felhaszndld kilép a vezérl6kb6l, és egy masik elemre helyezi a fokuszt Fz a megoldas a nem adasfelismerd vezérlok szokvdnyos alkalmazdsokba ualé beépitése sordn lehet hasznos. A NonAware mintaprogram mésik eleme egy, a DBNavigator komponensben levé gombok egy részének megfelel6 gombokat tartalmaz6 gomblista. Ezek a gombok &t egyé- ni mtivelethe2, kapcsolédnak. A szabvanyos adathalmaz-madveleteket ebben a mintaprog- ramban nem tudtam haszndlni, mert azok automatikusan hozzdkapcsolédnak ahhoz, 22 adatforrashoz, amely ahhoz a vezérlhéz van tirsitva, amellyel a felbaszndlé éppen foglalkozik — ez olyan megoldas, ami a mintaprogramban szerepl6 nem adatfelismer verérldkkel nem mtikédik. Altalaban az adatforrast ésszekapesolhatjuk az egyes miiveletek DataSource tulajdonsdgival is, de ebben a konkrét esetben nines a mintaprogramban adatforras, Van viszont egy par eseménykezel6, amelyeket a korabbi, adatfelismer6 vezérlékkel készitett programokban nem haszndltam. El6szdr is meg kell jelenitentink az aktualis tekord adatait a vizudlis vezérlékben (amint az a 13.14. 4bran M4that6), Ezt az adathalmaz- komponens OnAfterScrol1 eseményének kezelésével oldhatjuk meg: procedure Form] .cdsAfterSeroll (DataSet: TDataSet) ; begin EditName. ext := cdsNemevAsstring; EditCapital.Text := cdsCapital.asstring: Combotontinent.Text := cdeContinent -AsString; EditArea.Text := cdsArea.AsString; EditPopulation.tText := cdsPopulation.AsString; end; 13.14, abra A NonAware mintaprogram kimenete Browse (Tallézds) tzemmédban. A program minden atkalommal lekéri az adatokat, amikor az aktudlis rekord megualiozik. A vezérlé OnstateChange eseménykezeldje egy Allapotsor vezérlében jelentti meg a tabla Allapotat. Amikor a felhasznal6 elkezd beirni valamit az egyik szerkeszt6mez6be, vagy lenyitja a kombinalt listit, a program szerkesztési tiemmédra dllitja a tablit procedure TForml.EditKeyPress (Sender: Tobject; var Key: Char); begia 4f not (cds.State in [dsBdit, dsfnsert)) then cds Edit; end; Eza tagfiggvény az 6t komponens OnKeyPress eseményéhez kapesolédik, é5 hasonlé a kombinalt lista OnDropDown eseménykezel6jéhez. Amikor a felhaszndl6 kilép valamelyik vizuilis vezérl6b6l, az OnExit eseménykezel6 dtmasolja az adatokat a megfelelé mezobe, ‘mint itt is: Procedure ‘IForm!.EditCapital&xit (Sender: Tobject); begin if (cds.state in [dsEdit, dsInsert]) then cdscapital.asString := EditCapital.Text; end; Amivelet csak akkor megy végbe, ha a tabla szerkesztési tizemmédban van, azaz ha a felhasznalé beirt valamit ebbe a vezérldbe vagy egy masikba. Ez a viselkedés kézel sem. jdedlis, mert tovabbi miveleteket kell végrehajtani akkor is, ha a szerkeszt6mez6ben lev6 széveg nem valtozott meg. Ezek a miiveletek azonban elég gyorsan zajlanak le, ezért nem kell kiléndsebben trédniink veltik. Az els6 szerkeszt6mez6 eserében az atmasols elétt a program ellenérzi a sziveget, és ha a szerkesat6mez6 tires, kivételt valt ki: procedure TForml.editNamelxit (Sender: TObject); begin if (cés.State in [deedit, dstmsert}) then if BditName.Text <> '' then cdsName.AsString := EditName.Text else begin uditName. SetFocus: raise Exception.Create (‘Undefined Country"): end; end; ‘A mez6k értékének ellenérzése helyett kezelhetiitk az adathalmaz BeforePost esemé- nyét is, Ne feledjtik, hogy ebben a programban a7. adatbazisba kiildési milveletet nem egy ere a célra szolgélé gomb kezeli, hanem azonnal megtorénik az adatbazisba kiildés, amint a felhaszndl6 atlép egy masik rekordra vagy besziir egy ti rekordot: procedure TForml.cdsBeforePost (DataSet: DataSet} ; begin if cdsArea.value < 100 then raise Exception.Create (‘Area too small’); end; A kivétel kivaltasat mindkét esetben egy alapértelmezett érték bedllitsdval biztosithatjuk, de ha a mez6nek van alapértelmezett értéke, jobb azt eldre beaillitani, hogy a felhasznal6 lathassa, milyen értéket killd a program az adatbizisba. Ez példaul az adathalmaz, After Insert eseményének kezelésével oldhaté meg, amely azonnal elindul, amint a fel- haszndl6 egy tj rekordot hoz Iétre (de haszndlhattam volna az OnNewecord eseményt is): procedure TFormi.cdsafterInsert (DataSet: TDataset); begin cdsContinent.Value := ‘Asia’; end; Kérelmek killdése az adatbézisba A program felhasznal6i felillete pontosabban is testreszabhat6, ba igy déntiink, hogy nem akarjuk ugyanazt a szerkesziési méveletsorrendet kezelni, mint a szabvényos adatfelismeré vezérlokben, Ez a modszer teljes szabadsagot ad, bar Iehet néhény mellékhatésa (példéul az egyidejG folyamatok kezelésének korlétozott volta, amir6l a 14. fejezethen lesz. s26). Ebben az Gj mintaprogramban az els6 szerkesztémez6t egy kombinilt listara cseréltem, é lecseréltem a tablamiiveletekhez hasznilhat6 dsszes gombot is (amelyek a DENavi gator gombjainak feleltek meg) két egyéni gombra, amelyek egyike az adatbazisbol keri le az adatokat, a masik pedig oda killdi vissza a frissitett adatokat. Ebben a példaban sem haszndltam DataSource komponenst, A megfelel6 gombhox kapcsolt Get Data tagfiiggvény lekéri az els6 kombindlt listéin kiva- lasztott rekordot alkoté mezoket: procedure Form! .getbata; begin cds.Locate (‘Name", ComboName.Text, [loCaseInsensitive]); ConboNane.Text := cdaName.AsString; BaitCapital.Text :- cdsCapitel AsString; CombeContinent.Text := cdsContinent .Asstring; Pditarea.Text := cdsArea.AsString; EditPopulation.Text := cdsPopulation.AsString; end; Amikor a felhaszndlé a gombra kattint, kivalaszt egy elemet a kombinalt listan, vagy Jenyomja az Entse billentytit, amikor a kombinéit lista meg van nyitva, a program mindig ezta tagftiggvényt hivja meg: procedure TForml.ComboNameClick (Sender: TObject); begin GetData; end; procedure Form! .ComboNameKeyPress (Sender: Object; var Key: Char); begin if Key = #13 then GetData; end; Hogy a mintaprogram még simabban mikédj6n, indulaskor a kombindlt lista tartalmazza a tablaban szerepl6 dsszes orsz4g nevét: procedure Form! .FormCreate (Sender: Tobject) ; begin /f a lista felréitése az orszdgnevekkel cds.Open; while not cds.fof do begin ComboName. Items Add (cdsName.AsString) ; cds.Next; end; ands Buzel a médszerrel a kombinalt lista egyfajta rekordkivalaszt6va valiky, amint az a 13.15, 4b- ran lithat6, Ennek a kivalasztésnak késznhetéen a programban nines szikkség mozgis- végrehajt6 gombokra 13.15, dbra A SendToDb mintaprogramban egy kombinalt lista segitségével vdlaszthatjuk ki, melyik rekordot szereinénk megtekinteni. A felhasznél6 meg is valtoztathatja a vezérl6k értékét, és tigy is a Send (Elkildés) gombra kkattinthat. Az, hogy a program melyik kédot hajtja végre, att6l fiigg, hogy adatmodositas vagy Uj adat besztirdsa trtént-e, Ezt a nevet megvizsgilva lehet eldénteni (bar ezt a kédot haszndlva egy rosszul beirt nevet nem Jehet kés6bb kijavitani): procedure TForml.SendData; begin // kivétel kivdltdsa, ha nines megadva semmilyen név Af ComboNane.Text = '' then vaise Exception.Create ("Insert the name"); // annak ellendérzése, hogy a rekord szerepel-e mér a tdbidban if cds.Locate ('Name', ComboName.Text, [loCaseInsensitive]} then begin {/ a megtaldit rekord médositésa eds.Bdit; cdsCapital AsString := BditCapital.Text; cdsContinent .AsString := ComboContinent Text; cdeArea.AsString := EditArea.Text; edsPopulation.Asstriag := EditPopulation.Text; cds.Post; end begin i/ Sj rekord besairdsa cds.InsertRecord ([ComboName. Text, EditCapital.Text, ComboContinent Text, EditArea.Text, Editpopulation.Text]): J/ felvétel a listéra ComboName.Ttems.Add (Comboname. Text) end; Mielétt elktildenénk az adatokat a tabléba, barmilyen érvényesitési ellendrzésnek alévet- hetjik az értékeket. Ebben az esetben nines értelme az adathdzis-komponensek eseménye- it kezelni, mert teljes mértékben mi hatérozzuk meg, mikor menjen végbe a frissitési vagy besztirdsi mdveler. Csoportosités és dsszesités Azt mar léthattuk, hogy a ClientDataSet komponens indexe eltér az, adatok fajlban trténd térolasi sorren Ha meghatérozwunk valamilyen indexet, akkor annak alapjén csoportosithatjuk is az adatokat, A gyakorlatban a csoport olyan egymédst kévet6 rekordok listajaként van meghatérozva (az indexnek megfeleléen), amelyek esetében az indexelt mez6 értéke nem valtozik. Ha péld4ul 4llapot szerinti indexet vettiink fel, akkor az ugyan- olyan Allapoti cimek mindegyike a csoportba fog tartozni Csoportositas A CdsCaics mintaprogramban van egy ClientDataSet komponens, amely adatait a mér ismer6s Count ry (Orszg) adathalmazbél nyeri. A csoportot — egy index meghaté- rozasaval egytitt ~ az indexhez egy csoportositisi szintet megadva kapjuk meg: object ClientDataSeti: TClientDataset i IndexDeis = < item Name = 'ClientDataSetlindex1* Fields = ‘Continent’ F GroupingLevel = 1 end> : IndexName = ‘ClientDataSetIIndexl' Aut, hogy a csoportositas be van kapesolva, nyilvanvaléva tehetjtik a felhaszndl6 szAmara, ha megjelenitjik a csoportositasi szerkezetet a DBGrid vezérlében, amint az a 13.16. abrin lathat6. Ehhez nem kell mast tenniink, mint kezelni a csoportositott mezé (a mintaprog- : ramban ez a Continent ~ Féldrész) OnGet Text eseményét, és csak akkor megieleniteni a sziveget, ha a rekord az els6 a csoportban: procedure TForml.ClientDataset1Cont inentGetText (Sender: TField; var Text: String; DisplayText: Boolean); k begin if gbFirst in ClientDataSet1.GetGroupstate (1) then Text := Sender.asstring else Text i200; 13.16, bra A CasCales mintaprogram at szenilélteti, hogy egy kis lid segitségevel elérhetd, hogy a DBGrid vezérlé vizudlisan jelenttse meg a ClientDataSet komponensben meghatdrozot csoportositast. Gsszesitések meghatérozisa ACLientbataset komponens egy masik szolgiltatisa az Osszesitések lehet6ve tétele. Az dsszesités egy tb rekord alapjén sz4mitott éxték. Ilyen lehet példaul egy oszlop egész tébla vagy egy (az imént tirgyalt csoportositési logikiival meghatérozott) rekordcsoport alapjn szémitott dsszegénck vagy dtlaginak éntéke. Az sszesitéseket a program karban- tarija, azaz a rekordokban t6rtént viltozasok utén azonnal ijrasz4molja. Példaul egy szdmla sszegét automatikusan karban lehet tartani, amikor a felhasznal6 beir egy Gj értéket a seamléra. Az dsszesitések karbantartésa névekményes iiton trténik, azaz ha csak cay érték vdltozik meg, a program nem szimolja iijra minden atkalommal az dsszes enibket, Az ésszesitések frissitésthez a program aclientbataSet komponens altal nytl- vantartolt ideiglenes adatok nyiijtotta el6nydket haszndlja ki. Amikor példaul egy mez meguiltozik, az dsszeg frissitéshez a ClientDataSet kivonja annak régi értéket az Gsszesitett ENékbAI, & az eredményhex hazzdadja az tij éntéket. Jay csak két seamitas elvégzésére van sztikség, még akkor is, ha az Osszesitésben részt vevd csoport t6bb ezer sorbél all. Emiatt av dsszesitések frissitése azonnal végbemegy. ol Sain Az dsszesitések meghatérozasanak két médja van. Hasznalhatjuk a ClientDataset komponens Aggregates tlajdonsagat (amely egy gyGjtemény), vagy meghatérozhatjuk a mez6szerkeszt6vel, mely mez5k szerepeljenek az dsszesitésben. Mindkét esetben meg kell hatdrozni az dsszesitési kifejezést, nevet kell neki adni, és egy indexhez és egy cso- portositasi szinthez kell kapcsolni (kivéve, ha az egész tabla szerepel az Ssszesités}oen). ime a CdsCalc mintaprogram Aggregates gyiijteménye: . object ClientDatasetl: TClientDataset Aggregates = < item Active = True AggregateName = ‘Count! Expression = 'COUNP (NAME) ' Groupinglevel = 1 IndexName < 'ClientDataSet1Index1' Visible = False end item Active = True AggregateName = 'TotalPopulation' Expression = ‘SUM (POPULATION) ' : Visible ~ False E end> E AgaregatesActive = True Figyeljik meg az el6z6 kédrészlet utols6 sordban, hogy az egyes haszndlni kivint Ssszesi- tések bekapcsolasa mellett az Osszesitések tamogatésat is nekink kell bekapcsolnunk, ‘Az Osszesitések kikapcsolisa is fontos, mert ha til sok Ssszesitést haszndlunk, az lelassft- hatja a programot. Amint emlitettem, a masik médszer a Fields Editor haszndlata, amelynek helyi meniijébol valasszuk a New Fieid ((j me26) parancsot, majd az Aggregate (Osszesités) bedllitast (ez ~az Internalcalc beallitassal egyutt — csak a ClientDataSet komponensben talélha- t6 meg). Ime egy dsszesité mezé meghatarozdsa object ClientDataset1: TClientDataset object ClientDataSet1TotalArea: TAgsregateField FieldName = 'Totalarea’ ReadOnly = True visible = True Active = True DisplayFormat = '##¥, #48, ###" Expression = 'SUM(AREA)' GroupingLevel = 1 IndexName = 'ClientDataSet1Indexi‘ end i ‘Az 6sszesii6 mezdket a Fields Editor kiilin csoportban mutatja, amint az a 13.17. abran lathat6, Az dsszesité mez6k haszndlatanak elOnye a sima dsszesitéssel szeemben az, hogy megadhatjuk a megjelenitési formatumot, és a mezét kézvetleniil dsszekapesolhatjuk egy adatfelismer6 vezérlével, a CdsCale mintaprogramban példaul a DBEAit vezérl6vel. Mivel az dsszesités egy csoporthoz kapcsolédik, amint egy misilc csoport egyik rekordjat valasztjuk ki, a kimenetet automatikusan frissfti a program, ha pedig egy adatot valtozta- tunk meg, az dsszeg azonnal az dj értéket mutatja 13.17, abra A GlientDataSet komponens meziszerkeszt6jének alsé részén dsszesitd mezik lathatsk. Ha egyszent dsszesitéseket szeretnénk hasznélni, imunk kell egy rdvid kédot, mint a kéver kez6 példaban (figyeljtik meg, hogy az dsszesitésben a Value tulajdonsig variant): procedure TForml.ButtoniClick(Sender: TObject); begin Labeli.Caption := vaArea: ' + ClientDataSetiTotalaArea.DisplayText + #13 ‘Population : + FormatFloat (‘###,###,84#', ClientDataseti.Aggregates [1].Value) + #13 'Number ; ' + IntToStr (ClientDataSet1.aggregates [0].Value); end; Mester—részlet tipusd felépitések Gyakran kell olyan tablakra hivatkoznunk, amelyekben egy adathoz tobb masik adat kapesolédik. Ez azt jelenti, hogy a mestertabla (fétabla) egy rekordjihoz a masodlagos abla tb részletez6 rekordja is tartozik. Ennek egyik Klasszikus példaja egy szamla és a szmla elemei, a masik az tigyfelek listdja és az egyes tigyfelek Atal feladott megren- delések listija. Ezek az adatbazis-kezel6 programok készitése soran gyakran eldfordulé esetek, és a Delphi kifejezetten tamogatja ezeket a master/detail (mester-részlet) tipust felépité- sekkel, A TDataSet osztélynak van egy DataSource tulajdonsdga, amely a f6 adatfomas beiillitiséra szolgil. Ezt a tulajdonsdgot egy részleteket tartalmaz6 adathalmazban a {6 adathalmnaz.aktudlis rekordjaval valé dsszekapcsolasra hasznaljak, a MasterFields tulajdonsaggal kombinalva Mester—részet tipusti felépités ClientDataSet komponensekkel ‘A MastDet mintaprogram az gyfeleket és a megrendeléseket tartalmaz6 mintaadathal- mazokat hasznilja. Mindegyik adathalmazhoz felvettem egy adatforras-komponenst, és a masodlagos adathalmaz DataSource tulajdons4gat hozzitendeltem az els6 adathal- mazhoz kapcsolt adatforrashoz, Végtil a masodlagos tablit a Master? ields tulajdonsig szeskesaidje segitségével hozzakapcsoltam a mestertébla egyilk mez6jéhez. Mindezt egy adatmodult felhaszndlva hajtottam végre, a korabban, az Adatmodulok adathozz4- ferési komponensckhez cimii széljegyzetben ismertetett modon Alabb a MastDet program altal hasznélt adatmodul teljes kédja lathat6 (a lenyegtelen helymegad6 részek nélkil): object DataModulel: TDataModulel OnCreate = DataModulelcreate object dsCust: TDatasource DataSet = cdsCustomers end object dsdrd: Thatasource DataSet = cdsOrders end object cdsorders: TClientDataset FileName = 'orders.cds’ IndexPieldNames = 'CustNo* MasterFields = 'CustNo" MasterSource = dsCust end object cdsCustomers: TClientbataset FileName = 'customer.cds' end end A 13.18, bran a MastDet program foformja lathaté futdsidében. A mestertéblaval kapeso- latban lév6 adatfelismers vezérloket a form felsé részén helyeztem el, a részleteket tartal- maz6 tablaval ésszekapesolt tablat pedig alul. yen médon minden 6 rekord esetében azonnal lathat6 a hozz4 kapesoldd6, részleteket tartalmaz6 rekordok listdja — jelen esetben a kivalasztott digyfét dltal feladow dsszes megrendelés. Ahdnyszor csak 6j tigyfelet valasz- tunk ki, a f rekord alatti téblaban csak az dltala feladott megrendelések szerepelnek. 13.18, abra A MastDet mintaprogram futds kozben. Az adatbézis-hibak kezelése Az adatbazis-kezel6 programok készitésekor egy masik fontos elem az adathézis-hibak egyéni médon trténé kezelése. Természetesen hagyhatjuk, hogy a Delphi egy kivétel hatasdra felbukkan6 tizenetet jefenitsen meg minden adatbazis-hiba esetén, de ajantott inkabb kijavitani a hibdkat, vagy tobb részletet is megmutatni. Az adatbazisokkal kapcso- latos hibék kezelésére haromféle leherdségiink van: + Aveszélyes adatbazis-kezel6 méveletek kéré try /except blokkot irunk. Ez nem lehetséges, ha a mtivelet az adatfelismerd vezérl6k mikdtetésének hauiséra jon letre. * Kezel6t telepitiink a globilis Applicat ion objektum OnExcept ion eseményénele kezelésére. + Kezeljtik az eseményekhez kapesol6d6 egyedi adathalmaz-eseményeket, amilyen példaul az OnPostError, az OnEditError, az Onbeletenrror és az OnUpd@ateError, Bar a kivételosztalyok tbbsége a Delphiben kiad valamilyen hibatizenetet, az adatbazis- kivételek gyakran hibakédokat, eredeti SQL-hibak6dokat és -iizeneteket és hasonldkat tartalmaznak, A ClientDataSet komponens csak a sajat kivételosztélyanak (EDRC1ient) ad at egy hibak6dot, Ha megmutatom, hogyan kell azt kezelni - lasd lentebb ~, az j6 titmu- tat6 mas esetekhez is. Szemléltetésként készitettem egy olyan adatbizis-kezel6 programot, amely egy jegyzet komponensben jeleniti meg a hiba részleteit (a program automatikusan Aillit el6 hibaket, amikor a felhaszndlé a program gombjaira kattint). Hogy minden hibit kezeljiink, 2 DBError mintaprogram egy, a globélis Applicat ion objektum OnException esemé nyének kezelésére szolgal6 kezeldfiigevényt telepit. Az eseménykezeld alkor napl6z némi informaci6t az adatbazishiba részleteit megjelenit6 jegyzet komponensbe, ha a hiba EDBCLient osztalyd: procedure Tforml.ApplicationError (Sender: TObject; B: Exception); begin if — is EDBClient then begin Menol.Lines.Add{'Brror: ' + (B.Message}); MenolsLines.Add(’ Error Code: ' + IntToStr(EDBClient (E).BrrorCode) ); end else Memol.Lines.Add('Generic Error: ' + (E.Message)); end; Hogyan tovabb? Ebben a fejezetben az adatbazisok Delphi-programokbél térténé elérésére lathattunk példakat. Ismertettem az alapvet6 adatfelismeré vezédldket, valamint az adatbazis-kezelé alkalmaz4sok szabvanyos vezérlokkel t6rténd fejlesztését. Kitértem a TDataSet osztily és a mezGobjektumok bels6 felépitésére, és sz6ltam szmos olyan eseményrél é tulajdonsig- r6l, amelyet az dsszes adathalmaz kézdsen haszndil, és amelyeket haszndl az dsszes adatbé- 2is-kezel6 alkalmazis is, Bér a legtébb mintaprogramban a ClientDataSet komponenst haszndltam a helyi adatok elérésére, ez a komponens gyakran az SQL kiszolgilokon (Aagyfél-kiszolgalé rendszerekben) vagy t4voli alkalmazasokban (haromrétegt felépi rendszerekben) lévé adatok eléréséhez vezeté kapuként is szolgal. Targyaltam a sz4mitott mezOket, a keres6 mezdket, a DBGrid vezérl6 testreszabis4nak médjat és a fejlett megol- dasok egynémelyikét is. Nem merilitem viszont bele az adatbazis és az adatelérés mikéntjébe, ami az adatbézis- kezel6 motor és a hasznalt kiszolgal6 tipusatél fig. A 14. fejezet ere a témara Ssszpon- wosit, és mélységében targyalja az tigylél-kiszolgal6 rendszerekre trtén6 fejlesztést a Borland 4ltal biztositott dbExpress konyvtar segitségével. Foglalkozom az InterBase és az IBX komponenssel is, bemutatva egy valés allsalmazés néhdny elemét. A kovetkez6 fejezetek tovabb ismertetik a Delphiben torténd programkészités adatbazis- oktkal kapesolaios részét, ismertetik az ADO kapesolatokat és komponenseket, a Borland héromrétegt architeknirajat (DataSnap, koriibbi nevén MIDAS), az adatfelismer6 vezérl6k és az egyéni adathalmaz-komponensek fejlesztését és a jelentéskészité médszereket. dbExpress iigyfél-kiszolgalé rendszerek Az el6z6 fejezetben megismerkedtiink a Delphi adatbézis-programovdsi lehet6ségeivel, a legtébb péidaban helyi fajlokat hasznélva (pontosabban a ClientDataSet, illetve a MyBase komponenst alkalmazva), és nem dsszpontositva egyetlen adatbazistechnologia sajétos jellemzdire sem. Fejezettinkben az SQL kiszolgalé alapti adatbizisokat vessztik g6res6 ald, kézéppontban a BDE tgyfél-kiszolgalé fejlesrtési lehetéségeivel, valamint az tj dbExpress technol6giaval. Egyetlen fejezetben persze képtélenség, volna minden részletre kiterjed6en targyalni egy ennyire szertedgaz6 témakort, igy hat inkkabb megpro- balok a Delphi-fejleszt6 szemével némi auekintést adni, emellett bemutatok néhany jal hasznalhato fogast. A példaprogramokban az InterBase-t hasznéljuk, mivel ez a Borland RDBMS (reldciés adatbéizis-kezel6 rendszer), iletve SQL kiszolgalé megtalathaté a Delphi Professional, illetve fefletebb kiadasaiban, réadasul ingyenesen haszndlhat6 nyilt forristi kiszolgalé (nos, e2 az Ssszes viltozatdra azért nem igaz — de err6l majd késobb). Az InterBase bemu- tatdsat a Delphi szemszigéb6l végezatik el, anélkill, hogy killéndsebben elmélyednénic a bels6 szerkezetében. Az itt tanultak sok esetben més SQL kiszolgéldk esetében is ha- szonnal alkalmazhatok, igy akkor is talélunkk itt értékes tudnival6kat, ha nem az InterBase hasendlata mellett déntiink Fejezetiinkben a kévetkez6 témakérdkrd] ejttink szot: * Az iigyfél-kiszolgél6 rendszerek dttekintése + Azadatbazistervezés alapjai * Az InterBase bemutatasa * Kiszolgalo oldali programozas: nézetek, tarolt eljarasok és kiold6k * Helyi adattarolas a ClientDataSet komponenssel * Az InterBase Express (IBX) komponensek Ugyfél-kiszolgalé rendszerek Az e626 fejezetekben bemutatott adatbazis-kezel6 alkalmazasok nativ komponensekkel éték el a helyi gépen fajlokban tarolt adatokat, és a fajl teljes tartalmat a meméridba tolttték. Nos, ez meglehetdsen szélséséges médszer. Ennél kevésbé durva eljards, ha a program rekordonként olvassa be a {4jlt, igy t6bb alkalmazas is elérheti, amennyiben_ az irds dsszehangolisa megoldott, Ha az adatok egy ‘voli kiszolgal6n talélhat6k, a teljes tiblak memdéridba masolasa id6- és sivszélesség-igényes, és gyakran teljességgel felesleges is. Példaként vegytik az EMPLOYEE tablit a Delphivel egyiitt kapott InterBase példa-adatbézisAb6l. Toltsik fel néhany ezer rekorddal és helyezziik el a hal6zat egy fajikiszolgatoként mik6d6 gépén. Ha tudni szeret- nénk, hogy 2 cégnél mekkora a legmagasabb fizetés, megnyithanunk egy dbExpress tabla- komponenst (EmpTable), vagy egy, az Osszes rekordot kivataszté lekérdezést, majd futtat hatjuk az alabbi kédot: 5 : EmpTable. open; i BmpTable. First; : MaxSalery := 0; : while not Bmplable.zof do 5 begin a | if BmpTable.PieldByName ('Salary').AsCurrency > MaxSalary then MaxSalary := EmpTable.FieldByName ('Salary').AsCurrency; EmpTable Next ; end; Ezzel a mOdszerrel az dsszes adatot a fajlkiszolgal6 egy meglehetdsen nagy tablajabol athe- lyezziik a helyi gépre, ami percekig is eltarthat. Ilyenkor jobb megoldas, ha az eredmény kiscdmitasat atengeditik az SQL. kiszolgdlnak, és magunk csak az gy kapott adatokat vessziik at, Mindezt az alabbi SQL utasitissal tehetjk meg: select Max(Selary) from Employee A fenti k6t kédrészlet a GetMax mintaprogrambol val6, amellyel a két meghé- elites iddigényét hasonlithatjuk Gssze. A kis méretit Employee tabla esetében a'table Romponens haszndlata tizszer tébb idét vesz igénybe, mint a lekérdezés, még akkor is, ha az InterBase kiszolgalot az tigyfélgépre welepitetvak, R Ha nagy mennyiségd adattal szeretnénk dolgozni egy kézponti gépen, és el akarjuk keriilni, hogy az. adatok feldolgozsa az igyfélgépeken torténjen, akkor az az egyetlen megoldas, hogy a kézponti gép végzi a feldolgozist, az igyfélnek pedig csak az ered- ményt kiildi vissza.Ez az tigyfél-kiszolgilé programozés alapja. Altalanossigban; a kiszolgdlén egy mar létez6 programot (RDBMS-) fogunk haszndlni, és ehhez frunk egy kapcsol6d6 Ugyfélprogramot. Néhany esetben mind az tigyfél-, mind . akiszolgél6programot nekiink kell megimunk, péld4ul a héromrétegti alkalmazisoknal. ‘A Delphi ilyen — vagyis a MIDAS, illetve iijabban a DataSnap architektirén alapul6 ~ prog- ramokat tamogatd szolgaltatasair6l a 16. fejezetben sz6lok. Egy alkalmazés kiterjesztése (upsizing) — azaz.a helyi féjlok tartalmanak egy SQL kiszolgal6- adatbazismotorba val6 bewltése — Altalaban a teljesitmény navelésének, illetwe a nagyobb adatéllomdnyok kezelésének érdekében torténik. Visszatérve az el6z6 példahoz: tigyfél-ki- szolgél6 kérnyezetben, ha a legnagyobb fizetés meghatarozésihoz lekérdezést hasznalunk egy RDBMS segitségével, az Ugylélgépre visszaktildott eredmény egyetlen szam lesz! Egy eds kiszolgélogépnek, példaul egy tébbprocesszoros Sun SparcStation-nek csak esekély id6re van sziiksége az eredmény meghatérozisdhoz. Vannak ms okok is, amelyek miatt érdemes az iigyfél-kiszolgalé felépitést valasztani: + Segit a nagyobb adatmennyiségek kezelésében, hiszen senkinek sem célja, hogy tb sz4z megabajmnyi adatot téroljon helyi féjlokban. + Lehet6vé teszi tibb felhaszndl6 egyidejti hozzAférését az adatokhoz. Az SQL kiszol- al6k Altaléban az optimista 24roldst haszndljak, melynek soran tobb felhaszndl6 dolgozhat egyszerre ugyanazokon az adatokon, és az esetleges iikdzések kezelése csak késObb t6rténik meg, + Biztositja az adatok épségét, a tranzakcidk verérlését, az adatbiztonsdgot, az elérés vezérlését, a bizionsigi masolatok készitését, és mas hasonlé lebetOségeket, * Segiti a jobb programozhatésagot ~ lehetdvé teszi, hogy bizonyos kédrészleteket (tarolt eljarésokat, kiold6kat, nézewablikat és mas egyebeket) a kiszolgal6n futtas- sunk, csdkkentve a hél6zat és az tigyfélgép terhelését. Mindezek utan térjiink ra azokra a médszerekre, melyek hasznosak az tigyfél-kiszolgal6 programozasban. Ne feledjiik, a £6 cél az, hogy Ggy osszuk meg a munkit az tigyfelek és a kiszolgals kéz6tt, hogy a lehet6 legkisebb halézati forgalmat valtsuk ki, mikézben ada- tokat kiildiink oda és vissza Mindennek alapja a j6 adatbazistervezés — ebbe beleértenddk a j6 tablaszerkezetek, a megfelel6 adatellen6rz6 eljarasok és feltételek, illewve mikédési szabalyok. Az adatok helyességének kikényszeritése a kiszolgalén fontos, az adathazis épségének meg6rzése minden programnél alapkévetelmény. Az tigyfél oldal is tartalmazhat adatellenérzést, ezzel a felhasznal6i feliilet kezelhetSbb lesz, és a megadott adatok ellendrzése is felhasz- nél6bardt médon megy véghe. Nines sok értelme, hogy a felhasznélénak érvénytelen adatokat engedjtink megadni, majd a kiszolgal6t6] hibatizenetet kapjunkk. Ha tudjuk, az els6 lehetséges helyen akadilyozzuk meg az adatok helytelen bevitelét. Az adatbézistervezés elemei Jollehet ez a kényy a Delphi programozésarél, nem pedig az. adatbazisok elméletérdl sz61, mégis fontos, hogy megismerjik a korszerd adathazistervezés néhany alapelemét, Az ok egyszerti: ha az. adatbazisszerkezet hibés vagy indokolatlanul bonyolult, hihetetleniil 6ssze- tett SQL utasitsokat és kiszoigal6 oldali k6dot kell inunk, vagy rengeteg Delphi-progra- mozési munka szakad a nyakunkba, melynek sordn esetleg még a TDataSet osztdly fel- épitésével is meggydlhet a bajunk. Egyedek és reldci6k A Klasszikus relaciés adatbazisok tervezése az egyed-relacié modellen (entity-relation, E-R) alapul, melyben minden, az adatbazishan szerepl6 egyednek egy tabla felel meg, melyck- ben egy-egy mezét kapnak az egyes adatelemek, valamint az. adatelemet egyéb egyedekhez kot6 (egy-egy, vagy egy-tibb tipusti) relici6k. A tobb-t0bb tipust relaci6knak kil6n tablé- ra van saiikségiik. Példaként az egy-egy relacidkra tekintsiink egy tablat, amely egy egyetemi eldadas adata- it tartalmazza, Minden lényeges adatelem (név és Jefras, terem stb.) kap egy mez6t bene, valamint egy tovabbi mutatja a tandrt. A tandr adatait nem érdemes az el6adas adatai mellett térolni — érdemesebb erre egy kiilén tablat haszndlni, hiszen ra mashol is hivat- kozhatak. Az eléad4sok id6beosztasa kiilénb6z6 napokon meghatarozhatatlan szamG 6rabdl all - igy ezt sem helyezhetjiik el az eléadast leiré tablaban. Ezeket az adatokat szintén ktilén tablaba kell tenniink, amely tartalmazza az dsszes id6beosztast, valamint egy mez6t, ami megadja, melyik id6beosztas melyik eldadashoz tartozik. Egy-t6bb relacié esetén az idébeosztis-tab- la tobb rekordja mutat az eldadlastabla egyetlen rekordjara Osszetettebb helyzettel kerilink szembe, ha a didékok 6ravélasztisénak adatait kell térol- nunk, A didkokat nem sorolhatjuk fel kdzvetlentil az eléadasok tablajaban, mivel szamuk nem régzitett, és hasonl6 okokbél a diékok adatai kézétt sem trolhatdk az el6adasok, Egy ilyen t6bb-tbb tipusd relécidban sziikségiink van egy Gjabb tabléra, ami a didkok és az el6adasok kézti kapcsolatokcat t4rolja. Normalizélési szabélyok A Klasszikus adatbizistervezés sarokpontjai a normaliz4lisi szabélyok, melyek szerepe, hogy elejét vegyék az adatok tbbszbrds vitolésinak (nem annyira a jobb tarkihasznalas, mint az ellentmondé adatok jelenlétének elkeriilése miatt). Példanak ok4ért, nem kell minden egyes megrendelésné} megismételntink a vasarlé adatait - ehelyett hivatkozhatunk egy vasirlé egyedre. igy memoriat takaritunk meg, és ha a vasGrlé adatai megvaltoznak (példaul elkoltozik), az Ssszes megrendelése a friss adatokat ttikrézi majd. A médositésok persze emellett mas, a vasarl6ra hivatkoz6 tablékban is automatikusan megjelennek. | ‘A normalizalési szabalyok kodok haszndlatat irj4k el6 @ gyakran ismétld6 értékek helyett. Tegyik fel példaul, hogy van néhany kiilinbéz6 szallitasi lehet6ségtink. Ekkor ahelyet, hogy kilinbéz6 karakterlancokkal jeleniteriénk meg azokat a megrendelések tabl4jaban, alkalmazhatunk szimk6dokat is, melyeket egy killén téblaban feleltethetiink meg a leirs- suknak. Bza szabsily — melynek tGllbuzg6 alkalmazésa nem ajanlott ~ lehetSvé teszi, hogy etlseriijile nagy szmva tabla egyesitését a2 egyes lekérdezésekben, Alkalmazhatunk némi denormali- 2ilast (meghagyva bizonyos révid svAllitasi leirast a megrendelések tabldjaban), de hasznal- hatunk tigyfélprogramot is a helyes leirdsok biztositasdra, ami ismét csak egy formai ibs adatbazisszerkezethez vezet. Ez ut6bbi lehetdség csak akkor hasznalhato sikerrel, ha egyet- len fejleszt6kérnyezetet (példaul a Delphit) haszndlunk az adatbazis elérésére, Az elsddleges kulcsoktél az OID-kig Aseliciés adatbazisok @ rekordokat nem fizikai helyzetik alapjan azonositjak (mint a Pacadoxban vagy mids helyi adatbazisokban), hanem a benntik taldlhato adatok szerint Egy rekord azonositéséhoz azonban tbbnyire nincs sziikség az dsszes benne talélhaté mez6 értékének ismeretére, csak ezek egy részére — az ilyen csoportok alkotjak az elséd- leges kulcsokat. Mivel az els6dleges kulcsban talalhaté mez6k értékeinek azonositaniuk kell a rekordokar, ésszességében minden rekord esetében kilénbéznitik kell. Szdimos adatbéizis-kiszolgdlé bels6 azonosit6kat rendel a rekordokhoz — ext azonban csak a bels6 optimalizdlas miatt teszt, e hozzdrendelésnek vajmi kevés kéze van a reldciés adathdzis logikai felepitéschex. E bels6 azonositok kiilénféleképpen mithidnek mas és mas SQL kiszolgalokban, raaddsul a valtozatok szerint is eltérhetnek, igy nem érde- mes réjuuke hagyatkoznunk. Azeliciés adatbazismodell korai megvaldsitdsaiban a logikai kulcsokra épitettek — ezeke olyan mez6k halmazab6l dlinak, amelyekkel mar biztosan azonositani lehet az egyes egyedeket. Legalabbis elvileg. A cégnevek egyediségére példaul semmi garancia nincs, s6t, még a cimmel egyitt sem biztos, hogy pontosan azonositjak a céget. Réadésul, ha egy cég megvaltoztatja a nevét (ami nem is olyan ritka, lasd a Borland esetén), vagy a cimét, és hivatkozunk ra més tablékban, mindezeket a hivatkozdsokat is at kell funk, gy komoly esélyt adunk a7, 1itk6z6 adatok megjelenésének Részint ez okbél, részint a hatékonys4g névelése miatt (ha karakterlancokat haszndlunk hivatkozdsként, meglehet6sen nagy tirat kell foglalnunk azokban a mésodlagos tablikban, ahol sok a hivatkozés) a logikai kulcsokat a stillyesztbe keildték, és helyettik inkabb a fizikai és a helyettes kulesok haszndlata mellett maradtak: Fizikai kules Egyctlen mez6, amely egy elemet egyértelmien azonosit. Példanak oka- tt, az Egyesiilt Allamokban minden dllampolgar rendelkezik egy tarsadalombiztositsi szémmal, de mAs orsz4gok is alkalmaznak ad6sz4mot vagy mas hatés4gi azonositészA- mot. Ugyanez igaz a cégekre is. Jéllehet ezek az azonositész4mok garantéltan egyedi- ek, orsz4gonként valtozhatnak (gondokat okozva az olyan cégek adatbazisaiban, ame. lyek kalfeldin is értékesitik termékeiked, de egy adott orszdgban is médosulhatnak, példaul egy tj ad6uigyi jogszabvily kapcsén. Sok esetben réadasul ezek az azonosit6- szimok nem igaz4n hatékonyak, hiszen meglehetGsen hossztak (Olaszorszigban pél- dul az dllampolgarok egy 16 karakterb6l ~ bettikb6l és szmokbél — 4ll6 azonositét kapnak). Helyettes kules Rekordot azonosit6 sz4m, iigyfélk6d, sorsz4m stb. A helyettes kuleso- deat (surrogate key) gyakran hasznaljak az adatbazisok terverésében. MindazonAltal sok esetben logikai azonosit6 valik beldliik, és az Ugyfélk6dol mindentitt megjelennek (ami nem igazan j6 megoldis). 4 helpzet kailondsen akkor vélik kinossd, ha a helyettes kulesok maguk is je- lentéssel birnak, és bizonyos szabdlyokat kell Révetnitth, A cégek szamldinak sorszamai példdul egymast kell, hogy kévessék, nem ismétiédhetnek, és nem maradhat ki egyetien sorszam sem, Mindezt a programban kezelni meglehetésen bonyolult feladat, ha tudjuk, hogy kizavélag az adathazis hatdrozhatja meg ezeket az egyedi, egymast kavetd szamo- hat, amikor tij adatokat trunk be. Ugyanakkor azonositanunk kell a rekordot valahogy, mtel6t elhelyeznénk az adatbdzishan, hiszen. valamd alapjén ki is kell majd olvasnunk, E feladat megoldésit a gyakorlathan a 15. fejexet példdi segitik. O1D-k mindeniitt Akiils6 kulcsok és a hivatkozési épség A rekordot azonosit6 kulesok (legyenek barmilyen tipuséak) més tablakban ktilsé kulcs- ként alkalmazhatok — segitségiikkel példéul megoldhat6 a korabban targyalt kiilonbdz6 tipust reléciék abrazolasa. Az SQL kiszolg4ldk ellendrzik a kiils6 hivatkozasokat, igy nem hivatkozhatunk egy masik tabla nem létez6 rekordjara. Az igy kapott hivatkozasi épségre vonatkoz6 megszoritasok érvényesiiinek tj tablak készitésénél. Amellett, hogy nem hivatkozhatunk nem létez6 rekordokra, dltalaban tilos olyan rekordok trlése, melyekre kUlsé hivatkozasok mutatnak. Sét, néhdny SQL kiszolg4l6 még ennél is tovabb megy: ha térliink egy rekordot, nem utasitja el a miiveletet ~ inkbb automatikusan %6r61 minden r4 hivatkoz6 rekordot a tébbi tablaban. Tovabbi megszoritésok Az elsédleges kulcsok egyediségének, tovabbi a hivatkozésok épségének megszoritasin kiviil az adatbazisokban altalaban egyéb szabilyokat is alkalmazhatunk az adatok helyes- ségénck biztositasara. Megkévetelhetjik, hogy bizonyos oszlopok (példéul az adészam vagy a megrendelésszim oszlopa) egyedi értékeket tartalmazzanak, de ugyanezt eléirhat- juk oszlopkombinaciok értékeire is — igy biztosithatjuk példéul, hogy ne lehessen két el6- ads egyidében ugyanabban a teremben. Altalaban az egyszeré szabélyokat a tablak megszoritésaival érvényesitheritik, mig, a bo- nyolultabbak megvalésitéséra térolt eljardsokra, és az ezeket elindité kioldékra (trigger) van szitkség (példaul ha az adatok valtoznak, vagy ha tj adatot visznek be) Nos, a helyes adatbazistervezéshez mindez édeskevés, de az itt leirtak j6 kiindulépontként vagy emlékeztet6ként szolgélhatnak. RUPEES 12 SOL adatleirs (DDI) és adatkezeld nyelvérél (DML) a C filggelékben be- mutatott elektronileus kényv Essential SQL fejezetében olvashatunk. Egyiranyd kurzorok A helyi adatbazisoknal a tablak sorba rendezett (szekvenciilis) fajlok, melyekben a rekor dok sorrendie vagy fizikai sorrend, vagy index szerinti, Ezzel ellentétben az SQL kiszolga- 16k az adatok logikai halmazaival foglalkoznak, aminek semmi kéze a fizikai sorrendhez. Egy relaciésadatbazis-kiszolgal6 a reléciés modelinek megfeleléen kezeli az adatokat, a matematikai halmazelmélet alapjan. Alegfontosabb, hogy a rel4ciés adatbazisokban a tablak rekordjait nem helytik azonositja, hanem egy elsddleges kulcs, amely egy vagy tobb mez6bdl Allhat. Ha megkaptunk egy rekordhalmazt, a kiszolgalé mindegyiknél megadja, hogy melyik az azt kévet6 rekord, En- nek segitségével gyorsan léphettink egy rekordr6l a kovetkez6re, viszont rettent6en lelas- sul a visszalépés az el6z6 rekxordra, Hzért altalaban azt mondjak, hogy az RDBMS-ek egy- ixdny kurzort haszndlnak. Egy ilyen tablat vagy lekérdezést egy DBGr id vezérlGhiz kap- csolnunk gyakorlatilag lehetetlen, mivel igy a mozgis a ricsban elképesztGen lassti volna Egyes adatbézismotorok egy atmeneti tarban tartjak a mar kiolvasott aclatokat, jgy képesek tdmogatni a kétirinyo mozgist kOzéttiik. A Delphiben a tirol6 szerepét jatszhatja a C1i- entDataSet komponens, vagy mas 4tmeneti trol6 adathalmaz. Az itt lejftsz6d6 folya- matokat kés6bb, a dbExpress és az SQLDataset. komponens térgyalasindl részleteseb- ben is bemutatom, ADBGxrid komponens haszndlatanak egyszeri esete, azaz egy teljes tabla béngészése megfelel6 lehet helyi programokban, de keritlendé az iigyfél-kiszolgal6 kérnye- zeiben, Ehelyett csak azokat a rekordokat toltsiik be, amelyekre valoban sztikeségiink van, & a rekordok mexbit is sztiytile meg. Nevek listdjara van seaikségink? Tolistile be az dsszes A betivel kezdédét, majd a B-vel kezdddbket, é jay tovdbb, vagy kérdexzitk meg a fethase- nélét, hogy milyen bettivel kezdSdik a név. A visszafelé haladéssal mindig gondok vannak, de van ennél rosszabb is: ha a tabla utolsé rekordjara akarunk ugrani, akkor rendszerint az Gsszes rekordot le kell télteni! Hasonié a helyzet az adathalmazok RecordCount tulajdonsaganak haszndlatakor is, A rekordok szimdnak meghatérozasaksor az, dsszes rekordot az Ugyfélgépre kell masolni. Bz az oka annak, hogy a D3Grid komponens fiiggdleges gorditSsivja egy tivoli tabla esetén nem mkédik olyan tékéletesen, mint a helyi tablakndl. Ha meg akarjuk tudni a rekordok szamat, akkor inkabb irjunk egy kiilin lekérdezést, ekkor a kiszolgalé (nem pedig az iigyfél) végzi el a méveletet. Példaul ha azt szeretnénk tudni, hogy az EMPLOYEE tablaban hany olyan rekord van, ahol a fizetés nagyobb, mint 50 000, injuk a kovekezdket: select count (*) from Enployee where Salary > 50000 Acount (*} SQL wasitds segitségével konnyedén meghaphatjuk a kivant eredményt. A * jel helyett haszndlhatunk egy adott mezét is: count (First_Name) . Kombindlhatjuk még a distinct vagy azail kulesszoval, ekkor vagy csak a kilonboxt Grtékkel bir6 sorokat, vagy az Osszes nul. értékt6l killonbé26 sorokat sedmoljuk meg. Az interBase ‘Annak ellenére, hogy a piac nem til nagy szeletét uralja, az InterBase meglehetdsen haté- kony RDBMS. A kévetkezékben megismerkediink néhany technikai lehetSségével, anél- kil, ogy mélyebben belebonyolédnank a részletekbe (végiére is konyviink a Delphir6l 261). Sajndlatos médon az eddigiekben nem sok irds jelent meg az InterBase-r6l — ezek emét pedig a programhoz kapcsol6d6 dokumentaci6, valamint néhany idevago webhely tartalma (kiindulépontként érdemes ellatogatnunk a www. borland.com/interbase, yalamint a www. ipphoenix.com cimre) teszi ki. ‘Ay InterBase a kezdetektdl korszenti és rugalmas szerkezette épiil, Eredeti szer2dje, Jim Starkey, feltalalt egy olyan architektirat, amely képes kezelni az egyidejiiséget és a vanzakcidkat anélkil, hogy fizikailag zaroini kellene a tablik egyes részeit ~ ez nagy fegyvertény, tekintve, hogy napjaink szimos s7éles kOrben elterjedt adatbazis-kiszolgdloja nem képes ere. Az InterBase architekttira, melynek neve Multi-Generational Architecture (MGA), képes tbb felhasznal6 egyidejti hozzaférésének kezelésére, akik anélktil modo- sithatjak a rekordokat, hogy befolyasolndk, mit lat a tbbi felhasznal6 az. adatbazisban, Bza megkdzelités egybecseng az ismételt olvasas (Repeatable Read) ranzakci6-elszigete- lési méddal, melyben a felhasznal6 egy tranzakeién beliil mindig ugyanazokat az adatokat létja, fiiggetlentil a tébbiek 4ltal végrehajtott médositasokt6l. Technikailag a kiszolgal6 ezt ‘igy oldja meg, hogy minden nyitott tranzakciGhoz kiilén valtozatot készit az elért rekor- dokbOL Ez a médszer természetesen jelentés memériaigénnyel bir, de segitségével elke- rilhets a téblak fizikai z4roldsa, és a rendszer rugalmasabban viselkedik ésszeomlis ese- tén, Az MGA emellett egy egyértelmii programozasi modell - a Repeatable Read — felé iranyit, melyet mas ismert SQL kiszolgal6k csak a teljesitmény jelentés csdkkenése aran képesek tamogatni, Az InterBase az MGA alkalmazsa mellett szmos el6nyés technikai jellemz6vel rendelkezik: + Alacsony erdforras-kibaszndlis, ami idedliss teszi az Ugyfélgepeken — kozttik a hordozhatkon - val6 hasznalatra. Az InterBase minimalis telepitési mérete joval 10 MB alatt marad, és memériafelhasznéilésa is hihetetleniil takarékes. + Hatékony makédés nagy mennyiségd adaton is. * Eléthetdség kilénb6z6 feliileteken (32 bites Windows, Solaris, Linux stb.), teljes kérd megieleléséggel. 4 kiszolgilé konnyen méretezhet6, egészen kis rendszerek- 16] a7 Oridsokig, észlethets kitlinbségek nélkil « Igen meggy626 el6élet, mivel az InterBase-zel 15 éves thrténete alatt alig néhxiny gond adédott * Az ANSI SQL szabvanyanak megfelel6 nyelv. + Fejlett programozasi lehet6ségek (poziciondlt kiold6k, valaszthat6 tirolt eljarasok, frissithet nézettablak, kivérelek, események, generatorol, és mis egyebek). + gyszerd telepités és fenntartas, kevés feliigyeleti tends, Az IBConsole haszndlata Az InterBase régebbi valtozataiban két elsdleges eszkéz allt rendelkezésiinkre, hogy kézvetleniil ,tirsalogjunk” a programmal: a Server Manager alkalmazas, melyet hasznal- hatrunk mind a helyi, mind a tavoli kiszolgal6k feligyeletére, valamint a Windows Interactive SQL (WISQL). A 6-0s valtozatban ezeknél j6val fejlettebb felhaszndl6 oldali alkalmazast talélunk — ez. az [BConsole, ami teljes énékct Windows-programként (@ Delphiben irtak) lehetvé teszi a helyi vagy t4voli InterBase kiszolgéldk feliigyeletét, bedllitasat, tesztelését és lekérdezését. ‘Az BConsole egy egyszert, de teljes rendszer az InterBase kiszolgalok és adatbazisaike kezelésére. Segitségével belepillanthatunk az. adatbazis szerkezetének részleteibe, modostt- hatjuk vagy pen lekérdezheyjilk az adatokat (ami igen hasznos lehet a programjainkban hasznalt lekérdezések tervezésénél), biztonsigi masolatot készithetiink az adatbazisr6l, és ‘vissza is allithatjuk azt, valamint mas rendszerfeltigyeleti teendoket is elvégezhetiink, ‘Amint a 14.1, abran lathatjuk, az 1BConsole lehetdvé teszi tobb kiszolgalo és adatbazis feltigyeletét, melyek mindegyikét egyetlen szeckezeti faban ttinteti fel. It Altalanos adatokat tudhatunk meg az adatbazisokrdl, valamint hozz4juthatunk egyedeikhez (tablak, tarto- minyok, tarolt eljérdsok, kioldék, és mas egyebek), valamint ezek részletes adataihoz, Készithettink emellett Gj adatbazisokat, megadhatjuk bedllitésaikat, menthetjik a f4jlokat, frissithetjiik a meghatdrozdsokat, megfigyelherjiik, mi trténik adot iddben az adatbézisban, melyik felhasznal6 all vele kapcsolatban stb. Sten dut pon oye Seu te Petes kon er 2 TracioRny Re nestne HB socrasire | ete Yoroomctianne Onbootouat fn ne upbmve —Daphwarert cats Smusbuiip Soup esinan cates senate Scenes 2%} shares ] B pow CornectedUsxs View ote us cunt cometh er esteDoabate Rese an ltedane cabs 3 Wwemer 2 a WaNTECH GO 14.1. dbra Az IBGonsole lehetGvé teszi, hogy tobb kiszolgals InterBase adathaztsatt egyetlen géprét feltigyelitk. Az IBConsole lehet6vé teszi, hogy kiilén ablakokat nyissunk meg az egyes adatok sziméra — ilyen példaul a t4blakat mutaté ablak a 14.2. abran, Itt megszemlélherjike az egyes tablak legfontosabb tulajdonsagait (az oszlopokat, kioldGkat, megszorit4sokat és indexeket), lathatjuk a nyers metaadatolkat (a tibla SQL meghatarozdsat), elérhetjik a jogosultsagokat, megnézhetjik és médositharjuk az adatokat, és tanulmanyozhatjuk atibla filggdségeit. Hasonl6 ablakok allnak rendelkezésre minden egyedhez, amit csak egy adatldzisban meghatérozhatunk. Jevexo teneno) saan JRESTawwe RETIANE vancHe5 si Rae [asiwese) vaRcraae : WasCHER) Testa EPING| Owns) Ty SSoEcoDe vaREKERE DEFAULT HOW (Gaur) NMEA, 2) Nanciae 14.2. dbra Az IBConsole-ban 10bb ablakban jelentthesjal meg az adathazis egyedeinek adatait— jelon esetben egy tabla. Az IBConsole magaban foglalja az eredeti Windows Interactive SQL egy fejlettebb valtoza- tat (asd a 14.3. abrat). Az ablak fels6 részébe SQL utasitésokat ithatunk (sajndlatos médon chhez semmiféle segitséget nem kapunk), majd végrehajthatjuk az SQL lekérdezést. Igy elérjuk a kivant adatokat, valamint az adatbazis elérési tervét (melyb6l a hozaértok kévetkeztethemek a lekérdezés hatékonysigara), és adatokat a kiszolgal6 dltal végzett méveletrdl, Mindez persze csak egy igen sziikszavd leirdsdt adta az InterBase-nek, amely annyiban is kilénleges, hogy ez az egyetlen olyan nem parancssor alapii segédprogram, melyet a Borland a kiszolgaléhoz biztosit. Mindazondltal, az IBConsole nem a legteljesebb segéd- program a sajat kategériajaban. JO néhany ndla hatékonyabb, kils6 gyartok Altal készitett InterBase-{eliigyeleti segédprogram Kétezik ~ jélehet ezek Altalaban nem ilyen stabilak vagy felhaszndlébardtok. Egyesek kozillilk ingyenesen kiprobalhat6 programok, mig masok teljesen ingyenesek, Két emlitend6 példa az InterBase Workbench (wuw .upscene . com) é az IB_WISQL (amely része az InterBase Objects-nek, és ezzel is késziilt, isd a www. ib~ objects.com cimen). jenere caiary > 200000 Te sree 14.3, abra Az IBConsole Interactive SQL ablakdban eldre kiprobalhatjuk a Delphi programjainkban haszndilni Rivdnt lekérdezéscket, Kiszolgélé oldali programozés az InterBase-zel A fejezet elején mar emlitettiik, hogy az tigyfél-kiszolgalé fejlesztés egyik kuleskér- dése— és egyik problémdja -, hogy hogyan osszuk meg a munkit a szmitogépek kéz0tt. Ha kiadunk egy SQL utasitést az tigyfélen, az a kiszolgélohoz kerill, és az végzi a munka nagyobb részét, Erdemes ugyanakkor olyan select: utasftésokat alkalmaznunk, melyek egyszerre nagyobb eredményhalmazt adnak vissza, igy elkeriilhetjiik a halézat bedugulsat. ADDL (Data Definition Language, adatmeghatdroz6 nyelv) és DML (Data Manipulation Language, adatkezel6 nyelv) paranesok mellett a legtébb RDBMS kiszolgalé engedélyezi sajét eljarasok készitését kOzvetleniil a kiszolgdlén, amelyck a szabvanyos SQL parancsokon tal hasznalhatjak a kiszolgalofiigg6 bovitményeket is (ezek dltaléban nem tiltethet6k at mas rendszerte), Ezeknek a7 eljérdsoknak két fajtéja van, a tarolt eljarasok és a kiold6k. Térolt eljérdsok A térolt eljarasok a Delphi egységek globilis fllggvényeihez hasonléak és haszndlatukhoz kézvetleniil az Ugyfél oldalrél kell meghivounk Oket. A térolt eljérasokat az adatok kearban- tartdsara, méiveletek csoportos végrehajtésdra és bonyolult select utasitasok végrehajt4- sira hasznaljuk. A Delphi eljérasolchoz hasonléan a tarolt eljarasoknak is lehet egy vagy tobb tipussal meg- adott paramétere és visszatérési értéke. A visszatérési érték lehet egy eredményhalmaz.is, ha beliil egy select utasitas All. A kovetkezd tarolt eljards az InterBase-hez késziilt. Paraméterként egy datumot var és meghatiirozza, hogy az ekkor belépett dolgoz6k kézétt mekkora a legmagasabb fizetés create procedure MaxSal0fThePay (ofday date} returns (maxsal decimal(8,2)) as begin select max(salary) from employee where hiredate = :ofday inte :maxsal; end Figyeljak meg az into z4radék haszndlatét, amely azt mondja meg a kiszolgélonak, hogy a select eredményét a maxsal visszatérési értékbe kell tenni, Egy térolt eljarés médost- tas4hoz, illetve trléséhez az alter procedure és a drop procedure utasitisokat hasznalhatjuk. Ha megnézziik ezt az eljérast, felmeriilhet a kérdés, hogy mi az elénye, ésszehasonlitva egy hasonl6, az iigyfélr6l inditott lekérdezéssel szemben? A kitlnbség nem az ered- ményben van, hanem a sebességhen. A tirolt eljarast a kiszolgal6 forditja le, amely sokkal gyorsabb, ha mar létrehoztuk és a kiszolgilé egyszer meghatarozta hozz4 az optimalis végrehajtasi médszert, Ezzel ellentétben a lekérdezést minden egyes alkalommal le kell forditani, amikor kéréssel fordulunk a kiszolgalohoz (bar a kiszolgal6 tarolhatja a kérése- ket, hogy ne kelljen kétszer leforditania ugyanazt). Ezért aztén a bonyolult lekérdezéseket lecseréthetjitk tarolt eljérasokra, feltéve, hogy nem valtoznak tal gyakran. A Delphiben az eredményhalmazt visszaad6 tarolt eljarésokat a kévetkezShéz hasonlé SQL kéddal inditharjuk: select * from MaxSalOftheDay ('01/01/2003') Kioldék és generatorok A kiold6k (trigger) tbbé-kevésbé a Delphi eseményekhez hasonléan viselkednek, és automatikusan mikédésbe lépnek, ha egy adott esemény bekévetkezik. A kiold6knak lehet sajat k6djuk, de meghivhatnak tdrolt eljarasokat is: a végrehajtés mindkét esetben teljes egészében a kiszolgél6n torténik. A kiold6k haszndlatanak célja az adatok kovetke- zetességének biztosivésa, az ij adatok ellendrzése a megszoritisok dltal biztositottnal Ssszetettebb modokon, illetve egyes bemencti miveletek mellékhatisaként vegbemend tevékenységek automatizaldsa (ilyen példaul a fizetések médositisainak naplozésa). Akioldékat hérom alapvet6 adatfrissitési mtivelet kapesolhatja be: az insert, az update ésa delete. Amikor létrehozunk egy kiold6t, meg kell adnunk, hogy az emlitett mive- létek el6tt vagy utan hajtédjon végre. i i i a : : | Akioldékra példa, amikor egy generdtort (el6allitén haszndlunk egy tabla egyedi inde- xének létrehozaséra. Sz4mos adattabla hasznal elsddleges kulesként egyedi indexet, az InterBase-nek viszont nines AutoTne mezéje. Miutin tébb tigyfél képtelen egyedi azonosit6k létrehozaséra, ezt rabizhatjuk a kiszolgal6ra. Majdnem minden SQL kiszolgalé piztosit egy meghfvhat6 szimlélét, amivel Gj azonosit6t készithetiink, majd a tébléban fel- hasendlhatjuk azt, Az InterBase ezeket az automatikus sz4mlalokat generdtoroknak hivja, az Oracle sorozatoknak (sequence). ime a megfelel6 InterBase kéd: create generator cust_no.gen; genid (cust_no_gen, 1); ‘Agen_id figgvény allitja el6 az ti egyedi azonosit6t — ehhez At kell adni els6 paraméter- Ként a régi azonos{t6t, masodik paraméterként pedig a ndvelés mértékét, amely ebben azesetben 1 Most mar hozzéiadhatunk kioldékat a téblakhoz, hogy automatikusan kezelhesstik azok eseményeit, A kiold6 hasonlé a Table komponens eseménykezeléjéhez, de SQL-ben kell megimni és a kiszolgél6n fut le, nem pedig az tigyfélen. Nézziink egy példat. create trigger set_cust_no for customers before insert position 0 as begin new.cust_no = gen_id (cust_no_gen, 1); end Aldold6t a customers tablahoz adtuk meg és a program minden Gj rekord felvételénél végrehajtja. A new jel6li azt a rekordot, amit fel szeretnénk venni. A position adja meg a sorszémot abban az esetben, ha tobb kioldé is kapesolédik ugyanahhoz az eseményhez. A legalacsonyabb értékkel rendelkez6 kiold6 fut le el6szii. A kiold6 belsejében hasznalhatunk olyan DML utasitasokat is, amelyek mis tabldkat médo- sitanak, Jol nézziik meg azonban, hogyan adjuk meg a kiold6kat, nehogy végtelen ciklust valtsunk ki, A kiold6kat médositani és tordlni az alter trigger és a drop trigger uta~ sitésokkal lehet, Akkiold6k megadott eseményekre indulnak el automatikusan. Ha az adatbézisban olyan itést kell végezntink, amely kétegelt méveleteket tartalmaz, a kiold6 nagyon lelassit- hatja a2 eljarast. Ha a bemeneti adatok helyességét mar ellenGriztiik, idélegesen kikapcsol- hatjuk a kioldét. Bzeket a kétegelt feldolgozsokat tbbnyire térolt eljérésokban adjuk meg, de dltalaban nem tartalmazhatnak DDL utasitasokat, igy kiold6t sem kapcsolhatunk ki vagy be benaiik, Ebben az esetben adjunk meg egy nézettablat a select * from table Paranccsal, igy létrej6n a tabla egy masolata (masodneve, alias). Ezutan futtassuk a térolt eljérdst a feldolgozassal a tablin és alkalmazzuk a kiold6t a nézett4bléra (melyet szintén, az tigyfélprogram haszna)). A dbExpress kényvtar Napjaink Delphi alkalmazasai a2 SQL kiszolg4l6val rendelkez6 adatbazisokhoz leggyak- rabban a dbExpress kényvtdr ségitségével f6rnek hozz4. Amint a 13. fejezetben is lathattuk, nem ez az egyetlen lehetiség, de bizonyos, hogy et alkalmazzak a legtébben, A dbExpress kényvtar, amely eldsz6r a Kylixban és a Delphi 6-ban jelent meg, lehet6- séget ad ktilénbbz6 kiszolgalok (InterBase, Oracle, DB2, MySQL, Informix és Gjabban a Microsoft SQL Server) elérésére. A 13. fejezetben egy altalanos 6sszehasonlitast lathat- tunk a dbExpress és mas megoldasok kézétt, igy most kihagyjuk a bevezerést, és rogtén a technikai kérdésekre tértink ra. A Microsoft SQL Server meghaji6 tamogatasdinak beépitése a Delphi 7 legna- gyobb lépése volt a dbExpress szempontjabol. Megvalisitasdban a program nem nativ feileten csatlakozik a kiilsd kényotdrhoz, mint mas dbExpress meghajt6k esetében, hanem a Microsoft SOL Server OLEDB szolgdltatdjan keresztil. (Az OLEDB szolgdllta- tékr6l bovebben a 15. fejecetben sedtunk.) Munka egyiranyd kurzorokkal A dbExpress és a BDE, illetve az ADO kézétt abban All a kiilénbség, hogy az el6bbi csak egy egyirinyt kurzoron keresztiil képes végrehajtani az SQL utasivisokat és kiolvasni az eredményeket, Amint a koribbiakban léthattuk, egyiranyd adatbazis-elérés esetén adott rekordr6l csak a k6vetkez6re léphettink, visszafelé nem mozoghatunk (ha csak tijra ki nem olvassuk a teljes eredményt, levonva egy rekordot — ez. azonban olyan lassi mtivelet, hogy a dbExpress nem is engedi meg). Mindennek az az oka, hogy a kényvtar nem térol adatokat helyi atmeneti tirban — egyszertien csak tovabbitja azokat az adatbdzis-kiszolgs- lotél az alkkalmazis felé. Az egyirényt kurzorok haszndlata korlitozésnak tdnhet, és valdban az is ~ amellett, hogy a navigiciéban gondot okoz, még azt is lehetetlenné teszi, hogy az adathalmazokhoz adat riesot kapesoljunk. Mindazoniltal az egyiriny adathalmazok az alabbi esetekben haszno- sak lebetnek: + Egyirinyt adathalmazokat haszndlhanunk jelentések készitésére. Egy nyomtatott je- lentésben ~ de ugyantigy egy HTML lapon vagy XML-ben — rekordrél rekordra ha- ladva kiirjuk 2 kimenetet, és készen vagyunk, Nem kell visszatérntink kordbbi re- kordokhoz, és a felhaszndl6k parancsai sem zavarhatjak meg az egyiriny hala- dist. Az egyirdnyd adathalmazok talin.a legjobb megoldést jelentik a webes és tObbrétegil alkalmazasok szamara. * Az egyirdnyti adathalmazokkal helyi atmeneti tarakat is feltdlthetiink ~ egy ilyet boesat rendelkezéstinkre a ClientDataSet komponens, Innentél kezdve a vizuilis komponenseket 2 memériaban tirolt adatokhoz kapesolhatjuk, és igy elérhetve valik a vizudlis récs is. E magunk készitette 4tmeneti tar adatai kozOtt szabadon mozoghatunk, és tetszés szerinti médosttésokat végezhetiink — soklal jobban rélétwa a folyamatokra, mint a BDE-ben vagy az ADO-ban. Fontos megjegyezni, hogy ilyen esetekben a7 adatbazismotor atmeneti tarol4 Jemonds id6- és meméria-megtakaritdst jelent. A konyvtérnak nem kell kiilén meméridt pocsatania az dtmeneti tat rendelkezésére, é nem kell idét vesztegetnie az adatok térold- ira (Es egytittal masoldsdra). Az utébbi években sz4mos programoz6 valasztotta a BDE térolt frissitései helyett a ClientDataSet komponens haszndlatat, ami nagyobb rugal- massagot ad az adatok kezelésében és a memériaban tarolt informacié frissitésében. Haa ClientDataset komponenst a BDE (vagy az ADO) felett hasznaljuk, kitesszik magunkat anak a veszélynek, hogy két atmenet tar is mikdésbe Iép, ami jelentés ‘mem6riapazarlashoz vezet. AClientDataset alkalmazisinak mésik el6nye, hogy dtmeneti tara vimogatja a szerkesz- iési mtiveleteket, és az dtmeneti tarban lev6 frissitéseket az eredeti adathaziskiszolgalon is écvényesithetjiik a DataSet Provider komponens segitségével. Ez a komponens képes el6élitani a megfelel6 update SQL ulasitésokat ~ riadasul rugalmasabban, mint a BDE (jéllehet e téren az ADO meglehetésen ers), Altaléban a szolgéltat6 alkalmazhat egy adat- halmazt a frissitések samara, de ez kozvetlentil nem valésithat meg a dbExpress adat- halmaz-komponenseivel Rendszerek és adathézisok A dbExpress kényvtar egyik kulesfontossaga tulajdonsdga, hogy mind Windows, mind Tinux rendszereken eléchet6, szemben mas, a Delphiben eléthet6 adatbizismotorokkal (BDE, ADO), melyek csak Windowson haszndlhat6k. Mindazondltal néhiny adatbizis- figg6 komponens, mint az InterBase Express, szintén tobb rendszeren elérhetd. A dbExpress haszndlatandl egy olyan kérnyezetet kapunk, ami figgetlen a hasznalni Kivant SQL adathézis-kiszolgalot6l. A dbExpresshez meghajtkat kapunk a MySQL, az InterBase, az Oracle, az Informix, a Microsoft SQL Server, valamint az IBM DB2 adat- bézis-kiszolgalokhoz. Lehetdségiink van ara is, hogy sajat meghajtokat irjunk a dbExpress archi- tektirahoz. Ennek mikénijét részletesen bemutatja a Borland-kézosség webhelyének dbExpress Draft Specification dokumentuma, melyet a kényv indsanak idején @http://community.borland.com/article/0,1410,22495,00.htm1 cimen taldihattunk meg. J6 eséllyel fellelhetiimk kiils6 gyGrtdk dltal késziteit meghajtSkat ts. Létezth példdul olyan, ingyenesen beszerechet6 meghajt6, ami a dbBxpresst az ODBC-vel hol dssze. A meghajtok teljes listajdt az aldbbt cimen olvashat6 cikkben tekinthetjille meg: http: //community.borland,com/article/0,1410,28371,00.html A meghajt6k valtozatairél és a bedgyazott egységekrél A gyakorlat oldalarél megkézelitve, a dbExpress meghajt6i énallé DDL fajlokban érhersk cl, melyeket programunkkal egytitt kell telepitentink. {gy allt a helyzet a Delphi 6-ban, és za Delphi 7-re sem valtozott. A gond az, hogy a DDI-ek nevei sem valtoztak. Igy, ha egy Delphi 7-tel forditott alkalmazést telepitiink egy gépre, melyen a Delphi 6-ban talalhat6 dbExpress meghajt6k talélhatok, a program elindul, kapesolatot épit ki a kiszolgaléval, majd az adatok kiolvaséséndl hibajelzést ad. Ennek szévege: SQL Error: Ercor mapping failed. (SQL hiba: A hiba megfeleltetése sikertelen,) Nos, ez nem valami tiszta utalas arra, hogy eltéré meghajt6valtozatot haszndlunk.. Nézziink hat utana a dolgoknak ~ vizsgaljuk meg, van-e a meghajt6kban valamiféle valto- zatadat, A Delphi 6-ban ugyanis ilyet nem talélhattunk. Ha programjainkat rugalmasabba szeretnénk tenni, ugyanezt az ellendrzést a k6dban is elvégezhetjtk, kiolvasva a valtozat informaciékat a megfelelé Windows API-k haszndlataval: function GetDriverVersion (strbriverName: string): Integer; var ninfoSize, nDetSize: DWord; pvinfo, pDetail: Pointer; begin if alapértelmezés, ha nem lenne vdltozatadat Result := 67 Wa valtozatadatok kiclvasdsa ninfoSize := GetFileVersionInfoSize (pChar(strDriverName), nDetSize); if ninfoSize > 0 then begin GetMem (pVInfo, ninfoSize) ; try GetFileVersionInfo (pChar(strDriverName), 0, nInfoSize, pVInio); VerQueryValue (pVInfo, ‘\', pDetail, nDetsize); Result := HiWord (TVSFixedFileInfo(pDetail*) .dwFileversionMs) ; finally Freekem (pvinfo) ; end; end; end; Eat a kOdrészletet a késObb térgyakandé DbxMulti mintaprogrambél emeltem at. A prog- ram arra haszndija, hogy kivételt valtson ki, ha a meghajtévaltozat nem megfelel6: if GetDriverversion {‘dbexpint.dll') <> 7 then raise Exception.Create (‘Incompatible version We of the dbixpress driver "dbexpint.dll" found"); Ha athelyezziik a Delphi 6 bin mappajaban talAlt meghajt6t az alkalmazas mappajaba, mir lathatjuk is a hibatizenetet. Kissé médosftanunk kell a k6dot, hogy a meghajt6k é kOnyvtarak frissitett valtozatait is kiszdrje, de ez segithet aban, hogy elkeriiljik azokat a telepitési gondokat, melyeket a dbExpressnek maginak kellett volna megoldani. ‘yan azonban egy mésik lehetéségiinke is: statikusan beszerkeszthetjike 2 megfelel6 dbEx- press meghajt6 kodjat az alkalmazésunkba. Ehhez helyezzik el a megfelelé egységet (abexpint .dcu vagy dbexpora acu) az égyik uses utasitdsban. BOL fori meters nasznatnunk kell a Midastils egysdget is, és be kell szerkesz- teniink a program k6djdba a MIDAS.DIL kényotdrat. Ha nem igy tesztink, a Delphi 7 le- ll egy bels6 hibattzenettel, ami nem ad sok tampontot a hibéra nézve. Figyeljttnk tovdb- bd arra ts, hogy a bedgyazott dbExpress meghajtok nem mitkédnek kielégitéen a nemzet- kizi arakterkészlestel ___ A dbExpress komponensek ‘A dbExpress kényvtarral kapcsolatot létesité VCL komponensek két csoportra oszthatk: az adathalmaz-komponensekre, és néhany segédkomponensre. Hogy elktilonitsék ket ins, adatbazis-elérési komponenscsaladok tagjaitél, nevik elé az SQL eldtagot biggyesz- tették, kihangstilyozva ezzel azt, hogy e komponensek az RDBMS kiszolgaldk clérésére baszndlatosak. F esaladban talélhatunk egy adatb4zis-kapcsolati komponenst, néhany adathalmaz-kompo- nenst (kéziliik egy dltakinos, harom a téblak, lekérdezések és térolt eljérdsok kezelésére srolgal, egy pedig, magaban foghalja a ClientDataSet komponenst), valamint egy rend- szerfigyel6 komponenst. Az SQLConnection komponens AtsgLConnect ion osztély a TCustomConnect ion komponensbél szarmazik, melynek feladata az adatbazis-kapcsolatok kezelése — épptgy mint utédosztélyaiban (Database, ADOConnect ion és IBComnect ion). Mas komponensesalddoktl eltérten a dbExpressben a kapcsolat hasznélata kitelez6. Az adathalmaz-komponensekben nom adhatjuk meg k6zvetleniil, melyik adat- bdzist kivanjuk haszndlni, csak az SQLConnect ion-re hivatkozhatunk. ‘A kapcsolati komponens a drivers. ini ésa connections. ini fajlokban — ezek a dbExpress kizdrdlagos bealltofajljai, megtaldlhatjuk Sket a Common Files\por and Shared\DBExpress mappiban — talalhat6 adatokat haszndlja fel mikédéschez, Advivers. ini felsorolja az elétheté dbExpress meghajtokat — adatbazisonként egyel. E meghajt6k mindegyikehez tartozik egy-egy alapértelmezett paraméterlista — az InterBase- hez tartoz6 részben példaul az alabbiakat lathatjuk: [Interbase] GetDriverFunc=get SQLDr iver INTERBASE LibraryName=dhexpint .dl1 VenderLib=GDs32.DLL

You might also like