Az
adatok szűrésének lehetőségei
Az adattáblák rekordjait nagyon sok esetben kell megadott szempont szerint kiválogatni. Sok esetben nem csupán egy rekordra van szükségünk, hanem bizonyos feltételeknek megfelelő sorokra. Az előző részben megismert keresési eljárásokkal nem nyílik arra lehetőségünk, hogy ilyen módon válogassuk ki azokat, mivel csupán a keresési feltételnek elsőként megfelelő sort kapjuk vissza eredményül.
A szűrés a keresésénél sokkal összetettebb feladat és a Delphi számos lehetőséget biztosít ennek a feladatnak az elvégzésére. A táblák rendelkeznek egy Filter tulajdonsággal, amelybe a szűrési feltételeket adhatjuk meg. Ebben a tulajdonságban a feltételeket az SQL utasításokhoz hasonlóan, konkrét mezőnevek felhasználásával adjuk meg. Itt csupán egyszerűbb feltételeket adhatunk meg. A szűrésnek ennek a módját az alábbi módon használhatjuk:
Tabla_nev.Filter := 'MEZO_NEV = feltetel';
Amennyiben a feltetel string típus, akkor természetesen "" közé kell tennünk.
Több feltételt is összekapcsolhatunk a logikai operátorok (NOT, OR, AND, EXOR) felhasználásával.
A feltételben az alábbi relációkat használhatjuk:
Reláció |
Jelentése |
= |
Egyenlőséget határoz meg |
<> |
Nem egyenlő |
> |
Nagyobb |
< |
Kisebb |
>= |
Nagyobb, vagy egyenlő |
<= |
Kisebb, vagy egyenlő |
Természetesen amennyiben nem ismerjük a pontos kifejezést, akkor használhatunk joker karaktert is, mégpedig a * formájában.
A szöveges típusú mezőkre történő szűrésnél megadhatunk módosító opciókat is, az foPartialCompare és az foCaseInSensitive lehetőségeket. Mindezeket a FilterOptions tulajdonságba kell beállítani. Az előbbi igazra állításával utasítjuk az adatbázis-kezelőt, hogy csak azokat a rekordokat jelenítse meg, amelyeknél a mező értéke pontosan megegyezik a megadott feltétellel. A második opció azt határozza meg, hogy van-e különbség a kis- és a nagybetűk között.
A Filter tulajdonságba nem tudunk bonyolultabb feltételt megadni, mivel nem is ez a tulajdonság célja. Viszont az is igaz, hogy számos esetben szükséges akár olyan kifejezéseket is megadnunk a szűrésben, amelyek például elágazásokat tartalmaznak. Ilyenkor kell használnunk a táblák OnFilterRecord eseményt. Ez az esemény automatikusan meghívásra kerül, amikor a szűrést egy táblára bekapcsolunk. Az OnFilterrecord-ban az Accept változóban kell megadnunk azt a feltételt, amelyeknek megfelelő rekordokat engedhet az adatbázis-kezelő át a szűrőn.
Amikor egy szűrést beállítunk, még nem kerül automatikusan érvényesítésre, azt be kell kapcsolni. Erre a célra szolgál a tábla Filtered tulajdonsága. Amikor a Filtered = True, akkor a szűrés bekapcsolódik és a Filter, vagy az OnFilterRecord tulajdonságban beállított feltétel kerül kiértékelésre. Amennyiben mindkettőbe beírtunk valamilyen feltételt, úgy kettős szűrés következik be, ugyanis mindkettő érvényre jut. Természetesen a szűrésnek csupán a megjelenítésben, illetve a szűrt táblával való további adatkezelésben van szerepe, az adatfelvitel teljesen hagyományos módszerrel történik meg. Amennyiben a felvitt adat nem felel meg a szűrés feltételeinek, úgy automatikusan el is tűnik a képernyőről, de természetesen a táblába be fog kerülni.
Ezek a szűrések akkor lehetnek hasznosak, ha nincsenek nagy tábláink, illetve azok nem tartalmaznak sok rekordot. Ennek az oka az, hogy a minél nagyobb a relációnk, annál hosszabb ideig tart az adatbázis-kezelőnek, hogy a feltételnek megfelelő elemeket kiszűrje. A művelet felgyorsítására használhatjuk az SQL (Structured Query Language, strukturált lekérdezőnyelv) nyelvet, amely az adatok nagyon gyors leválogatását teszi lehetővé és természetesen minden adatbázis-kezelő alkalmazás ismeri. Az SQL nyelv felépítését ennek a cikknek nem célja ismertetni, arra a Codexben megjelent cikksorozat is alapjául szolgálhat, de számos szakleírás megtalálható az interneten.
A Delphit is felkésztették az SQL támogatására, a komponenspalettán, az adatelérési komponensek közül erre szolgál a Query. Ennek használata ugyanúgy történik, mint ahogy azt a Table komponensnél láttuk, annyi különbséggel, hogy az adatokat nem a fizikai táblákból szedi, hanem egy Table-DataSource-ből álló adatelérési komponenspáron keresztül. Ennek megfelelően megtalálhatjuk a DataBaseName és a DataSource tulajdonságokat, amelyek a kapcsolat létrehozásáért felelősek. Amennyiben szeretnénk ennek a lekérdezésnek a kimenetét valamilyen adatmegjelenítési komponensben megjeleníteni, akkor szükség lesz még egy DataSource komponensre is, amely a Query-hez kapcsolódik.
A lekérdezéseket a táblákhoz készthetjük el, a Table és a DataSource elem mellé helyezzünk el egy Query és még egy DataSource komponenst is. Állítsuk be a DataBaseName tulajdonságba azt az aliast, amellyel az adatbázisra hivatkozunk, majd a DataSource tulajdonságban hozzuk létre azzal az adatforrással a kapcsolatot, amely a táblánkhoz tartozik. Ezáltal rendelkezésünkre is áll egy elem, amelynek már csak a tulajdonságait kell beállítani, valamint a lekérdezési parancsokat kell megadni és máris az eredmény a képernyőnkön láthatóvá válik.
Az SQL parancsot az SQL tulajdonságba írhatjuk be, de feltölthetjük futási időben is. A paraméterezett SQL utasításokhoz a paraméterek a Params tulajdonságban határozhatjuk meg a nevükkel és a típusukkal együtt. Futás közben az alábbi módon hozhatunk létre új lekérdezést.
with
Query.SQL do
begin
Clear; //törli a már meglévő
SQL sztringet
Add
('SQL utasítások'); //Ezzel adhatunk új SQL utasítást a már meglévőhöz
ExecSQL; //Végrehajtja az
SQL adatmódodító utasításokat
ParamByName('Paraméter_név'):=érték //Értéket adhatunk
a paraméternek
end;
Amint a fenti kis kódrészletben is látjuk, az SQL utasításokat az Add-dal fűzhetünk hozzá a meglévő sztringhez. Mivel nem felülírásról, hanem hozzáfűzésről van szó, ezért az SQL parancsokat több részben is bevihetjük, ami az áttekinthetőséget és a későbbi hibakeresést is megkönnyíti. Amennyiben adatmódosító utasításokat használunk, akkor az SQL utasításokat az ExecSQL-lel kell lefuttatni. Erre egy egyszerű lekérdezésnél nincs szükség. A paraméterezett lekérdezések akkor lehetnek hasznosak, ha a lekérdezésbe egy beviteli komponens értékét is szeretnénk feldolgozni. Ilyenkor az értékadáshoz a ParamByName-met kell használni. Amit itt ügyelni kell, hogy típuskonverziókat mindig hajtsuk végre, mert különben a Delphi hibaüzenettel leáll.
A Table komponenshez hasonlóan a Query akkor fut le, amikor az Active tulajdonságát igazra (TRUE) állítjuk!
Események az adathalmazokban
Amikor a rekordokkal végzünk műveleteket, akkor a hozzárendelt események automatikusan meghívásra kerülnek. Ilyen esemény az Open, Post és a Delete műveletekhez tartozik. Az alábbi eseményekkel találkozhatunk:
A BeforeOpen és az AfterOpen esemény közvetlenül a tábla megnyitása előtt, illetve után kerül meghívásra.
A BeforePost a tábla adatainak elmentése előtt hajtódik végre. Ide célszerű ellenőrzési rutinokat beépíteni, hogy elkerüljük az adatbázis-motor által kiváltott hibákat. Az AfterPost eseményt akkor hajtja végre a Delphi, amikor az adatok elmentése megtörtént a táblába.
A BeforeDelete és az AfterDelete a rekord törlése előtt, illetve után hajtódik végre. A törlés előtt esetleg még kérhetünk megerősítést a művelet végrehajtására.
A fenti műveletekhez tartozik egy hiba esetén kiváltásra kerülő esemény is, az OnEditError, a OnPostError és az OnDeleteError. A hibát nekünk kell lekezelnünk, amelyhez rendelkezésünkre áll az események Action tulajdonsága. Ezt vagy daFail-re (az alapértelmezett hibaüzenetek jelennek meg), daAbort-ra (nem jelenik meg hibaüzenet), vagy daRetry-re (ismert hiba esetén, amelyet el tudunk hárítani).
Amikor új rekordot viszünk fel, akkor a tábla OnNewRecord eseménye is végrehajtásra kerül. Ebben nagyon kényelmesen beállíthatjuk a mezők kezdeti értékeit.
Ezeknek az eseményeknek a használatával az adatkezelés jelentősen leegyszerűsödik, tehát mindenképpen érdemes élni ezekkel a lehetőségekkel.
Markó Imre -
marko.imre@akribisbt.hu