Issuu on Google+

SQL jegyzet Üdvözlöm az SQL nyelv világában!

2012.04.08. http://ikon.inf.elte.hu/~cserep/ Cserép Anett


Tartalom Üdvözlöm az SQL nyelv világában! ...................................................................................................... - 3 Az SQL története ........................................................................................................................... - 3 Az SQL szerepe és tulajdonságai ................................................................................................... - 4 A nyelv szintaktikai és interaktív használati szabályai .............................................................. - 5 Adattípusok, műveletek ............................................................................................................ - 6 Az adattípusok körében támogatott műveletek ....................................................................... - 7 Összehasonlító műveletek ........................................................................................................ - 7 Predikátumok ............................................................................................................................ - 7 Függvények ............................................................................................................................... - 9 Karakteres függvények: ......................................................................................................... - 10 Dátum függvények: ............................................................................................................... - 11 Numerikus függvények: ......................................................................................................... - 12 Precedencia szabály ................................................................................................................ - 12 Az SQL DDL, vagyis az adatdefiníciós nyelv utasításai ................................................................ - 12 Táblák létrehozása .................................................................................................................. - 13 Táblák módosítása, törlése ..................................................................................................... - 16 Nézettáblák létrehozása, törlése ............................................................................................ - 18 Indexek létrehozása, törlése ................................................................................................... - 19 Táblák létrehozása megszorítással .......................................................................................... - 20 Megszorítások ..................................................................................................................... - 21 Táblaszintű megszorítások utólagos kezelése ................................................................ - 23 Mezőszintű megszorítások utólagos kezelése ................................................................ - 24 Az SQL DML, vagyis az adatmanipulációs nyelv utasításai .......................................................... - 25 A táblákban szereplő mezők feltöltése ................................................................................... - 25 A táblákban szereplő mezők tartalmának módosítása ........................................................... - 26 Táblák sorainak törlése ........................................................................................................... - 28 Az SQL DQL, vagyis az adatlekérdező nyelv utasításai ................................................................ - 30 A SELECT utasítás .................................................................................................................... - 30 -1-


A WHERE feltétel ..................................................................................................................... - 31 Az ORDER BY alparancs ........................................................................................................... - 35 A GROUP BY és a HAVING alparancs ....................................................................................... - 36 Függvények alkalmazás GROUP BY nélkül .............................................................................. - 38 Táblák összekapcsolása a SELECT utasítás segítségével ......................................................... - 40 Lekérdezések egymásba ágyazása .......................................................................................... - 42 Halmazműveletek SQL-ben ..................................................................................................... - 44 1. Unió ................................................................................................................................... - 44 2. Metszet .............................................................................................................................. - 45 3. Különbség .......................................................................................................................... - 45 Az SQL DCL, vagyis az adatelérést vezérlő nyelv utasításai ........................................................ - 46 Az adatbázishoz való hozzáférés szabályozása ....................................................................... - 46 Felhasználási jogok szabályozása ............................................................................................ - 46 Hozzáférési zárak kezelése ...................................................................................................... - 48 Tranzakciók kezelése ............................................................................................................... - 48 Feladatok ..................................................................................................................................... - 49 1. feladatsor: DVD kölcsönző .................................................................................................. - 49 2. feladatsor: Bankrablás ........................................................................................................ - 51 3. feladatsor: Autók ................................................................................................................. - 54 4. feladatsor: Zöldséges .......................................................................................................... - 56 5. feladatsor: Könyvtár ............................................................................................................ - 58 Az SQL utasítások kipróbálásához ajánlott programok ............................................................... - 63 A MySQL környezet ................................................................................................................. - 63 Az Access SQL felületének használata .................................................................................... - 67 -

-2-


Üdvözlöm az SQL nyelv világában! A mai világban, tapasztalataim szerint az informatika terjedésével a számítógépet használóktól egyre több informatikai tudást követelnek meg, nemcsak a szövegszerkesztők és táblázatkezelők ismeretét várják el, hanem az adatbázis-kezelésben való jártasságot is. Sok helyen adatbázissal kapcsolatos kisebb feladatok esetén az adatbázisok tervének és az adatbázist kezelő alkalmazások önálló elkészítését is előírják, azonban ezen feladatok megoldására nem mindig áll rendelkezésre szakember. A feldolgozott tananyag az SQL nyelv témaköreinek bővebb, informális ismertetése, mely a nyelv, szabályszerű, alapos leírásának megértéséhez vezető utat egyengeti. A tananyag nagyobb lélegzetvételű részekre tagolódik, ahol minden egyes rész egy-egy témakört dolgoz fel. A témakörök felölelik rendre az adatdefiníciós, az adatmanipulációs, az adatlekérdező, az adatvezérlő nyelvek utasításait, szabályszerűségeit, valamint további komplett gyakorló feladatsorokat, és az SQL nyelv gyakorlásához szükséges program, illetve programozási környezetek bemutatását. A tananyag feldolgozása során célszerű témakörről témakörre haladni, mivel minden egyes fejezet épít a korábbi szakaszban bemutatott ismeretekre. Jó munkát kívánok mindenkinek! Kérem, ha bárki hibát talál az oldalon, azt mielőbb jelezze. Segítségüket előre is köszönöm!

Az SQL története Az SQL, a Structured Query Language angol elnevezésből származtatott mozaikszó, mely a relációs adatbázis-kezelő rendszerek ma legelterjedtebb, szabványosított adatbázis-kezelő nyelvének rövidített megnevezése. Az angol elnevezés szószerinti magyar fordítása Strukturált Lekérdező Nyelv, ám a nyelv valójában komplett adatbázis-kezelő nyelv, mely tartalmaz adatdefiníciós, adatmanipulációs és az adatfelügyelet körébe tartozó utasításokat is. 1974-75-ben az IBM fejlesztette ki a SEQUEL egységesített lekérdező nyelvet egy kísérleti adatbázishoz, utalva ezzel a nyelv néhány alapvonására. A SEQUEL a Structured English Query Language kifejezésre utal, vagyis azt jelzi, hogy ez egy angol nyelvre épülő strukturált lekérdező nyelv. A parancsok kulcsszavai értelmes, a művelet jelentéséhez közel álló angol szavak. Ezekből a parancsok, mint mondatok hozhatók létre. Mivel nagyon szigorúan kötött e mondatok szerkezete, ezért is nevezhetjük strukturált nyelvnek. A lekérdezés szó azért szerepel a rövidítésben, mert bár a nyelv több mindenre alkalmas, de az igazi kifejező ereje a lekérdezésekben rejlik. Ez a név későbbiekben a ma használatos SQL névre változott, a nyelv felépítése és működési filozófiája változatlan maradt. Az SQL szép lassan egyeduralkodóvá vált a piacon. 1979-ben már több, adatbázis-kezelő (később AB) programokat gyártó szoftveres cég törekedett a lekérdező nyelv szabványosítására (IBM, ORACLE Corp.). Az első szabványosított lekérdező nyelvet 1986-87-ben az Amerikai Nemzeti Szabványügyi Hivatal (ANSI) alkotta meg, mely már relációs adatmodell alapján felépülő

-3-


adatbázisok kezelésére volt képes. A rákövetkező években az ISO (Nemzetközi Szabványügyi Hivatal) is elővette, majd megjelentetett egy ISO SQL szabványt. A gyakorlati élet fejlődését követve többször is módosították a szabványt, először 1989-ben, majd 1992-ben. Az egyes SQL szabványok megkülönböztetésére meg szokták adni az évszámot, így különböztethetünk meg SQL'86, SQL'89, és SQL'92 szabványt, más irodalmak viszont a '89-es szabványt SQL1, a '92-es szabványt pedig, SQL2 néven definiálják. Az egyes SQL szabványokról elmondható, hogy egymással alulról felfelé kompatibilisek, azaz az SQL'86 ismerete felhasználható az SQL'92-ben is, ugyanis az újabb verziók a régi elemeket változatlanul hagyják, a változás csak az újabb elemek befűzéséből ered. Az SQL szabványokra épülő piacon megjelenő adatkezelő nyelvek egyedi elemekkel is rendelkeznek a szabványos elemek mellett, hiszen az SQL szabvány átfogó jellege ellenére több olyan dologra nem tér ki, melyek a megvalósított rendszerekben viszont szükségesek, mint például az adattípusok fajtái és jelölésének kérdése. Így egy relációs adatbázis-kezelő rendszer használatához 3 fontos szintet kell bejárni. Egyrészt ismerni kell a relációs modellt, relációs algebrát, mésrészt ismerni kell az SQL szabványt, valamint az adatbázis-kezelő rendszer SQL alapú kezelő nyelvét. Ezt követve, egy másik SQL alapú rendszerre való átállást igen hatékonyan, és gyorsan meg tudunk oldani.

Az SQL szerepe és tulajdonságai Az SQL egy szabványosított lekérdező nyelv, amit több relációs adatbázis-kezelő ismer, különböző operációs rendszeri környezetben. Ennek óriási jelentősége van az adatbázis alkalmazások fejlesztőinek körében, mert így az alkalmazások a különböző operációs rendszerek és adatbázis-kezelők közötti módosítás nélkül vagy csekély módosítással átvihetők. Tömör, felhasználó közeli nyelv, mely alkalmas hálózatokon adatbázis-kezelő szerver és kliensek közötti kommunikációra. Az SQL nem algoritmikus nyelv, hiszen nem tartalmaz algoritmikus szerkezeteket (elágazás, ciklus, szekvencia), illetve nem tartalmaz normál fájlkezelésre vagy felhasználói képernyőkezelésre vonatkozó utasításokat, kimondottan az adatbázis-kezelés, adatkezelés megvalósítására szolgál. Az SQL-ben az eredményként keresendő adatokat specifikálni kell, de semmilyen előírást nem kell megadni az eredmény előállítására vonatkozóan. Az SQL halmaz orientált nyelv, mely a relációkon dolgozik. A halmaz orientáltság azt jelenti, hogy a feladat nem eljárásszerű megfogalmazását kell megadni, mely a reláció vagy relációk kiválasztott sorain hajtódik végre, tehát nem kell a művelet végrehajtásának lépéseit definiálni. Az SQL nem rekurzív nyelv, vagyis nem tartalmaz önmagát meghívó relációt. Az SQL és a relációs adatmodell kapcsolatáról elmondható, hogy az SQL több különböző szinten keresztül közelíti az elméleti relációs adatmodellt, melyre igaz, hogy bizonyos elemeket nem tartalmaz, ezért az SQL a relációs adatmodellnek csak részleges leképezése. Hogy az SQL már önmagában használható legyen, ne kelljen hozzá más kiegészítő nyelv, ezért az adatkezelési funkciókon belül a legszélesebb igényhalmazt ki kell elégítenie. Az SQL az előbb említett kritériumok miatt négy résznyelvből épül fel: 

SQL DDL (Data Definition Language = Adat Definíciós Nyelv), azaz az SQL adatdefiníciós nyelve, mely lehetővé teszi a felhasználók számára, hogy új adatbázisokat és azok sémáját hozhassák létre, vagyis az adatok logikai sémáját egy speciális nyelven adhassák meg. A használatos sémakezelő utasítások közé tartozik például az adatbázisok, táblák létrehozása, illetve ezek törlése, módosítása. SQL DML (Data Manipulation Language = Adat Manipulációs Nyelv), azaz az SQL adatmanipulációs nyelve, mely lehetővé teszi a felhasználók számára, hogy az adatokat

-4-


módosíthassák. A használatos adatkezelő utasítások például az adatok törlése, módosítása, vagy új adat felvétele. SQL DQL (Data Query Language = Adat Lekérdező Nyelv), azaz az SQL adatlekérdező nyelve, mely segítségével a felhasználók az adatokat lekérdezhetik, kilistázhatják valamilyen szisztéma szerint. Az adatok lekérdezését egyes irodalmakban legtöbbször a DML körében említik, de a relációs modellben betöltött fontosságuk miatt a lekérdező utasítások külön csoportot alkotnak, melyekre a Query elnevezést használjuk. SQL DCL (Data Control Language = Adatelérést Vezérlő Nyelv), azaz az SQL adatelérést vezérlő nyelve. Ezzel szabályozhatjuk, vezérelhetjük a műveletek végrehajtását, hiszen a megvalósított relációs adatbáziskezelő nyelvek hatásának köszönhetően az SQL tartalmaz a relációs adatmodellhez szorosan nem kötődő utasításokat is.

Az SQL utasításokat több különböző módon juttathatjuk el egy relációs adatbázis-kezelő rendszerhez. A legegyszerűbb egy interaktív SQL parancsértelmező használata, ami közvetlenül kapcsolódik a relációs adatbázis-kezelőhöz. Mivel ilyen esetben csak adatkezelő utasításokat adhatunk meg, ezért ez nem alkalmas normál alkalmazói programok készítésére. Ehhez az SQL utasításokat algoritmikus elemekkel kell bővíteni, melyre kétféle lehetőség kínálkozik. Egyrészt magát az SQL-t lehet egy létező algoritmikus nyelvbe beépíteni, beágyazni, másrészt az SQL-t lehet kibővíteni algoritmikus elemekkel. Persze ez utóbbi esetben kapott nyelv már igen messze esik az SQL szabványtól. Az SQL nyelvnek tehát két felhasználási területe van: 

Önálló SQL: Az SQL nyelv önálló alkalmazása esetén csak a nyelv utasításai állnak rendelkezésre. Erre általában akkor kerül sor, ha nincs megfelelő alkalmazás a feladat elvégzésére, illetve a negyedik generációs nyelvekbe építve használják az alkalmazások fejlesztői. Ilyen eszközök például a jelentéskészítő, az űrlapkészítő, vagy a menükészítő. Beágyazott SQL: A beágyazott SQL esetén egy harmadik generációs nyelvbe (C, PL/SQL, Pascal, Fortran, ... stb.) ágyazva alkalmazzuk az SQL nyelv elemeit. Az algoritmikus feladatokat a harmadik generációs nyelv, az adatbázis műveleteket, pedig az SQL végzi el. Jelen esetben a beágyazott SQL alkalmazását nem tárgyaljuk.

Összefoglalóan tehát a következőket mondhatjuk el az SQL-ről:      

Szabványosított lekérdező nyelv; Relációs algebrán alapszik; Szöveges, nem algoritmikus, előíró jellegű utasításokat tartalmaz; Halmazorientált; Nem rekurzív nyelv; Négy utasításcsoportot tartalmaz:  Adatdefiníciós,  Adatmanipulációs,  Adatlekérdező,  Adatvezérlő; Felhasználható önálló vagy beágyazott SQL-ként is.

A nyelv szintaktikai és interaktív használati szabályai Az SQL, hasonlóan más programozási nyelvekhez, utasításokból épül fel. Az egyes utasítások tartalmazhatnak alapszavakat, azonosítókat, kifejezéseket, konstansokat, listákat, és elválasztó jeleket is. A nyelv utasításai meglehetősen összetettek, úgynevezett záradékokból állnak. A záradékok használatának egy része nem kötelező, azonban a használt záradékok sorrendje minden esetben kötött. Az azonosítókat az adatbázis, az adatbázis elemek, az alaptáblák és a nézettáblák, valamint a táblák oszlopainak megnevezésére használják. Az azonosítók mindig betűvel kezdődnek, de a második pozíciótól kezdve tartalmazhatnak betűket, számjegyeket és akár aláhúzás jelet is.

-5-


Egyes számítógépes alkalmazások további karakterek használatát is engedélyezik. Az azonosítók hosszát a különböző számítógépes alkalmazások saját hatáskörükben szabályozzák. A nyelv alapszavai, illetve kulcsszavai azonosítóként nem használhatók. Úgy kell őket megválasztani, hogy azok minden esetben egyediek legyenek, az oszlopnevek táblázaton belül, a táblázat-, nézet-, indexnevek, pedig adatbázison belül. Mivel a nyelv szabad írásmódú, ezért az egyes utasítások tetszés szerint tördelhetők. A záradékokat általában új sorba szokás írni. Az utasítások végét a pontosvessző jelzi. Az utasítások kisbetűs, nagybetűs, és kevert formában is kiadhatók (pl.: a FROM nagybetűkkel ugyanazt jelenti, mint a from, vagy akár a FrOm is). Az utasításokban feltűntetett listákban az egyes elemeket egymástól, vesszővel kell elválasztani, továbbá bizonyos esetekben a listákat kerek zárójelpárba kell helyezni. Az utasítások egy bizonyos részébe szabályok szerint más utasítások is beágyazhatók. Az utasítások alapszavai és egyéb elemei közé elválasztójelként szóközt, vagy soremelést kell tenni. A zárójelek, és vesszők betöltik az elválasztójelek szerepét. Az elemek elválasztása során alkalmazott felesleges szóközök és zárójelpárok nem okoznak hibát.

Adattípusok, műveletek Az SQL nyelvben lehetőség van numerikus, szöveges, dátum jellegű, bináris, logikai, valamint szerkezet nélküli adattípusok használatára.

Adattípus Értelmezés BIT (n) Rögzített hosszúságú bitsorozat BIT VARYING Változó hosszúságú bitsorozat (n) SMALLINT INTEGER Egész LONG DECIMAL (x, [y]) Fixpontos valós (x az összes jegyek, y a tizedes jegyek száma) FLOAT REAL Lebegőpontos DOUBLE PRECISION DATE Dátum TIME Időpont TIMESTAMP Dátum és időpont INTERVAL Időtartam CHAR (n) Rögzített hosszúságú karaktersorozat CHAR VARYING Változó hosszúságú karaktersorozat (n) LOGICAL Logikai típusok (az ilyen adatokat bitsorozatként is tárolhatjuk) BOOLEAN Változó hosszúságú bit- és karakter-sorozat (szerkezet nélküli BLOB adattípus), lehetővé teszi nagy méretű kép, hang, szöveg ... stb. tárolást. 1. Táblázat Adattípusok

Az SQL utasításokban az egyes adattípusoknak megfelelő konstansokat is használhatunk. A szöveg és dátum típusú konstansokat idézőjelek között kell megadni. A dátumformátum

-6-


beállítására két szinten van lehetőség: az adatbázis-kezelő rendszerben, vagy az operációs rendszer szintjén. Ez a beállítás meghatározza az év-, hónap-, nap- adatok megadási sorrendjét, illetve a közöttük alkalmazandó elválasztójeleket. A dátumoknál használatos szabvány elválasztójel a kötőjel, az idő konstansokban az óra, perc, másodperc elhatárolására pedig, a kettőspontot használják. A dátumot és az időt szóközzel választják el egymástól, ha a konstans mindkettőt tartalmazza. Viszont azt fontos észben tartani, hogy a különböző számítógépes megvalósítások a felsoroltaktól eltérő jeleket is tartalmazhatnak az egyes konstansok esetén.

Az adattípusok körében támogatott műveletek A nyelv az alapvető adattípusok körében a következő műveleteket támogatja: 

 

Matematikai műveletek: 1. előjelváltás (+,-) 2. számtani alapműveletek (+,-,*,/) 3. hatványozás (** vagy ^) Karaktersorozattal végezhető műveletek: összefűzés (+,||, &) Bináris és logikai műveletek: 1. Tagadás (NOT) 2. Logikai ÉS (AND) 3. Logikai VAGY (OR) Dátumok, időpontok és időtartamok körében használható műveletek: 1. Számtani alapművelet (+,-,*,/)

Összehasonlító műveletek A keresési feltételekben szerepelhetnek összehasonlító műveletek, melyek egyaránt használhatók dátum-, numerikus- és karakteres típusú adatok esetén is. Ezekre az összehasonlító műveletekre a nyelvben théta operátorok összefoglaló névvel szokás hivatkozni. Az említett operátorok a következők:

= (egyenlő) >= (nagyobb egyenlő) <= (kisebb egyenlő)

> (nagyobb) < (kisebb) <>, !=, ^= (nem egyenlő)

2. Táblázat Összehasonlító műveletek

Az összehasonlító operátorok tagadására a NOT kulcsszó, illetve az összehasonlító műveletek tagadására a ! jel használható. Például a nem egyenlő összehasonlító művelet lehetséges formái: !=, ^=, <>, NOT= lehetnek. A numerikus adattípusok egymással kompatibilisek, tehát bármelyik két típus egymással összehasonlítható. A karaktersorozatok összehasonlítása balról jobbra, a karakterek belső kódja alapján történik. Mivel a kis- és nagybetŰk kódja nem egyezik meg, ezért ezek azonos alakra való konvertálása szükséges a megfelelő függvények segítségével. Ez a megállapítás azonban csak az idézőjelek közé tett kifejezések esetén igaz. Az attribútumnevek, a relációnevek, ... stb. mind-mind függetlenek attól, hogy kis- vagy nagybetűvel írtuk őket.

Predikátumok Az SQL nyelv a fenti összehasonlító műveleteken kívül más műveleteket, úgynevezett predikátumokat is definiál, melyek a következők:

-7-


IS: Olyan értékegyezést vizsgál, melyben azok a sorok kerülnek kiválasztásra, ahol az érték megegyezik az előírttal. Az adatbázis-kezelésből már jól ismert NULL érték vizsgálata nem lehetséges az =, <> operátorokkal, csak az IS predikátummal, vagy az adatbázis-kezelő rendszer egy megfelelő függvényével. Szintaktikája: oszlopnév1 IS NULL oszlopnév2 IS NOT NULL

LIKE: Azokat a sorokat választja ki, ahol a karakteres típusú oszlop vagy kifejezés a megadott mintát tartalmazza. A mintában két speciális helyettesítő karakter adható meg: a % jel tetszőleges hosszúságú karaktert jelöl, vagy az _ aláhúzás karakter, mely egy tetszőleges karaktert jelent. Ezek helyén a vizsgált karaktersorozatban tetszőleges karakterek szerepelhetnek. Szintaktikája: oszlopnév1 LIKE 'minta'

Operátor Értelmezés LIKE 'a%' Kilistáz minden 'a' betűvel kezdődő kifejezést Megadja az összes 'x'-el kezdődő kétbetűs LIKE 'x_' kifejezést LIKE Megad minden 'a' betűt tartalmazó kifejezést '%a%' LIKE Megadja az összes olyan kifejezést, melynek '_a%x' második betűje 'a' és 'x'-re végződik 3. Táblázat Szöveges minta megadása

BETWEEN: Azokat a sorokat választja ki, ahol az oszlop adatértéke, vagy annak behelyettesítésekor a kifejezés értéke a megadott értékhatárok közé esik. (x <= oszlopnév1 <= y) Szintaktikája: oszlopnév1 BETWEEN x AND y

IN: Azok a sorok kerülnek kiválasztásra, ahol az oszlop adatértéke vagy annak behelyettesítéskor a kifejezés értéke megegyezik az IN predikátumot követő értékek egyikével. A halmazban szereplő értékek egy kerek zárójelpárban adhatók meg. Az értékhalmaz egy allekérdezés eredménye is lehet. Szintaktikája: oszlopnév1 IN ('a','b','c') oszlopnév2 IN (SELECT oszlopnév3 FROM táblázatnév1)

ANY, SOME: Olyan összehasonlító művelet teljesülését vizsgálja allekérdezéssel előállított értékhalmazban, ami akkor eredményez igaz értéket, ha az allekérdezés során kiválasztott értékek közül legalább egyre teljesül a kijelölt művelet. Szintaktikája: WHERE oszlopnév1 <= ANY (SELECT oszlopnév2 FROM táblázatnév1)

-8-


ALL: Olyan összehasonlító művelet teljesülését vizsgálja allekérdezéssel előállított értékhalmazban, ami akkor eredményez igaz értéket, ha az allekérdezés során kiválasztott valamennyi értékre teljesül a kijelölt művelet. Szintaktikája: WHERE oszlopnév1 < ALL (SELECT oszlopnév2 FROM táblázatnév1)

EXISTS: Ha az allekérdezés eredménye nem üres, tehát kiválaszt legalább egy sort, akkor igaz értéket ad vissza. Szintaktikája: WHERE EXISTS (SELECT * FROM táblázatnév1)

UNIQUE: Olyan predikátum, mely az allekérdezés eredményeként ismétlődő sorok értékét vizsgálja. Ha nem talál két megegyező sort, akkor igaz értéket, egyébként pedig, hamis értéket ad vissza. Szintaktikája: WHERE UNIQUE (SELECT oszlopnév1 FROM táblázatnév1)

A predikátumokkal bizonyos feltételeket írhatunk elő, melyek teljesülését a rendszer ellenőrzi, és az eredményt egy logikai értékkel jelzi. A predikátumok a kiválasztási, illetve vizsgálati feltételekben, tehát az adatdefiníciós utasításokban (CHECK), valamint az adatkezelő utasításokban (WHERE) és azok záradékaiban (HAVING) használhatók. Ezeket majd később, a SELECT utasítás tárgyalása során ismertetjük.

Függvények Az adatbázis-kezelő rendszerekben számos karaktersorozatot, dátumot, időpontot valamint matematikai és típusátalakító függvényt definiáltak. Ilyen függvények használhatók az SQL nyelvben is. Az SQL nyelv maga is definiál bizonyos függvényeket, ezeket aggregát vagy összesítő függvényeknek nevezzük. Az aggregát függvényeket a SELECT utasítás GROUP BY záradékának tárgyalása során ismertetjük. Azonban először ismerkedjünk meg az SQL nyelvben használatos függvények típusaival és szerepével.

-9-


Karakteres függvények: Függvény ASC (szöveg) CHR (egész) INITCAP (szöveg)

Magyarázat A szöveg első karakterének ASCII kódját adja vissza. A számnak megfelelő ASCII kódú karaktert adja vissza. A szavak kezdőbetűit alakítja nagybetűssé.

Példa ASC ('aerobik') = 65 CHR (65) = 'a' INITCAP ('kis jános') = 'Kis János'

A szöveg1-ben a szöveg2 hányadik előfordulását adja meg a kezdettől számolva. INSTR ('aerobik', (Hányadik és kezdet paraméter megadása 'robi') = 3 elmaradhat) LENGTH LENGTH (szöveg) A szöveg hosszát adja meg. ('aerobik') = 7 LOWER ('JÓGA') LOWER (szöveg) Kisbetűssé alakítja a szöveget. = 'jóga' A szöveget kiegészíti balról a megadott LPAD ('k', 3) = '..k' LPAD (szöveg, karakterekkel az adott hosszig. A karaktereket LPAD ('k', 7, '23') hossz, karakterek) nem kötelező megadni, ekkor szóközt = '232323k' használunk helyettük. LTRIM ('..k') = 'k' A szöveg elejéről levágja a karakterekkel LTRIM (szöveg, LTRIM egyező részt. A karaktereket nem kötelező karakterek) ('gyógytorna', megadni, ekkor szóközt írunk helyette. 'gyógy') = 'torna' A szöveget kiegészíti jobbról a megadott RPAD ('k', 3) = RPAD (szöveg, karakterekkel az adott hosszig. A karaktereket 'k..' hossz, karakter) nem kötelező megadni, ekkor szóközt írunk RPAD ('k', 7, '23') helyette. = 'x232323' A szöveg végéről levágja a karakterekkel RTIM ('k..') = 'k' RTIM (szöveg, megegyező részt. A karaktereket nem RTIM karakter) kötelező megadni, ekkor szóközt írunk ('gyógytorna', helyette. 'anrot' = 'gyógy' SUBSTR ('aerobik', 2, 1) = Kiválasztja a szöveg egy olyan részszövegét, SUBSTR (szöveg, n, 'e' amely annak n sorszámú karakterétől kezdve m) SUBSTR m darab karaktert tartalmaz. ('aerobik', 3) = 'robik' TRANSLATE ('stepaerobik', TRANSLATE A szövegben eloforduló mit karaktereket 'step', 'gyermek') (szöveg, mit, mire) kicseréli a mire karaktereire. = 'gyermekaerobik' UPPER ('jóga') = UPPER (szöveg) A megadott szöveget nagybetűssé alakítja. 'JÓGA' INSTR (szöveg1, szöveg2, kezdet, hányadik)

- 10 -


4. Táblázat Karakteres függvények

Dátum függvények: Függvény Magyarázat ADD_MONTH (dátum, A dátumhoz n hónapot n) ad. A dátumban szereplő LAST_DAY (dátum) hónap utolsó napját adja. MONTH_BETWEEN A két dátum közötti idő (dátum1, dátum2) hónapokban A dátum utáni első NEXT_DAY (dátum, napra eső dátumot nap) adja meg. Dátum kerekítése a ROUND (dátum, megadott formátum formátum) szerint. Az adott dátum TO_CHAR (dátum, konvertálása a formátum) megadott karakteres formátumba. Az adott szöveg TO_DATE (szöveg, dátummá alakítása a formátum) megadott formátum szerint. Megfelelő alakú TO_NUMBER (szöveg) szövegből szám jellegű mezőt képez. Dátum csonkítása a TRUNC (dátum, megadott formátum formátum) szerint.

Példa ADD_MONTH ('15-MAY95', 2) = '15-JUL-95' LAST_DAY ('3-APR-95') = '30-APR-95' MONTH_BETWEEN ('2JAN-93', '3-DEC-94')= '23' NEXT_DAY ('10-APR85','TUESDAY') = '11APR-85'

TO_CHAR (1-JAN-83, 'YY.MM.DD') = '83.01.06.'

TO_DATE ('83.01.06', 'DDMM-YY') = '6-JAN-83'

5. Táblázat Dátum függvények

- 11 -


Numerikus függvények: Függvény ABS (érték) CEIL (érték) FLOOR (érték) MOD (érték, osztó) POWER (érték, kitevo)

Magyarázat Abszolút érték Az értéknél nagyobb vagy egyenlő legkisebb egész. Az értéknél kisebb vagy egyenlő legnagyobb egész

Példa ABS (-5) = 5

Osztási maradék/td>

MOD (7, 3) = 1

Hatványozás

POWER (3, 4) = 81 ROUND (233.523, 1) = 233.5 ROUND (132.234,-2) = 200 SIGN (-3) = -1 SQRT (121) = 11 TRUNC (253.456, 1) = 253.4 TRUNC (153.456,2) = 100

ROUND (érték, pontosság)

Kerekítés a megadott jegyig. Negatív pontosság is megadható.

SIGN (érték) SQRT (érték)

Előjel függvény Négyzetgyök-vonás

TRUNC (érték, pontosság)

Csonkítás a megadott jegyig. Negatív pontosság is megadható.

CEIL (5.15) = 6 FLOOR (2.83) = 2

6. Táblázat Numerikus függvények

Precedencia szabály Az SQL-ben használatos kifejezéseknek van egy kiértékelési sorrendje, vagyis precedencia szabálya, mely szerint az azonos szinten levő műveletek eredménye balról jobbra kerül meghatározásra. Ez a sorrend a következő:   

 

zárójelek, belülről kifelé függvényhívások matematikai, szöveg és dátum műveletek  előjelváltás  hatványozás  multiplikatív műveletek (szorzás, osztás)  összevonási műveletek (összeadás, kivonás) összehasonlító műveletek: =, >, >= , <, <=, <>, !=, ^= logikai műveletek:  NOT  AND  OR

Az SQL DDL, vagyis az adatdefiníciós nyelv utasításai Először ezzel a komponenssel foglalkozunk, hiszen az egyes alkalmazások során is előbb meg kell alkotni a struktúrát, az üres adatszerkezeti elemeket, hogy a későbbiek folyamán fel tudjuk tölteni azokat adatokkal, és fel tudjuk használni a bennük letárolt adatokat. Ez azt jelenti, hogy először létrehozzuk a táblákat. Ilyenkor üres, adatok nélküli táblákat kapunk. Úgy is

- 12 -


mondhatnánk, hogy létrehozzuk a táblák fejlécét, a táblák sorait pedig, csak a későbbi műveletek során alkotjuk meg. Egy tábla szerkezete, sémája, mint ahogy ez az adatbázis-kezelés témaköréből már ismert, a táblához tartozó mezőkkel írható le. Tehát ha megadjuk, hogy milyen mezőkből épül fel a tábla, azzal egyértelműen megadjuk a tábla szerkezetét. Két tábla szerkezete különbözik egymástól, ha található olyan mező, mely az egyikben benne van, a másikban nincs. A mezők megadása a mező nevének és adattípusának kijelölésével történik. Mivel a táblák szerkezete nem azonosítja azt egyértelműen, ezért minden tábla kap egy egyedi nevet az adatbázison belül. Ezzel a névvel egyértelműen lehet azonosítani a táblákat a műveletek során. Tehát a tábla nevének adatbázison belül, a mező nevének pedig, táblán belül kell egyedinek lennie. Egy tábla létrehozásakor meg kell adni a tábla nevét, valamint az őt alkotó mezők nevét és típusát. A táblák soraiban logikailag összetartozó adatokat tárolunk. A relációban szereplő sorok sorrendje tetszőleges, ám nem tartalmazhat két azonos adatokkal rendelkező sort. Mivel a relációs modellnek szerves része az integritási feltétel (más néven index) is, és az integritási feltételek szorosan kötődnek a táblákhoz azok megszűnéséig, ezért a táblák létrehozásakor lehetőséget kell adni az integritási feltételek definiálására is. Egy sor és oszlop metszésében található táblázat elemet mezőnek nevezzük, mely az adatot tartalmazza. A mezőkben oszloponként különböző típusú (numerikus, szöveges stb.) mennyiségek tárolhatók. Az irodalmakban a tábla helyett gyakran a reláció vagy táblázat, a sor helyett a rekord, az oszlop helyett, pedig az attribútum elnevezés szerepel. Összefoglalva tehát az előbbieket, az adatdefiníciós nyelv segítségével hozhatjuk létre az adatbázisokat, a táblákat, a nézettáblákat és az indexeket, illetve ezeket meg is szüntethetjük.

Táblák létrehozása A táblák létrehozására szolgáló SQL utasítás a CREATE TABLE, melynek általános alakja a következő:

CREATE TABLE táblanév (mezőnév1 adattípus (szélesség) [NOT NULL], mezőnév2 adattípus (szélesség) [NOT NULL], ... mezőnévN adattípus (szélesség) [NOT NULL] ); A mezők típusát megadva, a tábla azon oszlopába más típusú adat nem vihető fel, erről az adatbázis-kezelő gondoskodik, illetve szükség esetén figyelmeztet. A NOT NULL a mező definíciójában arra utal, hogy az adat megadása kötelező, azaz nem lehet olyan sor a táblában, ahol az így definiált adat nincs kitöltve. A továbbiakban egy fitnessz terem leegyszerűsített adatbázisának segítségével mutatom be az SQL utasításokat. Az adatbázisban szereplő táblák a következők:

- 13 -


Tanár tábla        

tanár_id: a tanár azonosítója név: a tanár neve tel: a tanár telefonszáma (pl.:06205849212) kor: 0-100 éves korú emberekkel foglalkozunk irsz: a tanár irányítószáma város: az a város, ahol a tanár lakik cím: a tanár címe (utca, házszám) idegennyelvű: értéke I/N lehet attól függően, hogy tart-e idegennyelvűeknek órát vagy sem

Óra tábla  

 

óra_id: az óra azonosítója típus: az óra típusa: mely lehet steptaerobik, gyermekaerobik, jóga, ... stb. felszerelés: milyen eszközt használunk az órán, pl.: zsámoly, polifom, ... stb. időpont: az órák kezdési időpontja, mely csak kerek idopont lehet, pl.: 17 óra, az edzések csak egy órásak jelleg: jellege szerint lehet: férfi, női, koedukált létszám: az órán résztvevők létszáma

Terem tábla  

terem_id: a terem azonosítója maxlétszám: a terem befogadó-képessége, hány ember lehet max bent

Fontos figyelembe venni azt, hogy egy tanár több teremben is tarthat órát, továbbá egy tanár több típusú órát tarthat, sőt több tanár tarthat ugyanolyan típusú órát, és több tanár is tarthat órát ugyanazon teremben csak más időben, vagyis N:M kapcsolatokat fedezhetünk fel. Az adatbáziskezelés során tanultak alapján ilyen esetben kapcsolótáblát kell létrehozni, jelen esetben is vehetünk fel, mely a következő:

- 14 -


Órarend tábla   

- 15 -

tanár_id: a tanár azonosítója óra_id: az óra azonosítója terem_id: a terem azonosítója


A minta adatbázisban található táblák létrehozása a következő utasításokkal történhet:

CREATE TABLE Tanár (tanár_id INT(4) NOT NULL, név CHAR(40) NOT NULL, tel CHAR(15) NOT NULL, kor CHAR(3) NOT NULL, irsz INT(4) NOT NULL, varos CHAR(50) NOT NULL, cím CHAR(50) NOT NULL, idegennyelvű CHAR(1) ); CREATE TABLE Terem (terem_id INT(2) NOT NULL, maxlétszám INT(2) NOT NULL );

CREATE TABLE Óra (óra_id INT(4) NOT NULL, típus CHAR(20) NOT NULL, felszerelés CHAR(20) NOT NULL, időpont INT(2) NOT NULL, jelleg CHAR(10) NOT NULL, létszám INT(2) NOT NULL ); CREATE TABLE Órarend (tanár_id INT(4) NOT NULL, terem_id INT(2) NOT NULL, óra_id INT(4) NOT NULL );

Példánkban többségében megköveteltem, hogy valamennyi mező, kötelezően legyen kitöltve, ezért kellett a NOT NULL predikátumot használni. Ha nem akarom az adott mezőt kötelezően kitöltetni, akkor a NOT NULL predikátumot egyszerűen el kell hagyni, ahogy azt a tanár tábla idegennyelvű mezője esetén is tettem.

Táblák módosítása, törlése A CREATE TABLE utasítással létrehozott táblák definícióját csak korlátozott számban módosíthatjuk, újabb mezőt adhatunk a táblához, vagy egy mező szélességét megnövelhetjük. Egy mező szélességének csökkentésére illetve törlésére nincs közvetlen mód. Ez csak abban ez esetben érhető el, ha a módosításoknak megfelelő üres táblát hozunk létre, amibe a szükséges adatokat átmásoljuk, majd töröljük az eredeti táblát. A tábla újabb mezővel való bővítésére az alábbi parancs szolgál:

ALTER TABLE táblanév ADD mezőnév adattípus (szélesség) NOT NULL; Az új mező a tábla legutolsó oszlopa lesz. A NOT NULL predikátum nem adható meg abban az esetben, ha a tábla már fel van töltve adatokkal, a mezők értéke pedig, a már meglevő sorokban NULL (definiálatlan) lesz. Az SQL nyelv a NULL, vagyis a még nem definiálatlan értékeket megkülönbözteti a nulla numerikus értéktől. Példaként vegyünk fel a tanár táblába egy újabb mezőt, melyben megadjuk a tanárok születési évét:

ALTER TABLE Tanár ADD születésiév INT(4) NOT NULL;

Egy tábla mezőjének szélességét az ALTER TABLE paranccsal lehet megnövelni, mely a következőképp valósítható meg:

- 16 -


ALTER TABLE táblanév MODIFY mezőnév adattípus (új szélesség) [NOT NULL]; Abban ez esetben, ha az adott mező csak NULL értéket tartalmaz, akkor lehetőség van az adattípus módosítására és a szélesség csökkentésére vagy növelésére is. Például a tanárok tábla név mezőjének megnövelésére a következő parancsot adhatjuk ki:

ALTER TABLE Tanár MODIFY név CHAR(50) NOT NULL; Teljes táblák törlésére is lehetőséget ad az SQL nyelv. Ezt az alábbi módon végezhetjük el:

DROP TABLE táblanév; A parancs kiadása után a táblákban tárolt valamennyi adat, és a tábla definíciója is törlődik. A tanárok személyi adatait tartalmazó tábla törlése tehát a következő módon történhet:

DROP TABLE Tanár;

Az SQL nyelv lehetőséget ad a táblákban szereplő oszlopok törlésére is. Az erre szolgáló parancs a következő:

ALTER TABLE táblanév DROP COLUMN oszlopnév; Például töröljük ki a Tanár tábla telefon mezőjét.

ALTER TABLE Tanár DROP COLUMN tel;

- 17 -


Nézettáblák létrehozása, törlése A nézet tábla az adatbázisban fizikailag nem létező relációs műveletek (szelekció, projekció, összekapcsolás, halmazműveletek) segítségével létrehozott tábla, mely a relációkhoz hasonlóan kezelhető. A táblázatok adataiból a SELECT utasítás segítségével nézethez rendelhetjük adatainkat. A nézettáblák alkalmazási lehetőségei:  

Származtatott adattáblák létrehozása, amelyek a törzsadatok módosításakor automatikusan módosulnak (pl. összegzőtáblák). Bizonyos adatok elrejtése egyes felhasználók elől (adatbiztonság vagy egyszerűsítés céljából).

A nézettábla tehát az adatbázisban létező táblán vagy táblákon végrehajtott művelet eredményét tartalmazó olyan új tábla, mely mögött a valóságban nem áll megfelelő reláció, azaz a virtuális tábla nem tartalmaz adatokat. Egy nézettáblát az alábbi paranccsal határozhatunk meg:

CREATE VIEW nézettáblanév [aliasnév, aliasnév,...] AS SELECT...; A CREATE VIEW végrehajtásakor a rendszer csak letárolja a nézettábla definícióját, és majd csak a rá való hivatkozáskor generálja a szükséges adatokat. A lekérdező nyelv utasításait az adatlekérdező nyelv ismertetése során részletezzük. Példánkban hozzuk létre az idegen nyelven is beszélő tanárok névsorát:

CREATE VIEW idegennyelv AS SELECT * FROM Tanár WHERE idegennyelvű='I';

Ha a CREATE VIEW utasítás végére a WITH CHECK OPTION záradékot illesztjük, akkor a rendszer nem engedi meg a nézettábla olyan módosítását, amely nem tesz eleget a leválogatási feltételnek. Az alaptáblázatok változásai a nézet táblában is megjelennek. A nézet tábla örökli az alaptáblázatokban definiált értékhalmazok, a kulcsok egyediségére és az idegen kulcs hivatkozási épségének fenntartására vonatkozó megszorításokat. A nézet tábla oszlopaihoz új név megadása nem kötelező, ekkor az alaptáblázat oszlopainak nevét örökli. Ha egy oszlopnevet megadtunk, akkor a többit is jelölni kell. Új oszlopnevet csak abban az esetben kell megadni, ha  

a SELECT utasítás oszloplistája származtatott oszlopot és/vagy aggregát függvényt tartalmaz két vagy több alaptáblázat azonos nevű oszlopa szerepel a SELECT utasítás oszloplistájában.

A nézettáblák megszűntetése a relációkhoz hasonlóan a DROP parancs segítségével végezhető el. Példaként töröljük az előbb létrehozott nézettáblát:

- 18 -


DROP VIEW nézettáblanév; DROP VIEW idegennyelv;

Ha egy nézettábla tartalmát módosítjuk, akkor a módosítás a megfelelő tárolt táblákon hajtódik végre, ez természetesen megjelenik a nézettáblában is. Alapelv, hogy egy SQL rendszer csak akkor engedi meg a nézettábla módosítását, ha azt a rendszer korrekten és egyértelműen végre tudja hajtani a tárolt táblákon. A nézettáblát nem lehet módosítani, ha a definíciója   

DISTINCT opciót, FROM után egynél több táblanevet, GROUP BY alparancsot tartalmaz.

Ha egy módosítható nézettáblába új rekordot veszünk fel, akkor az alaptáblának a nézettáblában nem szereplő oszlopaiba szükségképpen NULL kerül felvételre.

Indexek létrehozása, törlése A táblákhoz rendelhetünk indexeket, melyek helyes megválasztása esetén a lekérdezések felgyorsíthatók. Az indexek létrehozására a következő utasítás szolgál.

CREATE [UNIQUE] INDEX indexnév ON táblanév (mezőnév1, mezőnév2, ... [ASC/DESC]); Az utasítás a megadott tábla felsorolt oszlopaira, mint indexkulcsra generál le egy indexet. Az utasításban szereplő ASC és DESC alapszavak az indexkulcs értékének nagyság szerinti növekvő illetve csökkenő sorrendjét jelölik. A növekvő sorrend az alapértelmezés szerinti, tehát nem kell megadni az ASC alapszót, ha ilyen rendezettséget szeretnénk. Az index elkészítésekor, ha az indexkulcs egynél több oszlopot is tartalmaz, továbbá az első oszlopbeli értékek azonosak, akkor a második oszlop alapján történik a rendezés. Egy index létrehozásánál az UNIQUE módosító megadásával a rendszer ellenőrzi, hogy a táblázat indexkulcsban szereplő oszlopaiban egyedi alapértékek szerepelnek-e, továbbá minden módosítás és új sor hozzáadása esetén csak egyedi adatértékek bevitelét engedélyezi. Példaként hozzunk létre egy indexet a Tanár tábla telefon nevű mezője alapján:

CREATE UNIQUE INDEX Telefon ON Tanár (tel); A parancsban megadott UNIQUE következtében a tábla minden sorában különböző Tanár_id-nek kell szerepelnie, vagy már meglévő érték bevitele esetén hibát jelez a rendszer, tehát egy-egy index létrehozása után ugyanaz az érték

- 19 -


nem vihető be ismét. Mivel indexeket hozhatunk létre, így azokat törölhetjük is. Az indexek megszűntetése az alábbi paranccsal történhet:

DROP INDEX indexnév ON tábla; Ezen a két parancson kívül nincs több az indexek kezelésére. Az indexeket az adatbázis-kezelő, létrehozásuktól a megszűnésükig automatikusan frissíti, az elvégzett módosítások szerint. Azt azonban érdemes észben tartani, hogy az indexek számának növelésével a végrehajtott módosítások és törlések végrehajtási ideje nő.

Táblák létrehozása megszorítással Az előbbiekben megismerkedtünk a táblák, nézettáblák, indexek létrehozásával, ezek módosításával, illetve törlésével is. Azonban egy táblát létre tudunk hozni megszorítások megadásával is a tábla definiálása során. A megszorításoknak két csoportjával ismerkedünk meg a továbbiakban: 1. Táblaszintű megszorítások:  elsődleges kulcs  idegen kulcs  egyediség  logikai feltétel 2. Mezőkre vonatkozó megszorítások:  alapértelmezett érték  kötelezőség (NOT NULL érték) Először is tekintsük át, hogyan néz ki a CREATE TABLE utasítás megszorítással:

CREATE TABLE táblanév (mezőnév1 adattípus (szélesség) [mező szintű megszorítás1] mezőnév2 adattípus (szélesség) [mező szintű megszorítás2], ... mezőnévN adattípus (szélesség) [mező szintű megszorításN], [táblaszintű megszorítás1], [táblaszintű megszorítás2], ... [táblaszintű megszorításN] ); Az itt említett mezőszintű megszorításokat már ismertettük a Predikátumok című témakör során. Gondolok itt a NULL, vagy a NOT NULL megszorításokra. A táblaszintű megszorításoknak viszont van egy általános szintaxisa: CONSTRAINT megszorítás neve [megszorítás definíciója] A CONSTRAINT záradék segítségével ellenőrzési feltételeket adhatunk meg az adott oszlop esetében. Az ilyen ellenőrzési feltételek egyik legfontosabbika az elsődleges kulcs megadására vonatkozó feltétel.

- 20 -


Megszorítások 1. Elsődleges kulcs Az elsődleges kulcs egyedi azonosítója a sornak, tehát az egész rekordot meghatározza. Az esetek 95%-ában használunk elsődleges kulcsot. Leggyakrabban használt elnevezése: pk_Táblanév. Példákban a Tanár tábla Tanár_id-je, a Terem tábla Terem_id-je, és az Óra tábla Óra_id-je elsődleges kulcsok. Általános szintaxisa a következő: CONSTRAINT megszorítás neve PRIMARY KEY (mezőnév1, mezőnév2) 2. Idegen kulcs Az idegen kulcs olyan mező vagy mezők a táblában, amely egy másik táblában elsődleges kulcsként előforduló értékeket vehet fel. Ezek létrehozása esetén nagyon fontos, hogy figyeljünk a típus kompatibilitásra. A hivatkozott táblából sosem törölhető olyan rekord, amely elsődleges kulcsára hivatkozik a hivatkozó tábla. Az idegen kulcs jelölésére általában nyilat használunk a hivatkozó táblától a hivatkozott tábláig. Az idegen kulcs mindig egy a sokhoz kapcsolatot valósít meg. Szokásos elnevezése: fk_hivatkozó-táblanév_hivatkozott-táblanév. Példákban ez az fk_Órarend_Óra, hiszen az Órarend tábla óra_id nevű mezője idegen kulcs, melyre az Óra tábla óra_id mezője hivatkozik. Hasonló funkciót töltenek be az Órarend tábla terem_id nevű, és tanár_id nevű mezői is. Általános szintaxisa a következő: CONSTRAINT megszorítás neve FOREIGN KEY (mezőnév, mezőnév) REFERENCES [hivatkozott táblanév] (új mezőnév, új mezőnév) 3. Egyediség Az egyediséget akkor használjuk, ha több kulcs is szerepel a táblában. Mivel olyan nincs, hogy másodlagos vagy harmadlagos kulcs, ezért minden további, azaz az elsődleges kulcs után megadott kulcsot egyediség megszorítással adunk meg. Ez logikailag ugyanazt jelenti, mint az elsődleges kulcs, tehát minden értéknek különbözőnek kell lennie az adott mezőben. Azonban annyi eltérés van az elsődleges kulcshoz képest, hogy tartalmazhat NULL értékű mezőt is, de csak egyszer. Amennyiben a megszorítás több mezőre vonatkozik, akkor a mezőkben szereplő értékek együttesének kell egymástól különbözőnek lennie. Szokásos elnevezése: uq_táblanév. Példánkban ilyen lehet például a tanárok neve, vagy akár a telefonszáma. Ha megadjuk az előbbi feltételt a tanárok nevére, akkor azzal megszabjuk, hogy adatbázisunkban nem szerepelhet két ugyanolyan nevű tanár. Hasonlóan elvégezhetjük ezt a telefonszámra is. Általános szintaxisa a következő: CONSTRAINT megszorítás neve UNIQUE (mezőnév1, mezőnév2, ..., mezőnévN) 4. Logikai feltétel Segítségével logikai feltételeket adhatunk meg a tábla mezőire vonatkozólag. A feltételben

- 21 -


különböző logikai operátorokat (pl.: IN, OR, AND), összehasonlító relációkat, és egyéb műveleteket is használhatunk. Szokásos elnevezése: ck_táblanév. Példánkban ilyen megszorítás például a tanárok korára adható meg, hiszen olyan tanárokkal dolgoztatunk, akik betöltötték már a 20. életévüket, de még nem haladták meg az 50. életévet. Általános szintaxisa: CONSTRAINT megszorítás neve CHECK (logikai feltétel) 5. Alapértelmezett érték Ha egy rekordnál nem adjuk meg az adott mező értékét, akkor az, az alapértelmezett értéket fogja felvenni. Szintaxisa: DEFAULT érték. 6. Kötelezőség (nem null érték) A kötelezőség olyan megszorítás, amely nem engedi meg olyan sorok előfordulását, amelyben az adott attribútum érték nincs megadva. Az elsődleges kulcs mezői mind-mind NOT NULL értékűek. Ha egy definícióban van alapértelmezett érték és kötelezőség is, akkor a sorrend a következő: DEFAULT érték NOT NULL.

A példában szereplő táblák létrehozása megszorítással: CREATE TABLE Tanár (tanár_id INT(4) NOT NULL, név CHAR(40) NOT NULL, tel CHAR(15) NOT NULL, kor CHAR(3) NOT NULL, irsz INT(4) NOT NULL, varos CHAR(50) NOT NULL, cím CHAR(50) NOT NULL, idegennyelvű CHAR(1), CONSTRAINT pk_Tanár PRIMARY KEY (tanár_id), CONSTRAINT ck_Tanár CHECK (kor BETWEEN 20 AND 50), CONSTRAINT uq_Tanár UNIQUE (tel)); CREATE TABLE Óra (óra_id INT(4) NOT NULL, típus CHAR(20) NOT NULL, felszerelés CHAR(20) NOT NULL, időpont INT(2) NOT NULL, jelleg CHAR(10) NOT NULL, létszám INT(2) NOT NULL, CONSTRAINT pk_Óra PRIMARY KEY (óra_id), CONSTRAINT ck_Óra CHECK (időpont BETWEEN 7 AND 20), CONSTRAINT ck_Óra CHECK (létszám BETWEEN 8 AND 30)); CREATE TABLE Terem

- 22 -


(terem_id INT(2) NOT NULL, maxlétszám INT(2) NOT NULL CONSTRAINT pk_Terem PRIMARY KEY (terem_id), CONSTRAINT ck_Terem CHECK (maxlétszám BETWEEN 8 AND 30)); CREATE TABLE Órarend (tanár_id INT(4) NOT NULL, terem_id INT(2) NOT NULL, óra_id CHAR(4) NOT NULL, CONSTRAINT fk_Órarend_Tanár FOREIGN KEY (tanár_id) REFERENCES Tanár (Tanár_id), CONSTRAINT fk_Órarend_Terem FOREIGN KEY (terem_id) REFERENCES Óra (terem_id), CONSTRAINT fk_Órarend_Óra FOREIGN KEY (óra_id) REFERENCES Óra (Óra_id));

Táblaszintű megszorítások utólagos kezelése Az előbbiekben már láttuk, hogy egy elkészült táblát utólag is módosíthatunk. Egy táblához adhatunk megszorításokat, de el is dobhatunk már elkészített megszorításokat. A megszorítások hozzáadása esetén az utasítás szintaxisa:

ALTER TABLE táblanév ADD CONSTRAINT megszorítás neve; Például, ha azt a megszorítást kellene létrehozni a Tanár táblához, hogy nem lehet két ugyanolyan nevű tanár, akkor a következőket írnánk:

ALTER TABLE Tanár ADD CONSTRAINT uq_Tanár UNIQUE (név);

- 23 -


Mezőszintű megszorítások utólagos kezelése A mezőszintű megszorítások utólagos kezelésére szolgáló SQL utasítás a MODIFY. Használatának általános szintaxisa:

ALTER TALBE táblanév MODIFY mezőnév adattípus [mező szintű megszorítás]; Például, ha azt szeretnénk beállítani, hogy a Tanár tábla kor nevű mezőjének alapértelmezett értéke legyen a 20, akkor a következőt írnánk:

ALTER TABLE Tanár MODIFY kor INTEGER DEFAULT 20;

- 24 -


Az SQL DML, vagyis az adatmanipulációs nyelv utasításai Ha már létezik egy adatbázis, olyan táblákkal, melyek létrehozásukkor még üresek, akkor elkezdhetjük azokat feltölteni adatokkal. Az ilyen műveletek megvalósítására szolgál az SQL adatmanipulációs nyelve, melynek három fontos alaptevékenysége van:   

az adatok bevitele, vagyis a mezők feltöltése, adatok törlése adatok módosítása.

A táblákban szereplő mezők feltöltése A táblák feltöltésére az INSERT SQL utasítás szolgál, melynek általános alakja a következő:

INSERT INTO táblanév (mezőnév1, mezőnév2, ..., mezőnévN) VALUES (érték1, érték2, ..., értékN); Egy utasítással csak egy sor adható az adott táblához. A mezőnevek megadása csak abban az esetben kötelező, ha nem rendelünk minden mezőhöz értéket, vagy a mezők értékét nem a definiálás sorrendjében adjuk meg. A NOT NULL predikátummal definiált mezők megadása kötelező az INSERT parancs kiadása során, ellenkező esetben hibaüzenetet kapunk. A felsorolt mezők nevének, és a VALUES után megadott értékek sorrendjének és típusának meg kell felelnie egymásnak. A definiálatlan értékekre beállítható a NULL érték is, mely numerikus értékekre vizsgálva sem azonos a nullával. Példaként adjuk egy új sort a tanár táblához:

INSERT INTO Tanár (tanár_id, név, tel, kor, irsz, város, cím) VALUES (1, 'Kiss János', '06203152469', '25', 1118, 'Budapest', 'Rákóczi utca 15.');

A tanárok tábla idegennyelvű mezőjének értékét nem adtuk meg, hiszen nem kötelezően kitöltendő mező, így annak értéke NULL lesz. A tábla létrehozásakor NOT NULL predikátummal ellátott mezők kitöltése kötelező minden újabb sor megadásánál, ellenkező esetben hibaüzenetet kapunk. Az előbbi adatokat bevihetjük az alábbi formában is, mindössze arra kell figyelni, hogy a megadottak sorrendje megegyezzen a tábla mezőinek sorrendjével: INSERT INTO Tanár VALUES (1, 'Kiss János', '06203152469', '25', 1118, 'Budapest', 'Rákóczi utca 15.');

- 25 -


Az INSERT lehetőséget biztosít arra is, hogy a táblát egy másik táblából átvett értékekkel töltsük fel. Ebben az esetben az értékek megadása helyén egy SELECT, vagyis egy lekérdező utasítás áll. A lekérdezés eredményei kerülnek a táblába, akár több sor is. Ebben az esetben is igaz, hogy a lekérdezésben szereplő eredménytábla mezői sorrendjének, és típusának meg kell felelnie a feltöltendő tábla definíciójával. Az utasítás formája a következő:

INSERT INTO táblanév (mezőnév1, mezőnév2, ..., mezőnévN) SELECT lekérdező utasítás; A lekérdező utasítások formájával a következő témakörben foglalkozunk, de már itt is bemutatunk egy példát. Töltsük fel a tanárok adatai közül a budapesti lakosokat egy külön táblába:

INSERT INTO Budapesti SELECT * FROM Tanár WHERE Tanár.város = 'Budapest';

A feladatban szereplő budapesti táblát természetesen előbb létre kell hozni a tanárok táblával megegyező szerkezettel, azért hogy a fenti parancs működhessen. A tanárok tábla tartalma nem változik.

A táblákban szereplő mezők tartalmának módosítása A táblákban szereplő mezők tartalmának módosítására szolgáló SQL utasítás az UPDATE. Általános alakja a következő:

UPDATE táblanév SET mezőnév1 = érték1, mezőnév2 = érték2, ..., mezőnévN = értékN WHERE feltétel; Az UPDATE utasítás segítségével az adott tábla több sorát is módosíthatjuk egy időben. A SET alapszó után adhatjuk meg a módosítandó mezőket és a hozzájuk tartozó új értékeket. Az utasításban szereplő WHERE feltétel csak a tábla azon sorain dolgozik, melyekre a feltétel értéke igaz. Ha a szelekciós feltétel elmarad, akkor a tábla valamennyi sorára vonatkozik az UPDATE parancs. A feltételek alakjára részletesen a lekérdező nyelv ismertetése során térünk ki, de a szokásos összehasonlító operátorok itt is használhatók. Módosítsuk például az óra tábla felszerelés mezőjét zsámolyra, ha az óra jellege női, továbbá az óra típusa zsírégető óra.

- 26 -


UPDATE Óra SET felszerelés = 'zsámoly' WHERE típus = 'zsírégető óra' AND jelleg = 'női';

Vagy módosítsuk a terem táblázatban szereplő 5. azonosítójú terem maxlétszámát 25-re:

UPDATE Terem SET maxlétszám = 25 WHERE terem_id = 5;

A SET parancsban szereplő egyenlőség jobb oldalán állhat egy a tábla mezőiből alkotott kifejezés is. Ilyenkor az aktuális sor tartalma alapján értékelődik ki a kifejezés. Az értékek módosítása esetén a feltételben egy SELECT utasítás is szerepelhet, melynek segítségével egy másik táblából vett értékeket használhatunk. Ezen utasítás általános alakja a következő:

UPDATE táblanév SET mezőnév1 = (lekérdező utasítás) WHERE feltétel;

- 27 -


Táblák sorainak törlése A felvitt rekordok törlésére a DELETE utasítás szolgál. A törlés egyértelműen elvégezhető, ha megadjuk, hogy melyik táblából, és melyik rekordo(ka)t töröljük ki. A rekordok kiválasztása egy szelekciós feltétel segítségével történhet. A szelekciós feltétel a rekordokon értelmezett logikai kifejezés, mely igaz vagy hamis értéket vehet fel. Ha a kifejezés értéke igaz, akkor a rekord törlődik a táblából, ellenkező esetben nem. Az utasítás általános alakja:

DELETE FROM táblanév WHERE feltétel; Töröljük például a terem táblából a 4-es azonosítójú termet:

DELETE FROM Terem WHERE terem_id = 4;

A kérdés jelen esetben csak az, hogy törölhetünk-e egy rekordot a táblából az adatbázis konzisztenciájának (ellentmondás-mentesség) elvesztése nélkül. Ha az Órarend táblában szerepelt a törölt terem azonosítója, akkor ezek inkonzisztenssé teszik az adatbázist. Ebben az esetben helyesebb az alábbi törlő parancsokat kiadni, ha semmi szín alatt sem szeretnénk elveszteni az adatbázisunk konzisztenciáját: DELETE FROM Terem WHERE terem_id = 4; DELETE FROM Órarend WHERE terem_id = 4; Ha a szelekciós, vagyis a WHERE feltétel nem szerepel az utasítás soraiban, akkor alapértelmezés szerint törlődik a tábla valamennyi rekordja. A tábla definíciója természetesen megmarad, csak a benne szereplő adatok törlődnek, tehát egy üresen maradt táblázatot kapunk végeredményként. Tételezzük fel, hogy a tanárok közül a nyugdíjba menteket egy nyugdíj táblában, és annak név mezőjében tároljuk, továbbá kössük ki azt is, hogy nem létezik két ugyanolyan nevű tanár az adatbázisban. Ezek alapján töröljük a Tanár táblából őket:

- 28 -


DELETE FROM Tanár WHERE Tanár.név IN (SELECT név FROM nyugdíj);

- 29 -


Az SQL DQL, vagyis az adatlekérdező nyelv utasításai Az SQL utasítások harmadik csoportja alkalmas a lekérdezések elvégzésére. A lekérdezések a SELECT utasításhoz kötődnek, bár ennek az utasításnak számos variációja van. Tehát az adatlekérdező nyelv egyetlen utasításból áll, amely számos alparancsot tartalmazhat, továbbá a lekérdező utasítások egymásba ágyazhatók. A SELECT utasítás általános alakjának bemutatása helyett áttekintjük az egyes tipikus lekérdezési utasításokat az egyszerűektől a komplikáltakig. A szelekciót és a SELECT utasítás műveletét nem szabad összekeverni, mivel ezek csak névben hasonlók, de egymásnak egyáltalán nem felelnek meg.

A SELECT utasítás Először is tekintsük át az egy táblára vonatkozó lekérdezéseket, ahol a projekció műveletére van szükségünk. A projekció során egy tábla oszlopai közül csak bizonyosakat őrzünk meg az eredmény táblában. A projekció műveletét a következő SQL utasítással valósíthatjuk meg:

SELECT oszlopnév1, oszlopnév2, ..., oszlopnévN FROM táblanév; A Tanár tábla tanár_id és név attribútumainak lekérdezése a következőképp történhet, ahol a megadott lekérdezés felsorolt attribútumai jelennek meg soronként az utasítás hatására:

SELECT tanár_id, név FROM Tanár;

Lehetnek olyan projekciók is, ahol az eredménytáblázatban bizonyos rekordok többször is szerepelnek. Bizonyos esetekben hasznos lehet ez a duplázódás, máskor azonban teljesen feleslegesnek tűnik. Az SQL nyelv ezért lehetőséget biztosít az ismétlődések elkerülésére, ugyanis a DISTINCT módosító megadásával csak az egymástól különböző sorok lesznek láthatóak az eredménytáblában. Ezt az opciót közvetlenül a SELECT kulcsszó után kell megadni:

SELECT [DISTINCT] oszlopnév1, oszlopnév2, ..., oszlopnévN FROM táblanév; Például a különböző tanár és megtartott óra párosításokat lekérdezhetjük az Órarend táblából, mely a következőképp valósítható meg:

SELECT DISTINCT tanár_id, óra_id FROM Órarend;

- 30 -


A projekcióval kapcsolatban még egy megjegyzés fűzhető. Ha minden, táblában szereplő mezőre kíváncsiak vagyunk, nem szükséges valamennyi mező megadása, hanem elegendő egy * karaktert megadni a mezőnevek helyett:

SELECT * FROM táblanév; Például, ha a Tanár tábla valamennyi adatát ki szeretném listázni, akkor elegendő csak annyit megadni, hogy:

SELECT * FROM Tanár;

A WHERE feltétel Az adatbázis-kezelés egy másik nagy műveletcsoportja a szelekció. A szelekció megvalósítása esetén a SELECT utasítás egy WHERE feltétellel egészül ki, tehát a szelekció művelete során egy relációból csak az adott feltételt kielégítő sorokat őrizzük meg az eredmény relációban. A szelekciós feltétel és megadásának jellege megegyezik a DELETE és UPDATE parancsoknál említett feltétellel. Mivel egy lekérdezés több relációs algebrai műveletet tartalmazhat, ezért a SELECT utasításban szerepelhetnek már megismert elemek is az éppen vizsgált műveleti rész mellett. A szelekció megadása a következő alakban történik:

SELECT oszlopnév1, oszlopnév2, ..., oszlopnévN FROM táblanév - 31 -


WHERE feltétel; A SELECT és a FROM utáni részek a korábban megadott elemeket tartalmazzák. Adjuk meg például azon tanárok minden adatát, akik Budapesten laknak.

SELECT * FROM Tanár WHERE város = 'Budapest';

A szelekció és a projekció művelete összevonható egy utasítással. Példaként adjuk meg azokat a tanárokat, akik Budapesten laknak, és csak a nevükre és telefonszámukra vagyunk kíváncsiak:

SELECT név, tel FROM Tanár WHERE város = 'Budapest';

A keresési feltételekben szerepelhetnek összehasonlító operátorok (=, >, >= , <, <=, <>, !=, ^=), melyek numerikus, karakteres és dátum típusú adatok vizsgálata esetén is használhatók. Ezek megtekintéséhez ugorj az Összehasonlító műveletek című fejezethez. Segítségükkel attribútumokat és konstansokat hasonlíthatunk össze. A szöveg és dátum konstansokat mindig idézőjelek között kell megadni. Az SQL tartalmaz olyan összehasonlító operátorokat is, melyek nem egy adott értékkel, hanem az értékek egy halmazával történő összehasonlítást eredményeznek. Ezek a LIKE, az IN és BETWEEN operátorok, melyeket megtalálod a Predikátumok című fejezetben. Röviden róluk:

Operátor Értelmezés BETWEEN x AND Adott értékek közé esik-e az összehasonlítandó y érték Az értékek között található-e az IN(a,b,c,...) összehasonlítandó érték Hasonlít-e a mintára az összehasonlítandó LIKE minta szöveg - 32 -


7. Táblázat Össszehasonlító operátorok halmazokra

Tehát az IN operátor esetén egy halmazt adhatunk meg az elemek felsorolásával. A LIKE operátort, pedig karakteres mezők összehasonlítására használhatjuk. A Predikátumok témakörben már szó volt arról, hogy két speciális karakter adható meg a LIKE mintájában. A % jel tetszőleges hosszúságú karakter sorozatot helyettesít, míg az _ karakter, pedig egy tetszőleges karaktert. Az attribútumok vizsgálata esetén használható még az IS NULL összehasonlító operátor is, mely segítségével eldönthetjük, hogy a mező ki van-e töltve. Átismétléséhez ugorj vissza a Predikátumok témakörhöz. Több keresési feltételt kapcsolhatunk össze a logikai operátorokkal, illetve segítségükkel a halmazműveleteket is megvalósíthatjuk. Ezen logikai operátorok a NOT, AND és az OR. Megtekintéséhez ugorj a Predikátumok című fejezethez. Még egy fontos dolgot meg kell említeni, amire figyelni kell a lekérdezések megvalósítása során. Ez a precedencia szabály, vagy más néven kiértékelés sorrend. Megtekintéséhez ugorj a Precedencia szabály című fejezethez. A továbbiakban nézzünk néhány példát a lekérdezésekre. Például az idegennyelvűeknek órát tartó tanárok valamennyi adatát a következőképp kérdezhetnénk le:

SELECT * FROM Tanár WHERE idegennyelvű= 'I'; A jóga órát tartó tanárok azonosítói így adhatók meg (itt használható a DISCTINT módosító). Itt egyed-összekapcsolásra van szükség, melyet a Táblák összekapcsolása a SELECT utasítás segítségével című témakörben tárgyalunk.

SELECT DISTINCT tanár_id FROM Órarend, Óra, Tanár WHERE Tanár.tanár_id = Órarend.tanár_id AND Órarend.óra_id = Óra.óra_id AND Óra.óratípus = 'jóga'; A K betűvel kezdődő nevű tanárok neve, és telefonszáma így adható meg:

SELECT név, tel FROM Tanár WHERE név LIKE 'K%'; Tegyük fel, hogy a Tanár tábla telefon mezőjét nem kell kötelezően kitöltenünk. Adjuk meg azokat a tanárokat, akik irányítószáma 1112 és nincs telefonjuk:

- 33 -


SELECT * FROM Tanár WHERE irsz = 1112 AND tel IS NULL;

Adjuk meg azoknak az óráknak az időpontját, ahol a használt felszerelés ugrókötél, vagy zsámoly:

SELECT időpont FROM Óra WHERE felszerelés = 'ugrókötél' OR felszerelés = 'zsámoly';

Ugyanez megadható az IN operátor segítségével is: SELECT időpont FROM Óra WHERE felszerelés IN ('ugrókötél', 'zsámoly'); Adjuk meg azoknak a termeknek a számát, amelyek maxlétszáma 8 és 15 között van:

SELECT terem_id FROM Terem WHERE maxlétszám BETWEEN 8 AND 15;

- 34 -


Adjuk meg azokat az órákat, amelyek 15 és 18 óra között kezdődnek, és a típusuk stepaerobik:

SELECT * FROM Óra WHERE időpont BETWEEN 15 AND 18 AND típus = 'stepaerobik';

Adjuk meg a tanár táblából azon tanárok valamennyi adatát, akik keresztneve Lajos, és elmúltak 40 évesek:

SELECT * FROM Tanár WHERE név LIKE '% Lajos' AND kor>25;

Az ORDER BY alparancs Az eddigi lekérdezések eredményei a sorokban tárolt sorrendjük szerint kerülnek kiírásra. Az SQL lehetőséget biztosít a lekérdezés eredménysorainak rendezésére, melyre az ORDER BY alparancs szolgál. Az utasítás általános alakja:

SELECT oszlopnév1, oszlopnév2, ..., oszlopnévN FROM táblanév WHERE feltétel ORDER BY oszlopnév1 [ASC/DESC], ..., oszlopnévN [ASC, DESC]; Az ORDER BY után megadott attribútumok alapján az ASC növekvő, DESC esetén, pedig csökkenő sorrendbe rendezi az eredménytábla sorait. Az ASC alapértelmezés szerinti rendezést ad, mivel ez az alapértelmezett, ezért ezt nem kell megadni. Ha több attribútumot adunk meg a rendezési feltételben, akkor a megadás sorrendje szerint történik a rendezés, vagyis először az elsőnek megadott attribútum alapján rendezi sorban a sorokat, ha ez az attribútum azonos két sorra, akkor a másodikként megadott attribútum alapján történik a rendezés, és így tovább. A karakteres attribútumok esetén a rendezés a karakterek kódjai alapján történik, nevek esetén

- 35 -


például az angol ABC szerint. Példaként rendezzük név szerint a budapesti tanárok adatait ABC sorrendbe:

SELECT * FROM Tanárok WHERE város = 'Budapest' ORDER BY név;

Vagy adjuk meg típusonként valamennyi óra időpontját rendezve. Ebben az esetben először a típus, majd az időpont szerint fogja rendezni a sorokat.

SELECT óra_id, időpont, típus, jelleg FROM Óra ORDER BY típus, időpont;

A GROUP BY és a HAVING alparancs A gyakorlatban nagy jelentősége van a csoportképzés műveletének. A csoportképzés annyit jelent, hogy a táblázat rekordjaiból bizonyos csoportokat képezünk, ahol egy csoportba a valamilyen szempont szerint összeillő rekordok tartoznak. Az eredménytáblában egy rekord egy csoportnak fog megfelelni, vagyis egy rekord egy csoport adatait írja le. A lekérdezések eredményeit tehát csoportosíthatjuk, és az egyes csoportok között további szelekciót alkalmazhatunk. Erre szolgál a GROUP BY, és a HAVING alparancs, így a SELECT utasítás alakja a következő lesz:

- 36 -


SELECT oszlopnév1, oszlopnév2, ..., oszlopnévN FROM táblanév WHERE feltétel GROUP BY oszlopnévK HAVING csoport feltétel ORDER BY oszlopnévS A GROUP BY után megadott attribútum azonos értékei alapján csoportosítja az SQL a lekérdezés eredményeit, és a csoport feltételnek megfelelő sorok kerülnek az eredménybe. A csoportok képzésekor az eredmények között az azonos csoportba tartozó sorokból levezetett további eredmények megjelenítésére is lehetőséget biztosít az SQL. Ez a következő, az ún. aggregát függvényekkel valósítható meg:     

MIN (k) minimumérték MAX (k) maximumérték AVG (k) átlag SUM (k) összeg COUNT (k) elemek száma

Az operátorokban szereplő k szimbólum egy tetszőleges, az előzőekben már értelmezett kifejezés lehet. A kifejezés a csoport minden rekordjára kiértékelődik, és így visszakapjuk az értékek minimumát, maximumát, átlagát, összegét és elemszámát. Ez az elemszám olyan rekordok darabszámát jelenti, melyeknél a kifejezés nem ad üres (vagyis NULL) értéket. Ha a csoportban elhelyezkedő rekordok darabszámára vagyunk kíváncsiak, akkor a COUNT(*) kifejezést kell használnunk. Példaként adjuk meg azokat az órákat, melyeknél több, mint 5 felszerelést használnak: SELECT óra_id, típus, COUNT(felszerelés) AS felszerelések száma FROM Óra GROUP BY óra_id HAVING COUNT(felszerelés)>5; Adjuk meg, hogy átlagosan hány személy jár az egyes óratípusokra, melyeket nők számára tartanak:

SELECT típus, AVG(létszám) FROM Óra WHERE jelleg = 'női' GROUP BY típus;

Adjuk meg a tanárok átlagéletkoránál fiatalabb tanárok valamennyi adatát, név szerint csoportosítva, melyhez egy beágyazott lekérdezésre lesz szükségünk, amit a Lekérdezések egymásba ágyazása című fejezetben ismertetünk:

- 37 -


SELECT * FROM Tanár GROUP BY név HAVING kor < (SELECT AVG(kor) FROM tanár);

A függvények argumentuma előtt megadható a DISTINCT vagy az ALL módosító. A DISTINCT esetén csak a különböző értékek, ALL esetén minden érték részt vesz a számításban. Az alapértelmezés az ALL. A definiálatlan, NULL értékek nem szerepelnek a számításban. Megtekintésükhöz ugorj a Predikátumok című fejezethez.

Függvények alkalmazás GROUP BY nélkül Az előző témakörben említett aggregát függvények alkalmazhatóak a GROUP BY utasítás nélkül is. Ha például a tanárok számára vagyunk kíváncsiak, akkor azt mondjuk, hogy:

SELECT COUNT(*) FROM Tanár;

- 38 -


Adjuk meg, hogy a gyermekaerobik foglalkozásokra hány gyerek jár összesen:

SELECT SUM(létszám) FROM Óra WHERE típus = 'gyermekaerobik';

A lekérdezésekben az attribútumok és a csoportokra vonatkozó függvények mellett az attribútumok aritmetikai kifejezéseit is használhatjuk. A kifejezésekben használhatók az alapműveletek, illetve zárójelek a műveletek végrehajtási sorrendjének módosítására. Példakánt készítsünk egy olyan lekérdezést, melyben minden óra kezdési időpontját előbbre hozzuk egy órával: SELECT óra_id, időpont-1 AS újidőpont FROM Óra; A SELECT utasítás a relációk közötti szorzás művelet végrehajtására is alkalmas. Ez az úgynevezett Descartes-szorzat, mely két reláció sorait minden kombinációban egymás mellé teszi az eredmény táblában. Tehát több reláció nevét kell megadni a FROM után. Példaként adjuk meg az összes lehetséges tanár óra azonosító párt:

SELECT tanár_id, óra_id FROM Tanár, Óra

- 39 -

Megnézem


Táblák összekapcsolása a SELECT utasítás segítségével 1. Egyen összekapcsolás A lekérdező utasítás segítségével már eddig is sokféle kérdésre kaptuk meg közvetlenül a választ. Azonban táblák összekapcsolásával még komplexebb kérdéseket oldhatunk meg egy lépésben. Az összekapcsolás művelete két vagy több táblát kapcsol össze egy-egy attribútum érték összehasonlításával. Az összekapcsolás leggyakoribb esete az, amikor az attribútumok egyezését vizsgáljuk. Ezt egyen összekapcsolásnak (Equjoin) nevezzük. Az utasítás általános alakja a következő:

SELECT táblanév1.mezőnév, táblanév2.mezőnév, ..., táblanévN.mező FROM táblanév1, táblanév2, ..., táblanévN WHERE kapcsolómező operátor kapcsolómező; Az összekapcsolások esetén minimum két relációval dolgozunk. Ha a két táblában azonos nevű mezők szerepelnek, a minősített névvel, vagyis a táblanév.mezőnév kifejezés segítségével tudunk a kívánt elemre hivatkozni. Példaként adjuk meg a tanárok nevét, és az óráinak azonosítóját, típusát, és időpontját. SELECT név, óra_id, típus, időpont FROM Tanár, Órarend, Óra WHERE Tanár.Tanár_id = Órarend.Tanár_id AND Órarend.óra_id = Óra.óra_id; Az SQL szabvány egy másik megoldást is biztosít a belső összekapcsolásra, mely kulcsszava az INNER JOIN. Az utasítás általános alakja ezáltal a következő lesz:

SELECT táblanév1.mezőnév, táblanév2.mezőnév, ... FROM táblanév1 INNER JOIN táblanév2 ON táblanév1.kulcsmező = táblanév2.kulcsmező; Példaként adjuk meg a tanárok nevét, valamint az általuk tartott órák azonosítóját:

SELECT név, óra_id FROM Tanár INNER JOIN Órarend ON Tanár.Tanár_id = Órarend.Tanár_id;

- 40 -


2. Nem Egyen-összekapcsolás A táblák összekapcsolása esetén beszélhetünk más összekapcsolási módról is, melyet nem egyen-összekapcsolásnek (Non-Equjoin) nevezünk. Ez arról ismerhető fel, hogy a lekérdezésben szereplő oszlopkifejezések közötti relációjel az egyenlőségtől különböző. Példaként készítsünk el egy olyan párosítást a tanárok tagjai között, hogy az első tag fiatalabb legyen, mint a második:

SELECT T1.név, T2.név FROM Tanár T1, Tanár T2 WHERE T1.kor < T2.kor;

A lekérdezésben szereplő T1, és T2 a Tanár tábla alias nevei, melynek segítségével két sort vizsgálhatunk ugyanabból a táblából egyszerre. Ennél sokkal komplikáltabb szorzás műveletet is megfogalmazhatunk. Például 25 és 30 év közötti tanárok között rendezünk egy körmérkőzéses sakkbajnokságot, melyhez szeretnénk az összes lehetséges párosítását előállítani:

SELECT A.név, B.név FROM Tanár A, Tanár B WHERE A.kor BETWEEN 25 AND 30 AND B.kor BETWEEN 25 AND 30 AND A.tanár_id <> B.tanár_id;

- 41 -


A különböző tanár azonosítókra vonatkozó feltétel megadására azért van szükség, hogy az önmagukkal alkotott párok ne kerüljenek be a lekérdezés eredményébe. 3. Külső összekapcsolás Az összekapcsolások harmadik fajtája a külső összekapcsolás (Outer Join). A külső összekapcsolás esetén az egyik tábla minden sora megjelenik az eredményben, akkor is, ha nincs az összekapcsolás feltételének megfelelő sor a másik táblában. A külső összekapcsolás a LEFT JOIN, illetve a RIGHT JOIN kulcsszavakkal valósítható meg. A LEFT JOIN esetén az első tábla, míg a RIGHT JOIN esetén a második tábla minden sora bekerül az eredmény táblába. A külső összekapcsolás nem fogalmazható meg a WHERE feltételben. A lekérdezés általános alakja ezáltal a következő lesz:

SELECT táblanév1.mezőnév, táblanév2.mezőnév, ... FROM táblanév1 LEFT/RIGHT JOIN táblanév2 ON táblanév1.kulcsmező = táblanév2.kulcsmező; Példakánt alakítsuk át egy kicsit azt a példát, melyben a tanárok nevét, és az óráik azonosítóját kérdeztük le. Most azoknak a tanároknak a neve is megjelenjen, akik nem tartanak órát. Ehhez a LEFT JOIN kulcsszóra lesz szükségünk.

SELECT név, óra_id FROM Tanár LEFT JOIN Órarend ON Tanár.Tanár_id = Órarend.Tanár_id;

Lekérdezések egymásba ágyazása Az SQL DQL nyelvének számos olyan opciójával ismerkedhettünk meg eddig, mely kellő rugalmasságot adott a lekérdezések megfogalmazásában. Maradtak azonban olyan lekérdezések, melyek nem oldhatók meg az eddigi ismeretekkel. Például hogyan tudnánk megadni a legkevesebb létszámú jóga órát látogatók létszámát. Ehhez nem elegendő egy sima szelekció, hiszen a mi esetünkben arra lenne szükség, hogy először kilistázzuk az összes jóga óra létszámát, majd ennek eredményével hasonlítanánk össze az Óra tábla létszám mezőjének értékeit. Vagyis a szelekciós feltételben egy másik lekérdezés eredményére kell hivatkoznunk. Ha a SELECT utasítás WHERE vagy HAVING feltételében olyan logikai kifejezés található, amely SELECT utasítást tartalmaz, azt alkérdésnek nevezzük. Egyes irodalmakban allekérdezés,

- 42 -


vagy belső SELECT néven is szerepel. Nem csak a lekérdező utasításban találkozhatunk allekérdezéssel, hanem az UPDATE, és az INSERT utasítások esetén is. A mélyebben elhelyezkedő SQL utasítás több sort is visszaadhat a relációból. Ezen eseteket az ANY, ALL és EXISTS predikátumok segítségével is kezelhetjük. Az ANY és az ALL esetében az összehasonlítás egyik oldalára egy listát írhatunk, mely származhat egy beágyazott lekérdezésből is. Az említett lekérdezés tehát a következőképp oldható meg:

SELECT DISTINCT létszám FROM Óra WHERE típus = 'jóga' AND létszám <= ALL (SELECT létszám FROM Óra WHERE típus = 'jóga');

Ugyanezt a kérdést egyszerűbben is megfogalmazhatjuk egy aggregát függvény (MIN) segítségével. SELECT MIN (létszám) FROM Óra WHERE típus = 'jóga'; Az EXISTS predikátum esetén mindig egy újabb beágyazott lekérdezés következik. Ha egy beágyazott lekérdezés talál feltételt kielégítő sort, akkor igaz értéket ad, ellenkező esetben hamisat. Ezek megtekintéséhez ugorj a Predikátumok című fejezethez. Példaként adjuk meg azokat a tanárokat, akik nem tartanak jóga órát:

SELECT név FROM Tanár T WHERE NOT EXISTS (SELECT * FROM Órarend, Tanár, Óra WHERE T.Tanár_id = Órarend.Tanár_id AND Órarend.Óra_id = Óra.Óra_id AND Óra.típus = 'jóga'); Lap tetejére

- 43 -


Halmazműveletek SQL-ben Az egyenlőség vizsgálatok esetén a belső lekérdezés mindössze egy értéket adhat vissza. Azonban az SQL nyelv lehetőséget biztosít több érték visszaadására is egyenlőség vizsgálatok esetén, melyek megvalósítására a halmazműveletek szolgálnak. Tehát a halmazokkal kapcsolatos alapvető műveleteket (unió, metszet, különbség) a táblákra is értelmezzük. Minden értelmezett halmazművelethez legalább két operandus szükséges. A halmaz műveletek csak azonos szerkezetű táblák között hajthatók végre, ez alatt azt értjük, hogy a műveletbe bevont két reláció oszlopainak meg kell egyeznie az elnevezésben és a tárolt adat típusában is. A táblákon értelmezett halmazműveletek bizonyos esetekben az OR, AND, NOT és az IN operátorok segítségével is elvégezhetők. A halmazműveletek megvalósítása a következőképp történhet:

Unió SELECT ... UNION SELECT ...

Metszet SELECT... INTERSECT SELECT ...

Különbség SELECT... MINUS SELECT ...

Halmazműveletek megvalósítása az SQL nyelvben

1. Unió Az unió művelete csak két vagy több azonos szerkezetű tábla között végezhető el. Az eredmény reláció tartalmazza azon sorokat, amelyek a műveletbe bevont relációk közül legalább egyben szerepelnek. Ha ugyanaz a sor az egyesítendő relációk közül többen is szerepelne, akkor is csak egyszer szerepel az eredmény táblában. Példaként adjuk meg azokat a termeket, ahol Kiss Jánosnak vagy Fehér Márta vannak órái: SELECT Terem_id FROM Órarend, Tanár WHERE Órarend.Tanár_id = Tanár.Tanár_id AND Tanár.név = 'Kiss János' UNION SELECT Terem_id FROM Órarend, Tanár WHERE AND Órarend.Tanár_id = Tanár.Tanár_id AND Tanár.név = 'Fehér Márta'; Ugyanez megvalósítható az IN operátor segítségével is:

SELECT Terem_id FROM Órarend, Tanár WHERE Tanár.név IN ('Kiss János', 'Fehér Márta') AND Órarend.Tanár_id = Tanár.Tanár_id;

- 44 -


2. Metszet A metszet művelete két vagy több azonos szerkezetű tábla között végezhető el. Az eredmény reláció csak azokat a sorokat tartalmazza, melyek a műveletbe bevont relációk közül mindegyikben szerepelnek. Példaként adjuk meg azokat a tanárokat, akiknek a 10-es és 11-es teremben is van órájuk: SELECT Tanár.név FROM Tanár, Órarend WHERE Tanár.Tanár_id = Órarend.Tanár_id AND Órarend.Terem_id = 10 INTERSECT SELECT Tanár.név FROM Tanár, Órarend WHERE Tanár.Tanár_id = Órarend.Tanár_id AND Órarend.Terem_id = 11;

3. Különbség A különbség művelete két azonos szerkezetű tábla között végezhető el. Az eredmény reláció csak azokat a sorokat tartalmazza, melyek az első relációban megtalálhatóak, de a másodikban nem. A következőkben adjuk meg azon tanárok nevét, akiknek a 10-es teremben van órájuk, de a 11-es teremben nincsen: SELECT Tanár.név FROM Tanár, Órarend WHERE Tanár.Tanár_id = Órarend.Tanár_id AND Órarend.Terem_id = 10 MINUS SELECT Tanár.név FROM Tanár, Órarend WHERE Tanár.Tanár_id = Órarend.Tanár_id AND Órarend.Terem_id = 11; Az utóbbi két művelet is megoldható halmazműveletek nélkül, de ez csak egymásba ágyazott lekérdezésekkel lehetséges.

- 45 -


Az SQL DCL, vagyis az adatelérést vezérlő nyelv utasításai Az SQL komponensei közül már csak a DCL nyelv maradt ki, mely a jogok, jogosultságok parancsaira korlátozódik. Az adatbázis-kezelés egyik alapveto feltétele az, hogy az adatbázist több felhasználó is használhatja akár egy időben is, és adataikat letárolhatják. Az adatbázis így több különböző felhasználó adatait tárolja együttesen, ebből kifolyólag az adatbázis-kezelő rendszernek gondoskodnia kell arról, hogy mindenki csak azokat a műveleteket végezhesse el, amelyekre jogosult, vagyis csak a jogosult adatokhoz férhessen hozzá.

Az adatbázishoz való hozzáférés szabályozása Az SQL rendszerekben minden felhasználónak van egy azonosítója, és egy jelszava. Így minden felhasználóhoz könnyen rendelhető egy jogosultsági kör. A felhasználó egy

CONNECT TO adatbázisnév USER felhasználónév; utasítással tud az adott adatbázishoz kapcsolódni. Az adatbázis azonban a kapcsolódást követően még nem lesz aktív, hiszen a felhasználói név mellett hiányzik még egy jelszó. A jelszavak megadását az egyes számítógépes alkalmazások különbözőképp szabályozzák. Egyszerre több adatbázis is elérhetővé válhat, ehhez mindössze csatlakoznunk kell valamennyihez a CONNECT utasítással. Ahhoz, hogy egy adatbázist aktiváljunk, egy újabb parancsra van szükség:

SET CONNECTION DEFAULT adatbázisnév; A DEFAULT kulcsszó az alapértelmezett adatbázist jelöli, melyet egy adatbázis-felügyelő jelöl ki az adott felhasználó számára. Aktív adatbázis esetén a minosített neveknél az adatbázis neve elhagyható. Minden olyan adatbázis esetében, melyekhez már csatlakoztunk, de azok még nem aktívak, az adatbázis elemeire a következő minősített névvel kell hivatkozni: adatbázisnév.tulajdonos.adatbáziselem-név. A létrehozott kapcsolatot, pedig a következő utasítással szüntethetjük meg:

DISCONNECT adatbázisnév (ALL/CURRENT); A parancssorban szereplő ALL kulcsszóval valamennyi kapcsolat, a CURRENT kulcsszóval, pedig az aktív adatbázissal való kapcsolat szuntethető meg.

Felhasználási jogok szabályozása Az SQL rendszerekben minden objektumnak, vagyis adatbázis elemnek van egy tulajdonosa, ez pedig, az a felhasználó, aki létrehozta. A jogosultságok megadása a GRANT utasítással történik, melyben meg kell adni, hogy mely táblára, mely műveletre, és kinek engedélyezzük. Az egyes felhasználóknak kétféle jogot adhatunk: 

az adatbázisra vonatkozót:

GRANT adatbázisjog TO PUBLIC felhasználói nevek listája; 

és adatbáziselemekre vonatkozót:

- 46 -


GRANT műveleti jog ON adatbáziselem neve TO PUBLIC felhasználói nevek listája WITH GRANT OPTION; A parancssorokban szereplő PUBLIC kulcsszó használata következtében valamennyi felhasználó kap jogot, egyéb esetben csak az utasításban felsorolt felhasználók, vagy felhasználói csoportok. A WITH GRANT OPTION záradék lehetővé teszi, hogy a felhasználó, a kapott jogait más felhasználóknak továbbadhassa. Tehát ezek után bárki megszerezheti a jogokat. Az adatbázisra vonatkozó jogok a következők:   

CONNECT: kapcsolódás az adatbázishoz és a négy adatkezelési művelet (adatbevitel, módosítás, törlés, lekérdezés) használatának engedélyezése RESOURCE: adatbáziselemek létrehozásának, és megszűntetésének joga, továbbá az adatbázis kezelési joga DBA: az adatbázissal kapcsolatos bármilyen művelet elvégzésére vonatkozó jog, beleértve ebbe az adatbázis megszűntetését is.

Az adatbáziselemekre vonatkozó műveleti jogok a következők:        

ALL: az összes az alábbiakban felsorolt jog ALTER: táblák illetve nézettáblák megváltoztatási joga DELETE: sorok törlésére vonatkozó jog INDEX: táblázat indexelésének, illetve az index megszűntetésnek joga INSERT: új sorok bevitelére vonatkozó jog SELECT oszlopnév-lista: a felsorolt oszlopok, vagy azok hiányában a tábla valamennyi oszlopára vonatkozó lekérdezési jog UPDATE oszlopnév-lista: a felsorolt oszlopok, vagy azok hiányában a tábla valamennyi oszlopára vonatkozó módosítási jog REFERENCES oszlopnév-lista: a felsorolt oszlopokra, vagy azok hiányában a tábla valamennyi oszlopára vonatkozó hivatkozási jog

Az adatbázisra, vagy annak elemeire vonatkozó jogoknak mindig összhangban kell lenniük, de mindig az adatbáziselemre vonatkozó jogok az erősebbek. Erre talán az egyik legjobb példa az, hogy hiába van CONNECT jogunk egy adatbázishoz, ha az elemre vonatkozóan nincs UPDATE jogunk, hiszen az adatbáziselemet ebben az esetben nem tudjuk módosítani. Példaként adjunk az 1-es azonosítójú tanárnak a Tanár táblára vonatkozó módosítási jogot. Az azonosítás itt az adatbázis-kezelő rendszeren belüli azonosítást jelenti. GRANT UPDATE ON tanár TO 1; A gyakorlatban gyakran előfordulnak olyan esetek, amikor a korábban kiadott jogokat vissza kell vonni. Például megváltozik egy tanár beosztása, más órát fog tartani, így más emberek adatait láthatja. A kiadott jogosultságok kiadására a REVOKE utasítás szolgál, melyben hasonlóan a GRANT utasításhoz, meg kell adni a táblát, a felhasználót, és a visszavont műveletet. Az adatbázisjog visszavonása a következőképp törtéhet:

REVOKE adatbázisjog FROM PUBLIC felhasználói nevek listája A műveleti jog visszavonására a következő parancs szolgál:

REVOKE műveleti jog ON adatbáziselem neve FROM PUBLIC felhasználó nevek listája;

- 47 -


Az utasítás hatására a felhasználó többé már nem végezheti el a megadott műveletet az adott táblán. Csak az a felhasználó vonhatja vissza a jogokat, akinek van joga adományozni is. Példaként vegyük el az 1-es azonosítójú tanártól az összes jogot: REVOKE ALL FROM 1;

Hozzáférési zárak kezelése Az adatbázis-kezelő rendszerek egyik kiváltsága, hogy adatbázis területeket, adatlapokat, vagy sorokat automatikusan tudnak zárolni. Szükség esetén a felhasználó is kezdeményezheti a zárolást. Az SQL nyelv csak teljes táblázat zárolását engedélyezi, táblázatsorokét nem. Egy táblázat zárolásának kezdeményezésére szolgáló utasítás a LOCK TABLE, mely a következő:

LOCK TABLE táblanév IN (SHARE/EXCLUSIVE) MODE; Az utasításban szereplő SHARE kulcsszó használatával egyszerre több felhasználó tud az adott táblából lekérdezni, de módosítani nincs lehetőségük. Az EXCLUSIVE kulcsszó használatával a táblázatot, a zárolást kezdeményező felhasználó kizárólagosan használhatja, és felújítási műveleteket is hajthat végre rajta. A gyakorlatban az egyes zárolások visszavonására szükség lehet néha, melyre az UNLOCK TABLE utasítás szolgál.

UNLOCK TABLE táblanév; Tranzakciók kezelése A vezérlő utasításokhoz szokás sorolni a művelet végrehajtást szabályozó, más néven az úgynevezett tranzakció kezelő utasításokat. Az SQL szabványban két, a tranzakció végét jelző utasítást szokás definiálni. Az egyik utasítás a tranzakció sikeres befejezését jelenti, míg a másik a korábban végrehajtott tevékenységek visszavonását, azaz a megsemmisítését végzi. Az első, vagyis a tranzakció sikeres befejezésére a COMMIT utasítás szolgál. Ennek hatására véglegesítődnek a korábban végrehajtott tevékenységek. Ezzel szemben a másik utasítás, a ROLLBACK hatására a korábbi tevékenységek érvénytelenítődnek. Segítségével például egy hibával félbeszakadt műveletsort lehet töröltetni.

- 48 -


Feladatok 1. feladatsor: DVD kölcsönző A feladat: egy adatbázisban nyilvántartjuk a DVD kölcsönzők adatait. Minden Kölcsönzőnek van egy kódja, tudjuk a kölcsönzőben nyilvántartott tagok kódját, a kölcsönző címét, a tag általi kölcsönzés dátumát, és hogy mely DVD-t kölcsönözte ki. A Kölcsönző táblában értelemszerűen csak azok a DVD-k szerepelnek, amelyeket kikölcsönözték. A Tag táblában nyilvántartjuk minden tag kódját, a nevét, a születési dátumát, a címét, a korát, és az országot, ahol él. A DVDfilm tábla tartalmazza a DVD kódját, a DVD címét, annak kiadási évét, a beszerzési árát, a típusát, és a DVD-n levő film hosszát. A típus lehet mese, krimi, akciófilm... stb. A táblákban szereplő elsődleges kulcsokat kövérített betűvel jelöltem, az idegen kulcsokat, pedig aláhúzással. A kolcs_cím-ben és a tag_cím-ben csak a város nevét adjuk most meg! A kötelezően kitöltendő mezőket + jellel jelöltem!

DVDfilm DVD_kód szám(4),+ DVD_cím szöveg(50),+ Kiad_év dátum, Beszerz_ár egész(5),+ Típus szöveg(20),+ Hossz egész(3)+

Kölcsönző Tagok Kolcs_kód szám(4),+ Tag_kód szám(4),+ Dátum dátum,+

Név szöveg(50),+

Tag_kód szám(4),+ Kolcs_Cím szöveg (50),+ DVD_kód szám(4),+

Szül_dátum dátum,+ Tag_Cím szöveg(50),+ Kor egész(3),+ Ország szöveg(20),+

Megoldás: CREATE TABLE Dvdfilm (Dvd_kód INTEGER(4) NOT NULL, Dvd_cím CHAR(50) NOT NULL, Kiad_év DATE, Beszerz_ár INTEGER(5) NOT NULL, Típus CHAR(20), Hossz INTEGER(3), CONSTRAINT pk_Dvdfilm PRIMARY KEY (DVD-kód)); CREATE TABLE Kölcsönző (Kolcs_kód INTEGER(4) NOT NULL,

- 49 -


Dátum DATE NOT NULL, Tag_kód INTEGER(4) NOT NULL, Kolcs_cím CHAR(50), DVD_kód INTEGER(4) NOT NULL, CONSTRAINT pk_Kölcsönző PRIMARY KEY (kolcs_kód), CONSTRAINT fk_Kölcsönző_Tagok FOREIGN KEY (Tag_kód) REFERENCES Tagok (tag_kód), CONSTRAINT fk_Kölcsönző_Dvdfilm FOREIGN KEY (DVD_kód) REFERENCES Dvdfilm (Dvd_kód)); CREATE TABLE Tagok (tag_kód INTEGER(4) NOT NULL, név CHAR(50) NOT NULL, szül_dátum DATE NOT NULL, Tag_cím CHAR(50), Kor INTEGER(3), Ország CHAR(20) NOT NULL, CONSTRAINT pk_Tagok PRIMARY KEY (Tag_kód));

1. Írassuk ki a kikölcsönzött mese típusú DVD-k címét, a beszerzési árát, és a kölcsönzés dátumát! SELECT Dvdfilm.cím, Dvdfilm.beszerz_ár, Kölcsönző.dátum FROM Dvdfilm, Kölcsönző WHERE Dvdfilm.dvd_kód=Kölcsönző.dvd_kód AND Dvdfilm.típus='mese';

2. Adjon a DVD táblához egy olyan megszorítást, melyben kikötjük, hogy a DVD-k hossza 60 és 180 perc közötti lehet! ALTER TABLE Dvdfilm ADD CONSTRAINT ck_Dvdfilm_hossz CHECK (Hossz BETWEEN 60 AND 180);

3. Vegyük fel a Tag táblába a 95-ös azonositójú rekordot, ahol a Tag neve Pandacsöki Ákos, a születési dátuma 1970, a címe Düsseldorf, a kora 36 és az ország, ahol él Németország. INSERT INTO Tagok (tag_kód, nev, szül_dátum, Tag_cím, kor, ország) VALUES (95, 'Pandacsöki Ákos', 1970, 'Düsseldorf', 36, 'Németország');

4. Módosítsuk az akciófilm típusú DVD-k beszerzési árát 3000 Forintba! UPDATE Dvdfilm SET Dvdfilm.beszerz_ár=3000 WHERE Dvdfilm.típus = 'akciófilm';

5. Készítsen lekérdezést, amely kiírja az összes olyan Dvd címét, amit még senki sem kölcsönzött ki, ezeket rendezzük ABC szerint sorrendbe! SELECT DISTINCT Dvdfilm.cim FROM Dvdfilm, Kölcsönző WHERE Dvdfilm.Dvd_kód = Kölcsönző.Dvd_kód AND Dvdfilm.Dvd_kód NOT IN (SELECT Kölcsönző.Dvd_kód FROM Kölcsönző) ORDER BY Dvdfilm.cim;

6. Számoljuk meg, hány krimi típusú DVD található a kölcsönzőkben.

- 50 -


SELECT COUNT(Dvdfilm.tipus), Kölcsönző.kolcs_kód FROM Kölcsönző, Dvdfilm WHERE Kölcsönző.Dvd_kód = Dvdfilm.Dvd_kód AND Dvdfilm.típus='krimi' GROUP BY Kölcsönző.kód;

7. Töröljük a Dvd táblából az összes olyan DVD filmet, amit még nem kölcsönzött ki senki sem. (alselect) DELETE FROM Dvdfilm WHERE Dvdfilm.Dvd_kód NOT IN (SELECT Kölcsönző.Dvd_kód FROM Kölcsönző);

8. Készítsen lekérdezést, amely megadja az 1200 Ft feletti beszerzési árú DVD-k minden adatát! SELECT * FROM Dvdfilm WHERE Dvdfilm.beszerz_ár > 1200;

9. Készítsen lekérdezést, amely megadja a Budapesti lakosok átlagéletkorát! SELECT AVG(Tag.kor) FROM Tag WHERE Tag.cím = 'Budapest';

10. Dobd el az összes táblát! DROP TABLE Dvdfilm; DROP TABLE Kölcsönző; DROP TABLE Tag;

2. feladatsor: Bankrablás A feladat: Magyarországon nyilvántartjuk a bankrablások adatait egy adatbázisban. A Bankokról tudjuk, hogy milyen kóddal szerepel az adatbázisban, hogy mi a címe, és milyen néven szerepel. A Rablókról eltároljuk a kódjukat, hogy mely banko(ka)t rabolták ki, melyik börtönben vannak, továbbá, hogy mi a címük, a nevük, a születési évük, és mennyi pénzt raboltak az adott bankból. A rabló táblában értelemszerűen csak azok a bankok szerepelnek, ahonnan raboltak. A Börtönökről, pedig eltároljuk a börtön kódjárt, a címét, a nevét, és hogy mennyi a benne lévő férőhelyek száma.

- 51 -


A táblákban szereplő elsődleges kulcsokat kövérített betűvel jelöltem, az idegen kulcsokat, pedig aláhúzással. A bank_cím-ben, a rabló_cím-ben és a börtön_cím-ben csak a város nevét adjuk most meg! Minden mező kitöltése kötelező!

Bank Bank_kód szám(4),+ Bank_cím szöveg(50),+ Bank_név szöveg(50),+

Rabló Börtön Rabló_kód szám(4),+ Börtön_kód szám(4),+ Börtön_Név Bank_kód szám(4),+ szöveg(50),+ Börtön_Cím Börtön_kód szám(4),+ szöveg(50),+ Rabló_cím Férőhely egész(5),+ szöveg(50),+ Rabló_név szöveg(50),+ Szülév dátum,+ Menny egész(15),+

Megoldás: CREATE TABLE Bank (Bank_kód INTEGER(4) NOT NULL, Bank_cím CHAR(50) NOT NULL, Bank_név CHAR(50) NOT NULL, CONSTRAINT pk_Bank PRIMARY KEY (Bank_kód)); CREATE TABLE Rabló (Rabló_kód INTEGER(4) NOT NULL, Bank_kód INTEGER(4) NOT NULL, Börtön_kód INTEGER(4) NOT NULL, Rabló_cím CHAR(50) NOT NULL, Rabló_név CHAR(50) NOT NULL, Szülév DATE NOT NULL, Menny INTEGER(15), CONSTRAINT pk_Rabló PRIMARY KEY (Rabló_kód), CONSTRAINT fk_Rabló_Bank FOREIGN KEY (Bank_kód) REFERENCES Bank(Bank_kód), CONSTRAINT fk_Rabló_Börtön FOREIGN KEY (Börtön_kód), REFERENCES Börtön(Börtön_kód)); CREATE TABLE Börtön (Börtön_kód INTEGER(4) NOT NULL,

- 52 -


Börtön_név CHAR(50) NOT NULL, Börtön_cím CHAR(50) NOT NULL, Férőhely INTEGER(5) NOT NULL, CONSTRAINT pk_Börtön PRIMARY KEY (Börtön_kód));

1. Készíts lekérdezést, amely megadja, hogy a Kovács Béla nevű rabló melyik kódú börtönben van! SELECT Börtön.kód FROM Börtön, Rabló WHERE Rabló.börtön_kód = Börtön.börtön_kód AND Rabló.Rabló_név = 'Kovács Béla';

2. Adjon a Rabló táblához egy olyan megszorítást, melyben kikötjük, hogy nem lehet két ugyanolyan nevű rabló! ALTER TABLE Rabló ADD CONSTRAINT uq_Rabló_nev UNIQUE (nev);

3. Vegyük fel a Rabló táblába a 105-ös azonosítójú rekordot, a Rabló neve legyen Whiskys Ambrus Attila, a bank kódja melyet kirabolt a 15-ös, a börtön kódja, ahol jelenleg tartják, legyen 30-as, a címe legyen Kistarcsa, a születési éve 1967, a rabolt pénz mennyisége, pedig legyen 150.000.000 Ft. INSERT INTO Rabló (rabló_kód, bank_kód, börtön_kód, rabló_név, rabló_cím, szülév, menny) VALUES (105, 15, 30, 'Whiskys Ambrus Attila', 'Kistarcsa', 1967, 150000000);

4. Módosítsuk a 340-es kódú börtön férőhelyeinek számát 120-szal többre! UPDATE Börtön SET Börtön.férőhely = Börtön.férőhely + 120 WHERE Börtön.börtön_kód = 340;

5. Készítsen lekérdezést, mely megadja az összes olyan bank nevét, amit még nem raboltak ki, ezeket rendezzük név szerint! SELECT Bank.Bank_név FROM Bank, Rabló WHERE Bank.Bank_kód = Rabló.Bank_kód AND Bank.Bank_kód NOT IN (SELECT Rabló.Bank_kód FROM Rabló) ORDER BY Bank.Bank_név;

6. Készítsen lekérdezést, amely megadja rablónként, hogy hány budapesti bankot rabolt ki! SELECT Rabló.név, COUNT(Rabló.Bank_kód) FROM Rabló, Bank WHERE Rabló.Bank_kód = Bank.Bank_kód AND Bank.Bank_cím = 'Budapest' GROUP BY Rabló.név;

7. Töröljük a Bank táblából az össze olyan Bankot, amit még nem raboltak ki! DELETE FROM Bank WHERE Bank.Bank_kód NOT IN (SELECT Rabló.Bank_kód FROM Rabló);

8. Készítsen lekérdezést, amely megadja a 350 férőhely feletti Börtönök minden adatát!

- 53 -


SELECT * FROM Börtön WHERE Börtön.férőhely > 350;

9. Készítsen lekérdezést, amely megadja a rablók által rabolt pénz mennyiségének átlagát, amennyiben a rabló budapesti lakos volt! SELECT AVG(Rabló.menny) FROM Rabló WHERE Rabló.cím = 'Budapest';

10. Dobd el az össze táblát! DROP TABLE Bank; DROP TABLE Rabló; DROP TABLE Börtön;

3. feladatsor: Autók A feladat: Adott a következő adatbázis, ahol nyilvántartják a járművek, és a tulajdonosaik adatait. A jármű táblában szereplő márka a gépkocsi típusa(BMW, Mercedes, Ferrari, stb.), a kategória lehet személygépkocsi, teher, busz, ... stb., a tulajdonos idegen kulcs a Tulajdonos tábla személyi számára vonatkozóan, a megye pedig, a tulaj lakhelyének megyéje. A többi mezőhöz nem fűznék mást. A táblákban szereplő elsődleges kulcsokat kövérített betűvel jelöltem, az idegen kulcsokat, pedig aláhúzással. Minden mező kitöltése kötelező!

Jármű rendszám, szöveg(7) márka, szöveg(10) hengerűrtartalom, egész lóerő, egész szín, szöveg(10) férőhely, egész(1) kategória, szöveg(10) gyártási_év, egész(4) tulaj szöveg(12)

Tulaj személyiszám, szöveg(12) név, szöveg(40) cím, szöveg(50) megye, szöveg(20) szül_dátum, dátum szül_hely, szöveg(20) nem, szöveg(1)

- 54 -


Megoldás: CREATE TABLE Jarmu (rendszam CHAR(7) NOT NULL, marka CHAR(10) NOT NULL, hengerurtartalom INTEGER NOT NULL, loero INTEGER NOT NULL, szin CHAR(10) NOT NULL, ferohely INTEGER(1) NOT NULL, kategoria CHAR(10) NOT NULL, gyartev INTEGER(4) NOT NULL, tulaj CHAR(12) NOT NULL, CONSTRAINT pk_Jarmu PRIMARY KEY (rendszam), CONSTRAINT fk_Jarmu_Tulaj FOREIGN KEY (tulajdonos) REFERENCES Tulaj (szemelyiszam)); CREATE TABLE Tulaj (szemelyiszam CHAR(12) NOT NULL, nev CHAR(40) NOT NULL, cim CHAR(50) NOT NULL, megye CHAR(20) NOT NULL, szuldate DATE NOT NULL, szulhely CHAR(20) NOT NULL, nem CHAR(1) NOT NULL, CONSTRAINT pk_Tulaj PRIMARY KEY (szemelyiszam));

1. Minden Ferrari személygépkocsinak növeljük meg kettővel a férohelyeinek számát! UPDATE Jarmu SET ferohely = ferohely + 2 WHERE marka LIKE 'Ferrari' AND kategoria = 'szemely';

2. Töröljünk a Tulaj táblából minden olyan tulajdonost, akinek 3 gépjárműve van! (alselect) DELETE FROM Tulaj AS T1 WHERE 3 = ( SELECT COUNT(*) FROM Tulaj AS T2, Jarmu WHERE T2.szemszam = tulaj AND T1.szemszam = T2.szemszam);

3. Listázzuk ki a 2000 köbcentinél kisebb hengerűrtartalmú gépjárművek számát! SELECT COUNT(*) FROM Jarmu WHERE hengerurtartalom < 2000;

4. Listázzuk ki azokat a Vas megyében élő férfiakat, akiknek van tehergépkocsijuk (kategória), valamint rendezzük a táblát névsorrendbe! SELECT DISTINCT nev FROM Jarmu, Tulaj WHERE Jarmu.tulaj = Tulaj.szemelyiszam AND Tulaj.nem = 'férfi' AND Jarmu.kategoria = 'teher' AND Tulaj.megye ='Vas megye' ORDER BY nev;

- 55 -


5. Listázzuk ki azokat a férfiakat, akik Somogy megyében laknak, több mint egy gépjárművük van, és ezek közül valamelyik kék és a rendszámában szerepel az "K" betű, valamint rendezzük a táblát névsorrendbe. SELECT DISTINCT T1.nev FROM Jarmu AS J1, Tulaj AS T1 WHERE J1.tulaj = T1.szemelyiszam AND T1.nem = 'férfi' AND T1.megye = 'Somogy megye' AND 2 <= (SELECT COUNT(*) FROM Jarmu AS J2, Tulaj AS T2 WHERE J2.tulaj = T2.szemelyiszam AND T1.szemelyiszam = T2.szemelyiszam) AND J1.tulaj IN (SELECT J3.tulaj FROM Jarmu AS J3 WHERE J3.szin = 'piros' AND J3.rendszam LIKE '%K%') ORDER BY T1.nev;

4. feladatsor: Zöldséges A feladat: Adott a következő adatbázis, melyben nyilvántartják a boltok, a zöldségek, és a zöldségek termesztésénél alkalmazott vegyszerek adatait. A raktári készletben levő árúkat kilógrammban adjuk meg, a vegyszer idegen kulcs, mely a Vegyszer tábla vkód-jára mutat, a mennyiség az adott dátumon megvásárolt zöldségmennyiséget adja meg, a hatás pedig, a vegyszerek zöldségre gyakorolt hatását (gombaölő, rovarirtó, stb.) mutatja. A táblákban szereplő elsődleges kulcsokat kövérített betűvel jelöltem, az idegen kulcsokat, pedig aláhúzással. Minden mező kitöltése kötelező!

Zöldség Zkód egész(4) Zöldségnév szöveg(20) Raktáron egész Ár valós(4) Vegyszer egész(4)

Bolt Bkód egész(4)

Vegyszer Vkód egész(4) Vegyszernév Boltnév szöveg(50) szöveg(40) Cím szöveg(50) Hatás szöveg(15) Zöldségkód Ár valós(4) egész(4) Mennyiség egész Dátum dátum

Megoldás:

- 56 -


CREATE TABLE Zoldseg (Zkod INTEGER(4) NOT NULL, zoldsegnev CHAR(20) NOT NULL, raktaron INTEGER NOT NULL, ar DECIMAL(4) NOT NULL, vegyszer INTEGER(4) NOT NULL, CONSTRAINT pk_Zoldseg PRIMARY KEY (Zkod), CONSTRAINT fk_Zoldseg_Vegyszer FOREIGN KEY (vegyszer) REFERENCES Vegyszer (Vkod)); CREATE TABLE Bolt (Bkod INTEGER(4) NOT NULL, boltnev CHAR(50) NOT NULL, cim CHAR(50)NOT NULL, zoldsegkod INTEGER(4) NOT NULL, menny INTEGER NOT NULL, datum DATE, CONSTRAINT pk_Bolt PRIMARY KEY (Bkod), CONSTRAINT fk_Bolt_Zoldseg FOREIGN KEY (zoldsegkod), REFERENCES Zoldseg (Zkod)); CREATE TABLE Vegyszer (Vkod INTEGER(4) NOT NULL, vegyszernev CHAR(30) NOT NULL, hatas CHAR(10) NOT NULL, ar DECIMAL(4) NOT NULL, CONSTRAINT pk_Vegyszer PRIMARY KEY (Vkod));

1. Töröljünk minden olyan zöldséget, amiből nem vettek még! DELETE FROM Zoldseg WHERE Zoldseg.Zkod NOT IN (SELECT DISTINCT Bolt.zoldsegkod FROM Bolt);

2. Minden zöldségnek módosítsuk az adatait! Legyen a kódjuk 400-zal nagyobb, mint az eredeti, 10 kg legyen belőlük raktáron, az áruk az eredeti árának 120%-a legyen és valamennyi legyen vegyszerrel kezelt (NULL). UPDATE Zoldseg SET Zkod = Zkod + 400, raktaron = 10, ar = ar*1.2, vegyszer = NULL;

3. Listázzuk ki azoknak a boltoknak a nevét és címét, akik vásároltak már valamilyen almát(a gyümölcs nevében szerepel az alma), rendezzük az eredményt a boltok neve szerint! SELECT DISTINCT Bolt.boltnev, Bolt.cím FROM Bolt, Zoldseg WHERE Bolt.zoldsegkod = Zoldseg.Zkod AND Zoldseg.zoldsegnev LIKE '%alma%' ORDER BY Bolt.boltnev;

4. Listázzuk azokat a zöldségeket, amelyek nem voltak gombaölővel kezelve! SELECT DISTINCT Zoldseg.zoldsegnev FROM Zoldseg, Vegyszer WHERE Zoldseg.vegyszer = Vegyszer.Vkod AND Vegyszer.hatas NOT LIKE 'gombaölő';

- 57 -


5. Listázzuk ki azoknak a vegyszereknek a nevét, amellyel kezelt zöldséget már vásárolt győri bolt 650 kg-nál nagyobb tételben, az eredményt rendezzük névsorrendbe! SELECT DISTINCT Vegyszer.nev FROM Vegyszer, Zoldseg, Bolt WHERE Vegyszer.Vkod = Zoldseg.vegyszer AND Bolt.zoldsegkod = Zoldseg.Zkod AND Bolt.cim LIKE '%Győr%' AND Bolt.menny > 650; ORDER BY Bolt.boltnev;

6. Listázzuk ki minden vegyszerre, hogy átlagosan mekkora tételeket adtak el olyan zöldségből, amelyet az adott vegyszerrel kezeltek. A listában csak azok a vegyszerek szerepeljenek, amelyekkel kezelt zöldségekből már legalább 3 bolt vásárolt. SELECT Vegyszer.nev, AVG (menny) FROM Vegyszer, Zoldseg, Bolt WHERE Vegyszer.vkod = Zoldseg.vegyszer AND Bolt.zoldsegkod = Zoldseg.Zkod GROUP BY Vegyszer.vkod HAVING COUNT(DISTINCT Bolt.boltkod)>2;

5. feladatsor: Könyvtár A feladat: Adott a következő könyvtári adatbázis. Az adatbázisban nyilvántartjuk a Könyvek, az Olvasó tagok, és a Kölcsönzés adatait. A Kölcsönzés táblában szereplő Kiadás mező a kiadás dátumát jelenti, a Visszahozatal azt a dátumot, mikor visszavitték a kikölcsönzött könyvet. A Könyvek tábla Példányszáma, a könyvtárban levő könyvek darabszámát jelenti, a raktári jel, pedig az azonosító jelét. A többi mező egyértelmű. A táblákban szereplő elsődleges kulcsokat kövérített betűvel jelöltem, az idegen kulcsokat, pedig aláhúzással. Minden mező kitöltése kötelező!

Könyvek Raktárijel szöveg(5) Könyvcím szöveg(50) Szerző szöveg(40) Példányszám egész(10)

Olvasó Olvasójegy egész(5) Név szöveg(30) Olvasócím szöveg(50) Foglalkozás szöveg(20)

Kölcsönzés Sorszám egész(5) Olvasójegy egész(5) Raktárijel szöveg(5) Kiadás dátum Visszahozatal dátum Késedelmidíj egész(5)

- 58 -


Megoldás: 1. Írassa ki a könyvtárba 1988-ban befizetett 5000 forintnál nagyobb értékű 5 legnagyobb késedelmi díjat! SELECT TOP 5 Késedelmidíj FROM Kölcsönzés WHERE YEAR (Visszahozatal) = 1988 AND Késedelmidíj > 5000; ORDER BY Késedelmidíj DESC;

2. Írassa ki a könyvtárba 2002 január 7 és 20 között befizetett késedelmi díjakat! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.) SELECT Késedelmidíj FROM Kölcsönzés WHERE YEAR (Visszahozatal) = 2002 AND MONTH (Visszahozatal) = 1 AND DAY (Visszahozatal) BETWEEN 7 AND 20;

3. Írassa ki a könyvtárba 2000 első negyedévében befizetett késedelmi díjakat! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.) SELECT Késedelmidíj FROM Kölcsönzés WHERE YEAR (Visszahozatal) = 2000 AND MONTH (Visszahozatal) IN (1,2,3);

4. Írassa ki a könyvtárba az elmúlt egy hétben (=7 napban) befizetett késedelmi díjakat! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.) SELECT Késedelmidíj FROM Kölcsönzés WHERE Visszahozatal >= DATE( )-7;

5. Írassa ki a könyvtárba a 2004. február 27-én befizetett késedelmi díjakat! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be. Egy értéket csak egyszer írasson ki!) SELECT DISTINCT Késedelmidíj FROM Kölcsönzés WHERE Visszahozatal >= DATESERIAL(2004,02,27)

6. Írassa ki az egyes olvasók olvasójegy számát, és az olvasók által a könyvtárba 2003 október 1 és 15 között befizetett késedelmi díjak teljes összegét 'Késedelmi díjak' néven! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.)

- 59 -


SELECT Olvasójegy, SUM (Késedelmidíj) AS 'Késedelmi díjak' FROM Kölcsönzés WHERE YEAR(Visszahozatal) = 2003 AND MONTH (Visszahozatal) = 10 AND DAY (Visszahozatal) BETWEEN 1 AND 15 GROUP BY Olvasójegy;

7. Írassa ki a 2002-ban legtöbb késedelmi díjat befizető olvasók közül az első 10 olvasó olvasójegy-számát és az egyes olvasók által befizetett késedelmi díjak összegét 'Késedelmi díj' néven! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.) SELECT TOP 10 Olvasójegy, SUM (Késedelmidíj) AS 'Késedelmi díj' FROM Kölcsönzés WHERE YEAR (Visszahozatal) = 2002 GROUP BY Olvasójegy ORDER BY SUM (Késedelmidíj) DESC;

8. Írassa ki az 1978-ban 2500 Ft-nál több késedelmi díjat befizető olvasók olvasójegyszámát és az egyes olvasók által befizetett késedelmi díjak összegét 'Késedelmi díj' néven! (Feltéve, hogy a késedelmi díjakat a könyvek visszahozatalakor fizették be.) SELECT Olvasójegy, SUM (Késedelmidíj) AS 'Késedelmi díj' FROM Kölcsönzés WHERE YEAR (Visszahozatal) = 1978 GROUP BY Olvasójegy HAVING SUM (Késedelmidíj) > 2500;

9. Írassa ki az olvasók olvasójegy-számát, valamint a kikölcsönzött könyvek raktári jelzetét azokra a kölcsönzésekre, amelyek 2001 harmadik negyedévében történtek! Rendezze a kapott sorokat elsődlegesen olvasójegy-szám, ezen belül pedig raktári jelzet szerint! (Ha egy olvasó többször is kölcsönzött egy könyvet, csak egyszer írassa ki!) SELECT DISTINCT Olvasójegy, Raktárijel FROM Kölcsönzés WHERE YEAR (Kiadás) = 2001 AND MONTH (Kiadás) IN (7,8,9) ORDER BY Olvasójegy, Raktárijel;

10. Írassa ki a könyvtárba beiratkozott olvasók nevét és olvasójegy-számát, valamint a kikölcsönzött könyvek raktári jelzetét olvasójegy-szám, azon belül pedig raktári jelzet szerint rendezve! (Ha egy olvasó többször is kölcsönzött egy könyvet, csak egyszer írassa ki; ha pedig még egyszer sem kölcsönzött, a nevét és olvasójegy-számát akkor is írassa ki!) SELECT DISTINCT Kölcsönzés.Olvasójegy, Olvasó.név, Kölcsönzés.Raktárijel FROM Kölcsönzés, Olvasó WHERE Kölcsönzés.Olvasójegy = Olvasó.olvasójegy ORDER BY Kölcsönzés.Olvasójegy, Kölcsönzés.raktárijel;

11. Írassa ki a könyvtárból kölcsönző olvasók olvasójegy-számát, valamint az általuk kikölcsönzött könyvek számát 'Kölcsönzések száma' néven a kikölcsönzött könyvek száma szerint fordított sorrendben rendezve! SELECT Olvasójegy, COUNT (Raktárijel) AS 'Kölcsönzések száma' FROM Kölcsönzés GROUP BY Olvasójegy ORDER BY COUNT(Raktárijel) DESC;

- 60 -


12. Írassa ki Kiss Katalin és Kozma Ferenc kölcsönzéseinek adatait kiviteli dátum szerint rendezve! (Megjegyzés: lehet, hogy a hölgyeknek második keresztnevük is van!) SELECT * FROM Olvasó, Kölcsönző WHERE Olvasó.Olvasójegy = Kölcsönző.Olvasójegy AND Olvasó.Név LIKE 'Kiss Katalin%' ORDER BY Kiadás UNION SELECT * FROM Olvasó, Kölcsönző WHERE Olvasó.Olvasójegy = Kölcsönző.Olvasójegy AND Olvaso.Név LIKE 'Kozma Ferenc' ORDER BY Kiadás;

13. Írassa ki a könyvtárból kölcsönző olvasók olvasójegy-számát, a könyvek kiviteli és visszahozatali dátumát, valamint azt az időtartamot (napokban megadva) 'Kölcsönzési idő' néven, ameddig az általuk kölcsönzött könyvek náluk voltak! Az eredményül kapott sorokat rendezze olvasójegy-szám szerint! (A kölcsönzéseket csak akkor vegye figyelembe, ha a kikölcsönzött könyvet már visszahozták!) SELECT Olvasójegy, Kiadás, Visszahozatal, Visszahozatal - Kiadás AS 'Kölcsönzési idő' FROM Kölcsönzés WHERE Visszahozatal IS NOT NULL ORDER BY Olvasójegy;

14. Írassa ki a könyvtárból kölcsönző olvasók olvasójegy-számát, valamint azt a legrövidebb és leghosszabb időtartamot (napokban), ameddig az általuk kölcsönzött könyvek náluk voltak! Az eredményül kapott sorokat rendezze olvasójegy-szám szerint! (A kölcsönzéseket akkor is vegye figyelembe az aktuális dátum szerinti visszahozatali dátummal, ha a kikölcsönzött könyvet még nem hozták vissza!) SELECT Olvasójegy, MIN (Visszahozatal - Kiadás) AS 'Legrövidebb kölcsönzési idő', MAX (Visszahozatal - Kiadás) AS 'Leghosszabb kölcsönzési idő' FROM Kölcsönzés WHERE Visszahozatal IS NOT NULL GROUP BY Olvasójegy ORDER BY Olvasójegy UNION SELECT Olvasójegy, MIN (DATE( ) - Kiadás) AS 'Legrövidebb kölcsönzési idő', MAX (DATE( ) - Kiadás) AS 'Leghosszabb kölcsönzési idő' FROM Kölcsönzés WHERE Visszahozatal IS NULL GROUP BY Olvasójegy ORDER BY Olvasójegy;

15. Írassa ki a kikölcsönzött, de még nem visszahozott könyvekre a könyvek raktári jelzetét, a kölcsönző olvasók olvasójegy-számát, a könyvek kiviteli dátumát, valamint 15 nap kölcsönzési időt feltételezve: (1) ha a könyv kölcsönzése még nem járt le, a várható visszahozatali dátumot, (2) ha a könyv kölcsönzése már lejárt, egy "Lejárt!" szöveget! Az eredményül kapott sorokat rendezze olvasójegy-szám szerint! SELECT Olvasójegy, Raktárijel, Kiadás, 'Lejárt!' AS 'VISSZAHOZATAL' FROM Kölcsönzés WHERE (Visszahozatal IS NULL) AND (DATE( ) - Kiadás > 15) ORDER BY Olvasójegy

- 61 -


UNION SELECT Olvasójegy, Raktárijel, Kiadás, Kiadás + 15 AS 'VISSZAHOZATAL' FROM Kölcsönzés WHERE (Visszahozatal IS NULL) AND (DATE( ) - Kiadás <= 15) ORDER BY Olvasójegy;

16. Írassa ki azoknak a könyveknek az adatait (raktári jelzet, szerző, cím) és kölcsönzéseinek számát, amelyeket legalább tízszer kikölcsönöztek már! (A kapott sorokat rendezze raktári jelzet szerint!) SELECT Raktárijel, Szerző, Cím FROM Könyvek WHERE Raktárijel IN (SELECT Raktárijel FROM Kölcsönző GROUP BY Raktárijel HAVING COUNT(Raktárijel) >= 10) ORDER BY Raktárijel; Lap tetejére

- 62 -


Az SQL utasítások kipróbálásához ajánlott programok Ahhoz, hogy az SQL nyelvet tökéletesen elsajátíthassuk, szükségünk van valamilyen adatbáziskezelő környezetre, melyben az előbb említett utasításokat gyakorolni tudjuk. A következőkben ilyen környezetekkel ismerkedhetünk meg.

A MySQL környezet Az egyik, talán leggyakrabban használt környezetek közé tartozik a MySQL, mely egy nagyon kényelmes, és egyszerűen alkalmazható környezet. Emellé azonban szükségünk van egy phpMyAdmin felületre, melyen az adatbázissémákat kialakíthatjuk, és az SQL utasításokat gyakorolhatjuk. Továbbá nem árt a PHP nyelv ismerete sem, mely segítségével csatlakozhatunk egy adatbázishoz, valamint egyéb műveleteket hajthatunk végre. Hogy a környezetet tökéletesen használni tudjuk, az első feladatunk egy szerver feltelepítése. Én személy szerint az Apache szervert ajánlom mindenkinek. A továbbiakban még két dolgot kell tennünk, fel kell telepíteni a PHP és a MySQL nyelv összetevőit. A telepítésüket nem ecsetelném, mivel a következő oldalakon ezek részletes telepítési útmutatója megtalálható:  

Apache és PHP telepítése MySQL telepítése

A telepítések befejeztével a PhpMyAdmin felületet könnyedén el tudjuk érni a saját gépünkről abban az esetben, ha a telepítésnél mindent a leírtak szerint végeztünk. Ehhez elegendő a http://localhost/phpMyAdmin sort a böngészőbe írni. A telepítés során nagyon kell figyelni, hogy milyen verziókat használunk, mivel kompatibilitási problémák adódhatnak az egyes nyelvek verzióinak nem megfelelő megválasztásával. Miután minden működik, lépjünk be a phpMyAdmin felületre, ahol kiválaszthatjuk a nekünk megfelelő stílust, nyelvet, ... stb, továbbá importálhatuk illetve exportálhatunk táblákat, adatbázisokat, valamit itt tudunk adatbázissémát is létrehozni.

Ahhoz, hogy az SQL műveleteket gyakorolni tudjuk, először létre kell hoznunk egy adatbázist. Miután megadtuk a létrehozandó adatbázisunk nevét, már csak a Létrehoz gombra kell kattintanunk annak legeneráláshoz.

- 63 -


A következő feladat a táblák létrehozása, melyet egyszerű, és könnyed mozdulatokkal elvégezhetünk. Első lépésként meg kell adnunk az adatbázisban létrehozandó tábla nevét, továbbá, hogy annak hány mezője legyen. A Végrehajt gomb megnyomása után egy üres táblát kapunk. Felhívnám a figyelmet az ékezet nélküli betűk használatára, mely segítségével rengeteg hibát elkerülhetünk.

Miután elkészült az üres táblasémánk fel kell venni az egyes mezők nevét, típusát és hosszát, továbbá ki lehet jelölni, hogy a tábla mely mezője legyen elsődleges kulcs. A fitnessz termi példában az óra tábla óra_id nevű mezője az elsődleges kulcs.

A Ment nevű gomb megnyomása után létrejön az üres, adatok nélküli táblánk. Ha esetleg elfelejtkeztünk egy-két mezőről, azt könnyedén pótolhatjuk, mivel a Ment gomb mellett lehetőségünk van további mezők hozzáadására is. A hozzáadni kívánt mezők számának megadása után a Végrehajt gomb megnyomása szükséges, ekkor ahány mezőt megadtunk, annyit ír a rendszer még az előbbi táblához. Természetesen újabb mező hozzáadására a tábla létrehozása után is van lehetőség. A következő kép, amit látnunk kell, az egy SQL utasítás, valamit egy üres tábla szerkezeti képe.

- 64 -


A Beszúr fülre kattintva adatokat vihetünk fel a létrehozott táblába. Minden mezőnél meg kell adni a feltöltendő adatok értékét abban az esetben, ha NOT NULL volt mezőszintű megszorításnak megadva. Majd a Végrehajt gombra kattintva eltárolódik a táblában az új adat.

Abban az esetben, ha a táblában szereplő adatokat meg szeretnénk tekinteni, a bal oldali menüben ki kell választani a megfelelő tábla nevét, melynek Tartalom nevű fülére kattintva megjelennek a táblában tárolt sorok az alábbi módon.

- 65 -


Természetesen már rögzített adatok módosítására is van lehetőségünk. Az adott tábla változtani kívánt sorát az előtte álló kis dobozban kell kijelölni. A kijelölés után háromféle műveletet végezhezünk:   

Változtatás: a kis ceruza ikonra kattintva visszaléphetünk a Beszúr lépéshez, és itt módosíthatjuk a kívánt adatot. Törlés: A piros X ikonnal törölhetjük a tábla kijelölt sorát. Export: A tábla formájú ikonra kattintva megjelenik az Export fülön található SQL kérés, mely segítségével exportálni tudjuk a tábla adott sorát, vagy sorait egy fájlba.

Amint látható a PhpMyAdmin felületen számos feladatot el tudunk végezni, azonban ezeket nyílván nem használhatjuk, ha egy programozási nyelven keresztül szeretnénk az adatbázist módosítani. Ezért nagyon fontos, hogy megismerkedjünk az SQL nyelvvel. Abban az esetben, ha az SQL utasításokat ki szeretnénk próbálni, nem kell mást tennünk, mint az adott tábla SQL fülére kattintani. Ekkor megjelenik egy szövegdoboz, melybe a megfelelő SQL parancsot beírhatjuk, és a Végrehajt gomb segítségével futtathatjuk.

Lap tetejére

- 66 -


Az Access SQL felületének használata A legtöbb iskolában nincsen komolyabb adatbázis-kezelői környezet, ezért a Microsoft Office Access SQL felületét használják az SQL gyakorlására. Az Access alap felhasználásába nem folynék bele, hiszen azt, az adatbázis-kezeléssel kapcsolatos órák keretében már el kellett sajátítani. Hasonlóan az eddig tanultakhoz, létre kell hoznunk egy új, üres adatbázist, vagy meg kell nyitni egy korábban már elkészített adatbázist. Az adatbázisablak Lekérdezések/Queries lapján a felső nyomógombok közül az Új/New nyomógombbal kell új lekérdezés készítését kezdeményezni. Az Access által megjelenített ablakban ki kell választani a Tervező nézet/Design View lista elemet, majd az Ok gombra kattintani.

Ekkor az adatbázis-kezelő két ablakot jelenít meg, a Tábla hozzáadása/Add Table, és a Lekérdezés/Query ablakokat. A Tábla hozzáadása ablakot be kell zárnunk, és megmarad az interaktív lekérdezés ablaka. A Nézet/View menü SQL pontjával, vagy az eszközsoron a legelső kombinált lista SQL elemének segítségével lehet SQL nézetre átváltani.

Az SQL nézetben nem csak adatdefiníciós utasításokat, hanem lekérdezéseket, és adatmanipulációs utasításokat is végezhetünk. A szövegablakba az utasításokat begépelni, azokat javítani és törölni a szövegszerkesztőkhöz hasonlóan lehet. A begépelt utasításokat az eszközsor piros felkiáltójelű ikonjával lehet futtatni.

- 67 -


Az Adatlap nézetből/Datasheet-ből SQL nézetre visszaváltani szintén az eszközsor első kombinált listájának SQL elemével, vagy a Nézet/View menüvel lehet. A végrehajtott utasításokat a Fájl/File menü Mentés másként funkciójú menüpontjával lehet az általunk kiválasztott könyvtárba a kívánt néven menteni. A mentést követően a képernyő törlésével folytatható a munka az SQL felületen. Egyszerre csak egy utasítást lehet begépelni és végrehajtani. Az utasítás végére a pontosvessző elhelyezése nem kötelező. Magyarázó szöveg elhelyezésére és annak mentésére nincsen lehetőség az Access SQL felületén.

- 68 -


SQL