You are on page 1of 202

r .

i < />'i :
- ~- ' ' ,....

lváncsy Renáta

ADATBÁZISOK SZERVER OLDALI


PROGRAMOZÁSA

Műegyetemi Kiadó
!.Bevezetés Iváncsy Renáta

l. Bevezetés .................................................................................................................... 8
1. 1. Szoftverarchitektúrák ......................................................................................... 8
1.2. A szerver oldali programozás ................................................................ ........... 10
1.3. Kapcsolódás az adatbázishoz ........................................................................... ll
1.4. Adatbázis-kezelő rendszerek ............................................................................ 13
2. Az SQL nyelv áttekintése ......................................................................................... 20
2.1. Tábla létrehozása .............................................................................................. 20
2.2. Tábla törtése .............. ................. ......................................................... ............. 24
2.3. Tábla módosítása .............................................................................................. 24
2.4. Adatok lekérdezése táblából ............................................................................. 24
2.5. Új sor beszúrása táblába ................................................................ ................... 28
2.6. Sorok törtése táblából ....................................................................................... 28
2.7. Mezö módositása ........................... ..... .............................................................. 29
2.8. Nézet létrehozása .............................................................................................. 29
2.9. Nézet törlése ....................................................................... .............................. 30
2.1O. Nézet módosítása .............................................................................................. 30
2.11. Sor beszúrása nézetbe ....................................................................................... 30
2.12. Sor törtése nézetböl .......................................................................................... 31
2.13. Mezö módosítása nézetben ............................................................................... 31
2.14. Minta adatbázisok ............................................................................................ 31
3. A PUSQL áttekintése ............................................................................................... 44
3.1 . Blokkok ............................................................................................................ 44
3.2. Változók deklarálása, inicializálása, értékadása............................................... 46
3.3. Kurzorok ........................................................................................................... 47
3.4. Attribútumok ...................................................... .............................................. 47
3.5. Programvezérlő utasítások ............................................................................... 48
3.6. Modularitás ....................................................................................................... 48
3.7. Kollekciók (Collections) .................................................................................. 49
3.8. Objektumok ....................................................................................... ............... 49
3.9. Hibakezelés ...................................... .................................................... ............ 49
4. A PUSQL alapjai ..................................................................................................... 50
4.1. Karakterek ................................................... ................. ........................ ............ 50
4.2. Megjegyzések ................................................................................................... 50

3
!.Bevezetés lváncsy Renáta

4.3. Azonosítók ....................................................................................................... 50


4.4. Literálok ..................................... ...................................................................... 51
4.5. Változók., konstansok ..................................................................................... .. 51
4.6. Név konvenciók ................................................................................................ 53
4.7. Névelfedés ........................................................................................................ 54
4.8. Azonosítók hatásköre és láthatósága ................................................................ 55
4.9. Értékadás·········································································································· 56
4.1 O. Kifejezések és összehasonlitások .. ................................................... ................ 57
4.11. Beépített függvények ........................................................................................ 59
5. PUSQL programvezérlő utasítások ......................................................................... 60
5.1. Feltételes utasitások .......................................................................................... 60
5.2. Ciklusok ........................................................................................................... 63
6. PUSQL adattípusok ................................................................................................. 69
6.1. Előre definiált adattípusok ............................................................................... 69
6.2. LOB típusok ..................................................................................................... 71
6.3 . Programozó által definiált tipusok ....................................... ............................ 72
6.4. Adattipus konverzió ......................................................................................... 72
7. PUSQL összetett adattípusok .................................................................................. 74
7.1. A PUSQL rekord típus .................................................................................... 74
7.2. PUSQL tömb tipusok (varrays) ....................................................................... 77
7.3. PUSQL táblák .................................................................................................. 79
7.4. Az összetett adattípusok összehasonlitása ........................................................ 81
7.5. Metódusok táblákra és tömbökre ..................................................................... 82
8. PUSQL kurzorok ..................................................................................................... 83
8.1. Explicit kurzorok .............................................................................................. 83
8.2. Implicit kurzorok .............................................................................................. 86
8.3. Kurzorváltozók ................................................................................................. 87
8.4. Kurzor attribútumok ......................................................................................... 89
8.5. Kurzor kifejezések ............................................................................................ 91
9. PUSQL alprogramok ............................................................................................... 93
9 .l . PUSQL eljárások ............ .................................. ............................................... 93
9.2. PUSQL függvények ......................................................................................... 94
9.3. Alprogramok deklarálása ................................................................................. 96
9.4. Alprogramok paraméterezése ........................................................................... 96

4
l . Bevezetés Iváncsy Renáta

9.5. Paraméter módok ......................................................................................... ..... 97


9.6. Alprogram túlterhelés ....................................................................................... 99
l O. PUSQL hibák kezelése .......................................................................................... l 00
l 0.1 . A kivételek elkapása .......................................................................... ............. l 00
10.2. Elöre definiált kivételek ................................................................................. 102
10.3. Felhasználó által definiált kivételek ............................................................... 104
10.4. A kivételek láthatósága .................................................................................. 106
l 0.5. Nem előre definiált hibák ............................................................................... l 06
10.6. A RAISE_APPLICATION_ERROR ............................................................. l07
10.7. A kivételek terjedése ...................................................................................... 107
l 0.8. Hiba kód, hiba üzenet ........................................................................... .......... l 08
ll. PUSQL triggerek ...................................................................................... ............. ll O
11 .1. Tri gger DML utasításra .................................................................................. ll O
11 .2. Trigger adatbázis eseményre és DDL eseményre .......................................... 113
11.3. Triggerek futása .............................................................................................. 116
12. Tranzakciók PUSQL-ben ........................ ....................................... ....................... 117
12.1. Izolációs szintek ............................................................................................. 120
13. PUSQL csomagok (pack ages) ............................................................................... 128
13.1. A specifikáció ................................................................................................. l30
13.2. A csomag törzse ............................................................................................. 130
13.3. PUSQL előre definiált csomagok .. .. .............................................................. 133
14. A PUSQL objektum típusok .................................................................................. 138
14.1. Az objektum típus sttuktúrája ........................................................................ 139
14.2. Az objektum típus komponensei .................................................................... 140
15. PUSQLdinamikusSQL ........................................................................................ l45
16. A Transact-SQL alapjai ............................................. ...................... ....................... 148
16.1 . Kommentek .................................................................................................... l48
16.2. Azonosítók ..................................................................................................... 148
16.3. Konstansok ..................................................................................................... 149
16.4. Lokális változók ............................................................................................. 150
16.5. Értékadás változónak ........................................................................... ........... 151
16.6. Operátorok .................................................................... .................................. 151
17. T-SQL programvezérlő utasítások ......................................................................... 154
17.1. Blokkok definiálása, a BEGIN ... END ................ ............................................ 154

5
!.Bevezetés Iváncsy Renáta

17.2. A:z IF ... ELSE utasítás ..................................................................................... 154


17.3. A WHILE ciklus ............................................................................................. 155
17.4. AGOTO ......................................................................................................... l56
17.5. A RETURN .................................................................................................... 156
17 .6. RETURN integer_kifejezés ............................................................................ 157
17.7. A WAITFOR .................................................................................................. l57
17 .8. WAITFOR {DELAY idö l TIME idö} ........................................................... 157
17.9. A CASE ftlggvény .......................................................................................... l57
18. T-SQLadattipusok ................................................................................................. l6l
18.1. Adattípus precedencia (datatype precedence ) ............................................... 162
19. T-SQLkurzorok ..................................................................................................... 164
19.1. A kurzorok müködése .................................................................................... 164
19.2. A kurzor deklarálása ....................................................................................... 164
19.3. Akurzormegnyitása ...................................................................................... l66
19.4. A kurzor kezelése ........................................................................................... 167
19.5. A kurzor bezárása ........................................................................................... 168
19.6. A kurzor "elengedése" ................................................................................... 168
19.7. Kurzorváltozók ............................................................................................... l68
19 .8. Információk kurzorokról ................................................................................ 168
19.9. Módositások a kurzorban ............................................................................... 169
20. T-SQL tárolt eljárások ............................................................................................ 170
20.1. Tárolt eljárás létrehozása ................................................................................ 171
20.2. Tárolt eljárás futtatása .................................................................................... 172
20.3. Tárolt eljárások módosítása ............................................................................ 173
20.4. Tárolt eljárások törlése ................................................................................... 173
20.5. Információk tárolt eljárásról ........................................................................... 173
21. T-SQL ftlggvények ................................................................................................. l74
21.1. Beépített ftlggvények ...................................................................................... 174
21.2. Felhasználó által definiált ftlggvények ........................................................... 175
22. T-SQL triggerek ..................................................................................................... 181
22.1. Tri gger létrehozása ......................................................................................... 181
22 .2. Tri gger módosítása ......................................................................................... 184
22.3. Trigger törlése ................................................................................................ 184
23. T-SQL tranzakciók ................................................................................................. 185

6
!.Bevezetés lváncsy Renáta

23.1. Tranzakciómódok ........................................................................................... l85


23.2. Az explicit és az implicit tranzakciók ............................................................ 185
23.3. Izolációs szintek ............................................................................................. 187
23.4. Zárolások ..................................................... ................................................... 187
23.5. Holtpont kezelése ........................................................................................... 188
23.6. A hatékony tranzakció készítésszabályai ...................................................... 189
24. T-SQL hibakezelés ................................................................................................. 190
24.1. A hiba szerkezete ........................................................................................... 190
24.2. A sysmessages tábla ....................................................................................... 190
24.3. Az sp_addmessage ......................................................................................... 190
24.4. Az sp_al termessage ......... ............................................................................... 191
24.5. Az sp_dropmessage ........................................................................................ 191
24.6. A FORMATMESSAGE ................................................................................. l91
24.7. A @@ERROR fiiggvény ............................................................................... 192
24.8. A RAISERROR.............................................................................................. 192
25. SQL Server 2005 újdonságok ................................................................................ 195
25.1. Új adattípusok ................................................................................................ 195
25.2. T-SQL nyelvi fejlesztések .............................................................................. 196
25.3. Hibakezelés .................................................................................................... 199
25.4. DDL triggerek ................................................................................................ 200
26. Irodalom jegyzék ................................ ....................... ..... ........................................ 203

7
! .Bevezetés Iváncsy Renáta

l. Bevezetés
Az SQL (Structured Query Language) segítségévellehetőségünk van adatbázis struktúrák
(táblák. nézetek, szekvenciák stb.) létrehozására. az adatbázis struktúrákban adatok tárolására,
illetve számunkra lényeges, valamilyen feltételnek megfelelő adatok kinyerésére. Egyszóval
lehetőségünk van az adatbázisban található adatok manipulálására. A hatékony
adatfeldolgozás azonban ennél többet igényel. Gyakran nem elég az adatok szekvenciális
feldolgozása, szükség lehet ciklusok szervezésére, feltételek definiálására. komolyabb
programok eselén pedig felmerül az igény az egyes logikailag összefilggö programrészek
elkülönítésére. Szükség lehet filggvények, eljárások definiálására, melyeket késöbb több
helyen is meg lehet hívni. Egyszóval felmerül az igény olyan támogatás iránt, amilyet a
procedurális nyelvek nyújtanak.
Az adatbázisok szerver oldali programozása az adatbázis-kezelő rendszer által nyújtott
procedurális programozási nyelven történő programozást jelenti. A legtöbb adatbázis-kezelő

rendszer támogatja ezt a lehetőséget. A szerver oldali programozás lényegében tárolt


eljárások, filggvények és triggerek írását jelenti.
Az ,,Adatbázisok szerver oldali programozása" cimü tárgy keretén belül két nagy
adatbázis-kezelő rendszer szerver oldali programnyelvével ismerkedünk meg, az Oracle l Og
PUSQL nyelvével, valamint a Microsoft SQL Server 2000 Transact-SQL nyelvével, melynek
2005-ös kiegészítéséről külön fejezet szól.
A tárgy először röviden ismerteti a szoftverarchitektúrák formáit, hogy azon belül
könnyebben elhelyezhessllk az adatbázis szerver oldali programozásának szerepét. Aztán
áttekintjük az SQL nyelv legfontosabb és leggyakrabban hasmált elemeit, valamint a tárgy
keretein belül megtartott gyakorlatokon hasmált minta adatbázisok felépítését. Az
adatbázisok szerver oldali programozásának lehetőségeinek bemutatását a PUSQL nyelvvel
kezdjük, amit a T-SQL nyelv ismertetése követ.

l.l.Szoftverarcbitektúrák
Az adatbázisok használata napjainkra már igen alapvető igénnyé vált az élet számos
területén. Adatbázisra épülnek egyebek közt a vállalati, banki, egészségügyi információs
rendszerek, az egyetemi hallgatói nyilvántartó rendszerek, az áruházláncok nyilvántartó
rendszerei, már a fodrászatban is adatbázisban tárolják a vendégek hajkezeléséhez szolgáló
információkal. Az adatbázisok széleskörü felhasmálása különbözö igényeket támaszt az
adatbázis-kezelő rendszerrel szemben. Kis alkalmazások esetén az adatbázisban ezres,

8
! .Bevezetés Iváncsy Renáta

maximum százezres nagyságrendű rekordszám fordul elő, és a kiszolgált kliensek száma is


alacsony. Ehhez képest egy nagyvállalati rendszerben több millió rekordot kell tárolni, és
egyszerre akár több száz klienst is ki kell tudni szolgálni. Ezen különbségek miatt a
szaftverrendszerek különbözö architektúrák szerint kerülnek kialak.ításra. A két
legelterjedtebben használt szaftverarchitektúra a kétrétegű (kliens-szerver) és a három- vagy
többrétegű architektúra.
A kétrétegű architektúra az adatbázisok., és az alkalmazások rétegére oszlik. A két réteg
általában fizikailag is külön számítógépen van, az adatbázisok egy szerveren kerülnek
elhelyezésre, ami biztosítja az adatbázis-kezelő rendszer számára az erőforrásokat. A
kliensalkalmazások az adatbázist a hálózaton keresztül érik el. Az adatbázis réteg tartalmazza
az adatok struktúráját, magukat az adatokat, és a fenntartásukhoz és kezelésükhöz sz:Okséges
eszközöket. A kétrétegű architektúra előnye, hogy központilag felügyelhetö, mig a kliensek
különbözö módon fejleszthetők., valamint a kommunikációs költsége is kisebb, mint a késöbb
bemutatásra kerülö három és több rétegű architektúráknak., hiszen adatoknak csak a két réteg
között kell áramolnia. Hátránya, hogy az adatbázis felépítésének változtatása esetén a
kliensekben is lényeges változtatásokat kell tenni. Ez a probléma csökkenthető tárolt eljárások
használatával, amelyekkel biztosítható az adatok és az alkalmazások fiiggetlensége.
A háromrétegű architektúra esetén a három réteg az adatbázis, a fogalmi réteg és az
alkalmazások. Ebben az esetben, az adatbázis rétegben csak az adatok., és a hozzájuk szorosan
kapcsolódó funkciókat megvalósító program elemek kerülnek tárolásra. A fogalmi rétegben
található az üzleti logika, ezért szokás ezt a réteget az üzleti logika rétegének (Business Logic
Layer - BLL) nevezni. Bizonyos esetekben ezt a réteget további rétegekre osztják, így
alakítva ki az N-rétegű architektúrát. Dyen további réteg lehet például az adat elérési réteg
(Data Access Layer - DAL). Az alkalmazások rétege többségében csak a megjelenítéssel
kapcsolatos funkciót látja el, ezért szokás ezt a megjelenítési rétegnek (Presentation Layer -
PL) is hívni.
A háromrétegű architektúra előnye a kétrétegűvel szemben, hogy a háromrétegű

architektúra esetén a szoftver módosítása sokkal rugalmasabb. Az egyes komponensek cseréje


könnyebben megoldható. A középsö vagy az adatbázis rétegben történő változtatások nem
feltétlen érintik a klienseket A középsö réteg segítségével megoldható, hogy az alkalmazás
adatbázis fiiggetlen legyen, ilyenkor azonban kerülni kell a tárolt eljárások használatát, hiszen
azok - mint ahogy azt késöbb látni fogjuk - adatbázisftlggők. Három rétegű architektúra
esetén a rendszer teljesítménye nö, skálázhatóvá válik.

9
l .Bevezetés Iváncsy Renáta

1.2.A szerver oldali programozás


Az adatbázisok szerver oldali programozása az adatbázis rétegben történő programozást
jelenti. A korszeru adatbázis kezelő rendszerek lehetövé teszik olyan program részletek
tárolását az adatbázisban, amelyek szorosan az adatok kezelésével foglalkoznak. A
legalapvetöbb szerver oldali elemek a tárolt eljárások. a filggvények és a triggerek. Az
eljárások általában müveletek elvégzésére szolgálnak, a filggvények értékek kiszámítására. A
triggerek a szerveren történt valamilyen esemény hatására automatikusan lefutó tárolt
eljárások.
A továbbiakban a szerver oldalon az adatbázis szervert értjük, kliens oldalon pedig az
adatbázishoz képest kliensként szereplö rétegeket (három rétegü architektúra esetén a középsö
réteget). A szerver oldali programozásnak vannak előnyei és hátrányai a kliens oldali
programozással szemben. Az alábbiakban ezeket vesszük sorra.

1.2.1. A szerver oldali programozás előnyei:


Teljesítmény
A tárolt eljárások egyszer kerülnek lefordításra, és futtatható formában kerülnek tárolásra,
így az eljáráshívás gyors és hatékony. A futtatható kód a felhasznáJók közt megosztásra kerül,
így csökkentve a memória szükségletet. Az SQL utasítások csoportba rendezésévellehetőség

nyílik ezen utasítások egyetlen hívással történő futtatására, ezzel csökkentve a hálózati
forgaimat Szintén a hálózati forgaimat csökkenti, ha a nagy adathalmazon történő müveletek
a szerver oldalon kerülnek elvégzésre, mivel így nem kell a nagy adathalmazt átküldeni a
hálózaton. A tárolt eljárások a szerveren futnak, így a szerver kerül terhelésre és nem a kliens.
Produlaivitás és könnyú használat
Amennyiben az alkalmazás tárolt eljárások alapján készül el, úgy el lehet kerülni a
redundáns kódolást. ezzel növelve a produktivitást. A tárolt filggvények SQL-böl történő

hívásával ki lehet terjeszteni az SQL lehetőségeit.

A tárolt eljárás segítségével az üzleti logikát meg lehet osztani a k:ülönbözö alkalmazások
között. Például egy tárolt eljárás, ami egy üzleti szabályt implementál k:ülönbözö olyan
kliensalkalmazásokból meghívható, amik ezt az üzleti szabályt alkalmazzák.
Karbantarthatóság
Mivel a tárolt eljárás a szerveren kerüJ tárolásra, olyan módosítás esetén, ami a tárolt
eljárás interfészét nem érinti, nem kell a kliens kódhoz hozzányúlni, elég a szerveren újra
fordítani a módosított eljárást.

10
! .Bevezetés lváncsy Renáta

Biztonság
Tárolt eljárások használatával több lehetőség nyílik a jogosultásogok kezelésére.
Megoldható, hogy egy adott felhasználó az adatokat csak a tárolt eljárásokon keresztül érje el.
Például egy tárolt eljáráson keresztül a felhasználó módosíthat egy táblát, noha a tárolt eljárást
futtató felhasználónak magára a táblára semmilyen joga nincs.

1.2.2. A szerver oldali programozás hátrányai


Nem szabványos
A szerver oldali programozás egyik legnagyobb hátránya, hogy nem szabványos.
Egyrészt egyelőre még nem minden adatbázis kezelő rendszer biztosítja ezt a funkciót,
például a MySQL 3.23-as verziója még egyáltalán nem teszi lehetövé a tárolt eljárások írását.
Másrészről azok az adatbázis kezelők. amik lehetövé teszik a szerver oldali programozást,
teljesen más nyelvet alakítottak ki erre a célra, és eltérő mértékben támogatják a különböző

funkciókat. Az Oracle szerver oldali nyelve a PUSQL, a Microsoft SQL Server 2000-é a
Transact-SQL, a DB2 az SQL PL-t használja.
Nem hordozható
A szerver oldali programozási elemek (tárolt eljárások. ftlggvények. triggerek) a
szerveren kerülnek eltárolásra. Ha a szoftver rendszer alá egy másik adatbázis-kezelőt kell
tenni, akkor a szerver oldali elemeket át kell migrálni az egyik adatbázis kezelőröl a másikra.
Ez gondot jelenthet abban az esetben, ha a két adatbázis-kezelő nem azonos, hiszen azok nagy
valószínűséggel más-más nyelvet támogatnak. Oyen formán a szerver oldali elemek nem
hordozható ak.
Teljesítmény
Teljesítmény szempontjából a szerver oldali elemek használata nem csak elöny lehet, de
akár hátránnyá is válhat. Bizonyos esetekben teljesítmény szempontjából jobb megoldás a
bonyolultabb funkciókat a középsö rétegben megvalósítani. Így nem az adatbázis szerver lesz
terhelve, és skálázhatóbbá is válik a rendszer.

1.3.Kapcsolódás az adatbázishoz
A kliens oldalról az adatbázishoz különböző technológiák segítségével lehet csatlakozni.
Ezek a technológiák többek között az ODBC, OLE DB, ADO valamint a JDBC. Mindegyik
technológia lényege, hogy egy réteget képezzen az adatbázis és a kliensalkalmazás között,
amely eltakruja az alkalmazás elöl az adatbázis specifikus részeket.

ll
! .Bevezetés Jváncsy Renáta

Az ODBC (Open Database Connectivity) egy alkalmazás programozói interfész


(Application Proggramming Interface - API) olyan alkalmazások számára, amelyek SQL
utasítások segitségével akarják elérni az adatbázist. Az ODBC esetén a hangsúly a
hordozhatóságon van, cél volt. hogy a forráskód változtatása nélkül lehessen a különböző
adatbázisokhoz csatlakozni. Az ODBC két réteget tett az adatbázis és az alkalmazás közé, ez
egyrészt a meghajtó menedzser (driver manager) másrészt maguk az adatbázis meghajtók
(database driver). Az adatbázis meghajtók konvertálják az általános ODBC kéréseket
adatbázis specifikus kérésekké. Minden egyes adatbázis kezelőhöz külön meghajtót kell
létrehozni. Az adatbázis alkalmazás ODBC hívásokon keresztül SQL utasításokat küld, és
fogadja a lekérdezések eredményeit. Az ODBC meghajtó menedzser (ODBC driver manager)
aktivizálja a megfelelő meghajtót és feldolgozza az ODBC hívásokat. Az ODBC meghajtó
(ODBC driver) felállítja a kapcsolatot az adatbázissal, lekérdezéseket küld az adatbázis felé,
adatokat más adattipusokká konvertál, ha szükséges és az eredményt szolgáltatja az
alkalmazás felé.
Az OLE DB egy komponens alapú adatbázis elérési megoldás Windows C és C++-
programok számára.[12] Az OLE DB a Microsoft egy rendszer szintü interfésze, aminek
segitségével különféle adatforrásokhoz kapcsolódhatunk. Az OLE DB Microsoft COM
(Component Object Model) objektumok interfész halmazát specifikálja, ami különböző

adatbázis-kezelő rendszerszolgáltatásokat foglal magába. Mig az ODBC-t kifejezetten


relációs adatbázis kapcsolatokhoz fejlesztették ki, addig az OLE DB kapcsolatot tud nyújtani
mind relációs mind nem relációs adatforrásokhoz.
Az ADO (ActiveX Data Object) egy objektum réteg az OLE DB felett, ami adatbázis
elérést biztosít olyan nyelveknek. amik nem kezelnek mutatókat. mint például a Visual Basic
és a script nyelvek (pl. JavaScript, VBScrit). Az ADO egy szolgáltató semleges, alkalmazás
szintü adatbázis kapcsolat objektum modell. Noha az OLE DB hathatós interfészt nyújt az
adatok kezeléséhez, nem minden programozó szeretné az alkalmazásában az adatbázis-
kezelést alacsony szinten megvalósítani. Másrészről sokan jobban kedvelik a Visual Basicet
vagy a script nyelveket a C++--nál, amik nem kezelnek mutatókat, így igény volt egy
magasabb szintü kapcsolatot biztosító réteg kidolgozására. Ezért fejlesztették ki az ADO-t. Az
ADO könnyü használhatóságot biztosít, filggetlen a programozási nyelvtől, bármilyen OLE
DB forráshoz tud csatlakozni, mindemellett nem veszti el az OLE DB által nyújtott
lehetőségeket. a C++- programozók elérhetik az alacsonyszintü OLE DB funkciókat is.
A JDBC több rétegben van megvalósítva. A meghajtó kezelő (DriverManager) és az
adatbázis specifikus meghajtó a Java beépített része, ezért programozónak csak a kapcsolat

12
! .Bevezetés lváncsy Renáta

(Connection), utasítás (Statement), és eredmény halmaz (ResultSet) objektumokkal kell


foglakoznia. A kapcsolat objektumban kell beállitani, hogy melyik adatbázishoz szecetnénk
kapcsolódni, milyen felhasználóként, stb. Egy prograrnon belül több adatbázis kapcsolatot
lehet létesíteni egy vagy akár több adatbázis-kezelő rendszerrel. Természetesen az adatbázis-
kezelő rendszerek lehetnek különbözö cégek termékei is. A kapcsolat objektum nem más,
mint egy nyitás, amelyen keresztül a program adatbázis szolgáltatást kér, és kap. Az utasítás
objektum tartalmazza az adatbázis-kezelő rendszer által végrehajtandó utasításokat. A
lekérdezések eredményét az eredmény halmaz objektum tartalmazza.

1.4.Adatbázis-kezelő rendszerek
Napjainkban a szoftver piacon számos adatbázis-kezelő rendszer létezik. Ezek a
rendszerek különbözö tulajdonságokkal rendelkeznek funkcionalitás, teljesítmény és ár
szempontjából egyaránt. A legelterjedtebb adatbázis kezelök az Oracle, a Microsoft SQL
Server 2000, az ffiM DB2 valamint a MySQL. Ezen kívül még számos adatbázis-kezelő

létezik. mint például a Sybase, az lnformix, a Microsoft Access stb., ezekkel azonban idő és
hely hiányában nem foglalkozunk.
Az egyes adatbázis kezelöknek számos változata létezik. amelyek közül bizonyosak
teljes, mások korlátozott funkcionalitással rendelkeznek. Az alábbi táblázat az egyes
adatbázis-kezelő rendszerek közelitö árát mutatják.
Microsoft SQL Oracle9i ffiMDB2 MySQL
Server 2000 Venion 8.1 3.23
Enterprise Edition $19 999 us $40 OOO US $25 OOO US $400 us
az EE változat
DataMining $20 OOO US $60 OOO US nincs
tartalmazza
az EE változat
OLAP
tartalmazza
$20000 us $28 OOO US nincs
Standard Edition $4 999 us $15 OOO US $7 500 us $200 us
1.4.1. Az OraclelOg
A tárgy első felében az Oracle adatbázis kezelő rendszer szerver oldali programozásával
fogunk foglalkozni . Ennek jobb megértése érdekében nézzük meg, hogy hogyan lehet röviden
jellemezni az OraclelOg adatbázis kezelőt

Az OraclelOg architektúrája
Az Oracle adatbázis valamilyen szempontból összetartozó elemek gyűjteménye. Az
adatbázisnak logikai és fizikai struktúrája van. Mivel ez a két struktúra egymástól elkülönül,
ezért a fizikai struktúra anélkül kezelhetö, hogy a logikai struktúrát a módosítások érintenék.

13
l.Bc:vc:zetés Iváncsy Renáta

A logilclli stnllctÍirll
Az Oracle logikai struktúrája a következö elemeket tartalmazza:
• séma objektumok,
• adat blokkok,
• extentek,
• szegmensek
• és táblahelyek.
A séma
A séma adatbázis objektumok gyűjteménye. Egy séma egy adatbázis felhasználó
tulajdonában van, és a séma neve megegyezik a tulajdonosának a nevével. A séma táblákat,
nézeteket, indexeket tartalmazhat.
Az adat blokJcok, extentek és szegmensek
Az adat blokkok, extentek és szegmensek használatával az Oracle-nek lehetősége van a
diszk hely használat finom hangolására.
Az 110 müveletek szempontjából legalacsonyabb szinten helyezkednek el az adat
blokkok. Egy adat blokkhoz megadott számú fizikai hely tartozik. A logikai struktúra
következő szintje az extent. Az extent megadott számú egymás mellett elhelyezkedő

adatblokkból áll. Az extent megadott típusú információ tárolására szolgál.


A legfelső szinten található a szegmens. A szegmens extentek halmaza, amiket
meghatározott logikai struktúra tárolására használnak. llyen szegmensek lehetnek az adat
szegmens, az index szegmens, az átmeneti szegmens és a rollback szegmens. Amikor egy
szegmens betelik, az Oracle automatikusan foglal helyet a szegmenshez tartozó következö
extentnek. Mivel az extent foglalás dinamikus, ezért az extentek fizikailag nem feltétlenül
egymás mellett helyezkednek el a diszken.
A táblahelyek
Az adatbázis táblahelyeknek nevezett logikai egységekre van bontva. Egy táblahely
összetartozó logikai struktúrákat, a szegmenseket gyűjti csoportba. Az adatbázisok,
táblahelyek és adatfájlok viszonyát a következö ábra szemlélteti:

14
! .Bevezetés Iváncsy Renáta

Database
:-S;s~t~ T~b~e:pa~~~- - -: :-U;E~~ T~b~es~a~e- - -
l l l
l l
l l
OATA1 .0RA OATA2.0RA l l
1111b 1Mb
l l
l l
L ___ _ ______ IL __________ I

Látható, hogy egy adatbázis egy vagy több táblahelyből állhat. Minden táblahelyhez
létrehozásra kerül egy vagy több adatfájl az adatok tárolásához.
A jiz)klli struktflr11
Minden Oracle adatbázis egy vagy több adatfájlt tartalmaz. Az adatfájl tartalmazza az
összes adatbázis adatot.
Az adatfájlok mellett van kettő vagy több redo log fájl. A redo log fájlokban kerülnek
naplózásra az adatbázisban történt adat módosftások
Minden Oracle adatbázis rendelkezik egy control fájllaL A control fájl olyan
információkat tartalmaz, ami meghatározza az adatbázis fizikai struktúráját. Például a
következő információkat tartalmazza:
• Adatbázis név
• Az adat és redo log fájlok nevei és helyei
• Az adatbázis létrehozásának ideje
Az lllllltszóúir
Minden Oracle adatbázishoz tartozik egy adat szótár (data dictionary). Az adatszótár
olyan csak olvasható táblák és nézetek referenciáinak halmaza. amelyek az adatbázisról
tartalmaznak információkat Tartalmaz például adatokat az adatbázis fizikai és logikai
struktúrájáról. Ezen kivül a következő adatokat is tartalmazza:
• Az adatbázis felhasználói
• Információk a táblák számára definiált integritás megkötésekről
• Információk a sémákról (táblák, nézetek stb).
Az adatszótár akkor jön létre, amikor az adatbázis létrehozásra kerül, és automatikusan
fiissftödik.
Az alábbi példa lekérdezi az aktuális felhasználó tábláinak nevét:
l SELECT table name FROM user tables;

15
l .Bevezetés lváncsy Renáta

Az IUÜJibtízis péükíny
Minden futó Oracle adatbázis hozzá van rendelve egy Oracle példányhoz (instance).
Amikor elindul egy adatbázis az adatbázis szerveren, az Oracle memóriát foglal magának
(globális rendszer tér -System Global Area - SGA) és elindit egy vagy több folyamatot. Az
Oracle példány nem más, mint ez a memóriaterület (SGA) és a folyamatok összessége.
Amikor elindftunk egy példányt, akkor az Oracle összerendeli a példányt a megadott
adatbázissal. Ezt az adatbázis csatolásának (mounting) hívják. Egy gépen több példány is
futhat, melyeknek saját fizikai adatházisuk van.
Biztonság
Az Oracle adatbázisban léteznek rendszer és séma jogosultságok. A rendszer
jogosultságok azt határozzák meg, hogy milyen rendszer szintű müveleteket hajthat végre a
jogosultsággal rendelkező felhasználó. llyen müvelet lehet például táblahely létrehozása, új
felhasználó felvétele az adatbázisba stb. Több, mint 60-féle különbözö rendszer jogosultság
van. A séma jogosultságok különbözö séma objektumokon végezhető müveleteket
engedélyeznek. vagy tiltanak meg felhasználóknak. llyen objektumok a következők :
• Tábla
• Nézet
• Szekvencia
• Eljárás
• Függvény
• Csomag
A különbözö objektumokra más-más jogosultságok vannak definiálva. Például egy
táblára beszúrási jogosultságot adhatunk. egy tárolt eljárásra futtatási jogot stb.
Szerepek
A különbözö jogosultságok könnyebb kezelésére be lehet vezetni szerepeket (roles). Egy
szerep definiálásakor meg kell adni, hogy az adott szerep milyen rendszer és séma szintű

jogosultságokkal rendelkezik. Ezek után az egyes felhasználókat szerepekhez lehet


hozzárendelni. A szerep jogosultságának változtatásakor az összes hozzá rendelt felhasználó
jogosultsága egyszerre változik, igy spórolva meg az egyenkénti változtatás kényszerét Egy
szerephez nem csak felhasználókat lehet rendelni, hanem másik szerepeket is.

16
).Bevezetés I váncsy Renáta

Támogatott operációs rendszerek


Unix
Linux
Windows 9x, NT, 2000, XP
Mac OS X Server
SunOS 4.x

1.4.2. A Microsoft SQL Server 2000


A tárgy második felében a Microsoft adatbázis kezelő rendszerével, az SQL Server 2000-
rel foglalkozunk.
AMS SQL Server 2000 arcbitektúrája
Az MS SQL Server 2000 esetén is lehetöség van több példányt létrehozni egy gépen
belül. Ilyenkor a két példány teljesen független egymástól. Egy alkalmazás, ami az egyik
példányhoz csatlakozott nem érheti el a másik példányon található objektumokat, kivéve
elosztott lekérdezések esetén.
Az SQL Server példányon belül az objektumok (táblák, nézetek, indexek stb.)
adatbázisok szerint kerülnek csoportosításra (Oracle esetén egy példányon belül nincs több
adatbázis, ott az objektumok felhasznáJók szerint kerülnek logikai csoportosításra).
Minden egyes szerver példányon alapvetően négy rendszer adatbázis (master, model,
tempdb, és msdb) van és egy vagy több felhasználói adatbázis.
• A master adatbázis tartalmazza az összes rendszer szintü SQL Server információt.
Ez tartalmazza a felhasználókat, és núnden rendszer konfigurációs beállítást. A
master adatbázisban kerül eltárolásra az összes többi adatbázis helye és az SQL
Server inicializációs adatai.
• A tmpdb tárolja az átmeneti táblákat és tárolt eljárásokat.
• A model adatbázis az újonnan létrehozandó adatbázisok núntájaként szerepel.
• Az msdb adatbázist az SQL Server Agent használja figyelmeztetések és munkák
ütemezésére.

17
!.Bevezetés lváncsy Renáta

SQL Szarver

Rendszer adatbézlsolt Felhaszrlélói adatbázisok

Az adatbázisok két vagy több fájlként kerülnek eltárolásra a diszken. Egy adatbázishoz
tartozik egy adat fájl (.mdf vagy .ndf) valamint egy log fájl (.ldf). Az adatfájl extentekre
bontható, ami 8 folytonos 8K.b-os lapot tartalmaz.
Az SQL szerveren is lehetőség van a rendszerben tárolt adatokról információk szerzésére,
erre a rendszer tárolt eljárások szolgálnak, amiknek előtagja az "sp". Például az "aszp" nevü
felhasználó tábláinak nevét a következő módon kérdezheljük le az adatbázisból:
l exec sp tables @table owner = 'aszp';
Biztonság
Az SQL Serveren a felhasználóknak létre kell hozni egy Iogint. Az adatbázisban az
autentikáció történhet operációs rendszer szinten vagy adatbázis szinten. Az egyes loginokat
különbözö adatbázisokhoz lehet rendelni . Egy adatbázist az a felhasználó használhatja, aki
hozzá van rendelve.
Az SQL Serveren, hasonlóan az Oracle-hez, lehetőség van az egyes felhasználóknak
különbözö rendszer és objektum szintü jogosultságokat adni, illetve megvonni. Ezen kívül
lehetőség van a szerepek definiálására is.
Támogaton operációs rendszerek
l Windows 9x, NT, 2000, XP
AziBMDB2
Az IBM DB2 adatbázis kezelő rendszer architektúrája két szintre bontható. Egyrészt
lehetőség van kalönbözö példányok létrehozására, mely példányok egymástól függetlenül
mü.ködtethetők., adminisztrálhatók és karbantarthatók. Minden példányon belül lehetőség van
egy vagy több adatbázis létrehozására.

18
].Bevezetés Iváncsy Renáta

A DB2-ben is definiáltak a következő logikai és fizikai objektumok:


• Táblák., nézetek, indexek, sémák
• Zárak, triggerek, tárolt eljárások, csomagok
• Butfer poolok, log fájlok és táblahelyek.
Biztonság
A DB2-ben a felhasznáJók autentikációja operációs rendszer szintű . Az egyes
felhasználóknak lehet adni rendszer szintű szerepeket, és objektum szintű jogosultságokat.
Egyéb szerepeket is létre lehet hozni, hasonlóan az Oracle-hez és az SQL Server 2000-hez.
Támogatott operációs rendszerele
Unix
Linux
Windows 9x, NT, 2000, XP
SunOS 4.x

!9
2.A:z SQL nyelv áttekintése Iváncsy Renáta

2. Az SQL nyelv áttekintése


Az SQL (Structured Query Language) egy ANSI szabvány adatbázisokban tárolt adatok
elérésére és kezelésére. Az SQL nyelv segitségével van lehetőségünk egyszerűen beszúrni,
módosítani vagy törölni adatokat az adatbázisban. Az SQL nyelv szabványosított változata az
SQL-92. Az egyes adatbázis-kezelő rendszerek azonban kialakították a saját SQL
kiterjesztésüket. A szabványt általában m.indenk:i támogatja, de ahhoz képest számos
bővítéssel rendelkeznek. Az alábbiakban főleg az Oracle és a Microsoft SQL Server 2000
SQL nyelvének metszetének lényegesebb részeit ismertetjük, néha kitérve az egyes adatbázis-
kezelök sajátosságaira.
Az SQL nyelv utasításait három nagy csoportba osztjuk, a DDL (Data Definition
Language) utasításokra, a DCL (Data Control Language) utasításokra és a DML (Data
Manipulalion Language) utasításokra. Az első csoportba tartoznak az olyan utasítások.
amikkel új adatbázis objektumokat lehet létrehozni, mint például új táblákat. nézeteket,
indexeket stb. A DCL utasítások között szerepeinek a jogosultságot kezelő utasítások, mint pl.
a GRANT vagy a REVOKE. A DML utasítások az adat módosító utasítások, m.int az
INSERT, UPDATE, DELETE utasítások. A SELECT utasítás szolgál az adatbázisból történő

információ kinyerésére. Egyes helyeken a SELECT az SQL csoportosításának negyedik


csoportját alkotja, a DQL-t (Data Query Languge).

2.1. Tábla létrebozása


A táblák az adatbázis azon objektumai, amik az adatokat tartalmazzák. A tábla alapvetöen
oszlopokból és sorokból áll. Minden egyes sor egy egyedi rekordot reprezentál, és minden
egyes oszlop a rekord egy mezöje. A tábla létrehozásának általános szintaktikája a következő:
CREATE TABLE táblanév
(
{oszlop definicióltábla szintG megkötés}(, _ ]

A tábla létrehozása során az oszlopok definícióit kell megadni egymás után, vesszövei
elválasztva. Az oszlop definícióján kivül lehetőség van tábla szintü megkötések definiálására
is. Az alábbiakban az oszlop definíció és a tábla szintü megkötés szintaktikáját újuk le.

2.1.1. Oszlop defmició


Egy táblában minimum szerepelnie kell egy oszlopdefiníciónak, és ezt követően,

vesszövei elválasztva bármennyi egyéb, a fenti szintaktikában szereplö elemnek. Az oszlop

20
2.Az SQL nyelv áttekintése Iváncsy Renáta

definíció az oszlop nevén és típusán túl tartalmazhat különböző megkötéseket. Az oszlop


definíció szintaktikája a következő:
Oszlopnév típus [DEFAULT érték) [oszlop szintú megkötések]
Az oszlop nevének meghatározása után meg kell adni annak típusát. Az oszlop típusának
az adatbázis-kezelő által támogatott típusok közül kell kikerülnie. Az egyes típusok a
k:ülönbözö adatbázis-kezelő rendszerekben eltérnek. de általában elmondható, hogy vannak
numerikus típusok (pl. integer, number, decimal stb.), karakteres típusok (pl. char, varchar),
dátum tipusok (date) valamint nagy objektumok tárolására szolgáló tipusok.
Az opcionális DEFAULT kulcsszó használatával alapértelmezett értéket rendelhetünk az
oszlopnak. Abban az esetben, ha egy új sor bevitelekor ez az oszlop nem ketill kitöltésre,
akkor a tábla létrehozásakor az alapértelmezett érték kerül beszúrásra.
Az SQL Server esetén az IDENTITY kulcsszó segítségével egy soronként folyamatosan
növekvő, egyedi értéket rendelhetünk az oszlophoz. Az IDENTITY kulcsszóval megjelölt
oszlop típusa tinyint, smallint, int, bigint, decimal(p,O) vagy numeric(p,O) lehet. Egy táblában
csak egy mezőt jelölhetünk meg IDENTITY kulcsszóval. Az IDENTITY meghatározásakor
meg lehet határozni a kezdőértéket és a növekményt, de vagy mindkettő értéket
meghatározzuk, vagy egyiket sem. Ha nem adjuk meg az értékét, akkor alapból (l, l) lesz. Az
IDENTITY kulcsszóval ellátott oszlop általában elsődleges kulcsként szokott szerepelni.
Ennek segítségével lehet megoldani az automatikus azonosító generálást egy táblában. Az
IDENTITY kulcsszó nem szerepelhet együtt a DEFAULT kulcsszóval, hiszen nem lehet egy
konkrét alapértelmezett értéke, mert az értékét az SQL Server generálja.
Az Oracle-ben nincsen lehetőség egy oszlop automatikusan növekvő értékkel való
definiálására. Ehelyett a sequence nevü objektumot lehet használni, aminek segítségével a
táblába való beszúráskor lehet azonosítót generálni a táblához.
Az oszlop szintü megkötések szintaktikája a következő:
[CONSTRAINT megkötésnév)
{[NULLINOT NULL]
[ {PRIMARY KEY l UNIQUE} ]
[ [FOREIGN KEY] REFERENCES hivatkozott táblanév
[(hivatkozott_oszlopnév))
[ON DELETE {CASCADE l NO ACTION}]
[ON UPDATE {CASCADE l NO ACTION}]

CHECK {logikai kifejezés}


}
Az oszlop szintü megkötés opcionálisan kezdőrlhet a CONSTRAINT kulcsszóval, ami
után meg kell adni egy nevet, ami a megkötés neve lesz. Érdemes élni ezzel a lehetöséggel,

21
2.Az SQL nyelv áttekintése lváocsy Renáta

mert a későbbiekben hasznos lehet, ha pontosan tudjuk, hogy melyik megkötés miatt hiúsult
meg az utasításunk. Amennyiben nem adunk meg nevet, az Oracle és az MS SQL Server is
egyedi névvellátja el a megkötést
A NULL lrulcsszó segitségével megadhatj uk, hogy egy oszlop felvehet NULL értéket. Ez
az alapértelmezett. A NOT NULL lrulcsszóval megtilthatjuk, hogy NULL értéket vegyen fel
egy oszlop. Ebben az esetben az adott oszlopnak mindig meg kell adni értéket beszúrás
esetén, kivéve, ha rendeltünk hozzá alapértelmezett (DEFAULn értéket.
Az oszlopot elsődleges lrulcsként definiálhatjuk, ha a PRIMARY KEY lrulcsszó kerül
mögé. Ebben az esetben a táblán belül az adott oszlopban az értékek egyediek, és nem
vehetnek fel NULL értéket. Ha a UNIQUE kulcsszót használjuk, akkor szintén biztosítjuk az
egyediséget, viszont az oszlop értéke lehet NULL is. Az egyediség a nem NULL értékű

oszlopokra van biztositva. A PRIMARY KEY és a UNIQUE megkötés egy oszlopra


egyszerre nem használhatóak. Ha egy oszlop elsődleges Irulesként kerül definiálásra, vagy
egyedinek, akkor a rendszer automatikusan létrehoz egy indexet az adott oszlopra. Egy táblán
belül egyszerre csak egy elsődleges lrulcs lehet, de több egyedi megkötéssel rendelkező

oszlop is lehet.
A REFERENCES kulcsszó után adható meg, hogy az adott oszlop melyik tábla mely
mezőjére hivatkozzon, mint idegen kulcs. Az ON DELETE megkötéssel megadható, hogy mi
történjen az idegenlrulcsként meghatározott mező értékével, ha a hivatkozott mező törlésre
kerül. A CASCADE lrulcsszó használata esetén a hivatkozó tábla megfelelő sora törlődik, ha
a hivatkozott sor törlésre kerül. A NO ACTION lrulcsszó használata esetén a szerver hibát
generál, és a hivatkozott táblában történt törlést visszagörgeti, azaz nem törli ki az adott sort,
mert még van rá hivatkozás az adatbázisban. Az ON UPDATE megkötéssel megadható, hogy
mi történjen a hivatkozó mező értékével, ha a hivatkozott mező értéke megváltozik.
A CHECK lrulcsszó után zárójelben meg kell adni egy logikai kifejezést. A rendszer
minden egyes új sor beszúrásakor az adott mezőre kiértékeli a logikai kifejezést. Ha az
eredmény igaz, a beszúrást elvégzi, egyébként pedig hibát generál. A CHECK megkötés
segítségével biztosítható a tartomány integritás az oszlopban. Fontos, hogy az oszlop szintü
megkötés esetén a CHECK feltétel csak az adott oszlopra vonatkozó logikai kifejezést
tartalmazhat. Amennyiben több oszlop közötti feltételt szeretnénk megadni, akkor tábla szintű
megkötést kell alkalmazni.

22
2.Az SQL nyelv áttekintése lváncsy Renáta

2.1.2. Tábla szintfi megkötés


A tábla szintü megkötést olyankor érdemes használni, ha a megkötés nem csak egyetlen
oszlopot érint, hanem többet is. Tipikusan, ha azt szeretnénk, hogy több oszlop legyen együtt
egyedi, vagy ha egy oszlopra történő feltétel filgg egy másik oszlop értékétőL A tábla szintü
megkötés szintaktikája:
[CONSTRAINT megkötés_név]
{ [ {PRIMARY KEY l UNIQUE}
{ (oszlopnév [, ... n]) }
FOREIGN KEY [(oszlopnév [, ... n))] REFERENCES
hivatkozott táblanév [(hivatkozott oszlopnév) [, ... n] J
[ON DELETE {CASCADE l NO ACTION})
[ON UPDATE {CASCADE l NO ACTION}]
J
CHECK (logikai _kifejezés)
}
A táblaszintü megkötés opcionálisan kezdödhet a CONSTRAINT kulcsszóval és egy, a
megkötést einevező megkötés névvel. Ezek után meg lehet adni a különböző megkötéseket,
amiknek a sorrendje tetszőleges lehet. Az egyes megkötések használata opcionális.
A PRIMARY KEY és a UNIQUE hasonlóan müködnek, mint az oszlopszintü megkötés
esetén, annyi kivétellel, hogy a táblaszintü megkötés esetén a kulcsszó után zárójelben meg
kell adni, hogy mely oszlopok legyenek együtt elsődleges kulcsok, vagy egyed.iek.
Az idegeokules megadásánál tábla szintü megkötés esetén kötelező kiírni a FOREIGN
KEY kulcsszót, majd utána az oszlopokat, amik idegenkulesként fognak szerepelni. A
REFERENCES kulcsszó után kell megadni a hivatkozott tábla nevét, és opcionálisan a
hivatkozott oszlopok neveit. A többi funkció megegyezik az oszlopszintü megkötésnél
leirtakkaL
A CHECK használata megegyezik az oszlopszintü megkötésnél leírtakkal, annyi
különbséggel, hogy míg az oszlopszintü CHECK megkötés esetén csak az adott oszlopot
lehetett a kifejezésben használni, addig a táblaszintünél a tábla bármely oszlopát.
Fontos tudni, hogy az Oracle nem támogatja a SYSDATE (aktuális időpont) használatát a
megkötésekben. Amennyiben egy dátum típusú oszlop értékére a beszúrás időpontjához

viszonyitva szeretnénk megkötést tenni, akkor Oracle esetén triggert kell alkalmazni. MS
SQL Server 2000 esetén használható a getdateO fiiggvény.

23
2.Az SQL nyelv áttekintése Iváncsy Renáta

2.2. Tábla törtése


Táblát törölni a DROP T ABLE utasftássallehet. melynek szintaktikája a következő :
DROP TABLE táblanév;
A tábla törlésével együtt törlödnek a táblában tárolt adatok. a táblára létrehozott indexek,
triggerek, megkötések és jogosultságok is. A nézeteket és tárolt eljárásokat, amik a törölt
táblára hivatkoznak, explicit ki kell törölni a DROP VIEW vagy a DROP PROCEDURE
utasításokkaL Olyan táblát nem lehet kitörölni, amire hivatkoznak idegen kulccsal, először a
hivatkozó mezöt tartalmazó táblát kell törölni vagy a hivatkozást kell megszűntetni . Rendszer
táblákat nem lehet törölni a DROP TABLE utasítással.

2.3. Tábla módosftása


Táblát módosítani az ALTER T ABLE utasítással lehel Lehetőség van oszlopok és
megszorítások megváltoztatására, új oszlop és megszorítás felvételére vagy régiek törlésére,
illetve lehetőség van engedélyezni vagy letiltani megszorításokat, triggereket. Az utasítás
részletes szintaktikája a különböző adatbázis-kezelök SQL dokumentációjában megtalálható,
mi itt most a leggyakrabban használt szintaktikákat mutatjuk be.
Új oszlop felvételét a táblába:
ALTER TABLE táblanév ADD oszlopdefinició;
Egy oszlop törlése táblából:
ALTER TABLE táblanév DROP COLUMN oszlopnév;
Új megkötés felvétele a táblába:
ALTER TABLE táblanév ADD CONSTRAINT megkötésnév megkötés;
Megkötés törlése:
ALTER TABLE táblanév DROP CONSTRAINT megkötésnév;

2.4.Adatok lekérdezése táblából


Egy vagy több táblából sorokat a SELECT utasítással lehet lekérdezni. Lehetőség van egy
vagy több oszlop adatait egy vagy több táblából is lekérdeni. Az utasítás szintaktikája a
következő:

SELECT [ALL l DISTINCT] oszloplista


FROM táblák __listája
[WHERE keresési_ feltétel]
[GROUP BY csoportosítási_ kifejezés]
[HAVING keresési feltétel]
[ORDER BY rendezési_kifejezés [ASC l DESC]];
Az MS SQL Serveren a lekérdezés elsö n sorát a TOP n kulcsszó megadásával lehet
lekérdezni. Oracle-n ezt a rownum-ra tett feltétellellehet megoldani .

24
2.Az SQL nyelv áttekintése Iváncsy Renáta

MS SQL Server esetén lehetőség van a lekérdezés eredményét egy új táblába létrehozni.
Ebben az esetben a lekérdezésben a SELECT és a FROM lrulcsszó között megjelenik egy
INTO lrulcsszó és utána egy táblanév. A lekérdezés eredménye az új táblába kerül, a tábla
oszlopainak a nevét a lekérdezésben meghatározott oszlopnevek al.ko~ák.

2.4.1. A SELECT oszlop listája


A SELECT lrulcsszó után opcionálisan kitehető az ALL vagy a DISTINCT lrulcsszó,
aminek segítségével azt lehet beállítani, hogy a lekérdezés eredménye minden sort
tartalmazzon-e (ALL, ez az alapértelmezett), vagy csak a kOlönbözöeket (DISTINCT). Ezek
után kell felsorolni a kívánt oszlop listát Az oszlop lista tartalmazhatja a lekérdezen táblák
különbözö oszlopait, konstansokat, az oszlopokból számított új oszlopot, valamint az
oszlopokra vonatkozó oszlopfüggvényeket Az oszlopokat lehetőségünk van elnevezni, ekkor
az eredményhalmazban az új névvel fog megjelenni. Ezt az oszlopnév után az AS lrulcsszó és
az oszlop új nevének megadásával tehetjük meg. Az AS lrulcsszó opcionális. Az elnevezést
célszerií használni, ha az eredményhalmazban több azonos nevü oszlop szerepelne, ba
számított oszlopokat használunk, vagy ba oszlopfilggvényeket kérdeztünk le. Az oszlop új
nevére a lekérdezésen belül csak az ORDER BY lrulcsszó után hivatkozhatunk, minden más
esetben újra le kell írni az eredeti oszlopnevet vagy a kifejezést, hogy hivatkozhassunk rá.
Amennyiben több táblából kérdezünk le adatokat, és a tábláknak vannak azonos nevü
oszlopai, úgy az oszloplistában meg kell határozni, hogy az adott oszlopot melyik táblából
szeretnénk lekérdezni.

2.4.2. A FROM kulcsszó


A FROM lrulcsszó után kell megadni azokat a táblaneveket, amikböl az eredményt le
szeretnénk kérdezni, illetve azokat is, amik a WHERE feltételben szerepelnek, bár egyetlen
oszlopát sem jelení~ük meg. Lehetőség van a táblákat is átnevezni, ezt az AS lrulcsszóval
tehetjük meg. Az AS kulcsszó használata ebben az esetben is opcionális. Fontos megjegyezni,
hogy ha egy táblát átnevezünk, akkor a lekérdezésen belül már az új nevével kell hivatkozni
rá, egyébként hibát kapunk. Egy táblát el lehet nevezni két módon is, ha ugyanarra a táblára
két különbözö módon szeretnénk hivatkozni. llyenkor a FROM után kétszer kell felsorolni az
adott táblát, és mindkét helyen más-más új névvel elnevezni. Ez olyankor lehet hasznos, ha
egy táblát önmagával szeretnénk összekapcsolni.
A táblákat két módon lehet összekapcsolni. Az egyik eset, amikor a WHERE feltételben a
táblák Irulcsaira azonossági feltételt teszünk. A másik lehetőség, hogy ha a FROM listában az

25
2.Az SQL nyelv áttekintése lváncsy Renáta

egyes táblákat a JOIN k:ulcsszó segitségével, és az összetartozó oszlopok megjelölésével


kapcsoljuk össze. Bövebben erről az egyes adatbázis-kezelök dokumentációjában
olvashatunk. A JOIN szintaktikája:
Táblanévl JOIN táblanév2 ON összekapcsolási_feltétel;

2.4.3. A WHERE feltétel


A WHERE kulcsszó után adhatók meg olyan logikai kifejezések. amiknek segítségével a
megfelelő sorokat kiválaszthatjuk. Oyen feltételek lehetnek táblák oszlopai közötti
kapcsolatok, az egyes oszlopokra bizonyos feltételek (tartomány, érték, kisebb, nagyobb stb.).
Az oszlopok közötti kapcsolat magába foglalja a FROM kulcsszó tárgyalásakor emlitett JOIN
műveletet is. A k:ülső JOIN Oracle esetén a + jelet kell kitenni azon tábla attribútumok után,
ahova a lekérdezés eredményeképpen megengedhető a NULL érték az illesztés helyett. FULL
OUTER JOIN ilyen módon nem adható meg, azt csak a megfelelő k:ulcsszó használatával a
FROM listában lehet definiálni (Oracle eselén csak Oracle 9i és magasabb verzióiban).

2.4.4. A GROUP BY és a HAVING


A GROUP BY k:ulcsszó használatával van lehetőségünk csoportosítani a sorokat az
eredményben. A mögötte felsorolt oszlopok alapján kerül az eredményhalmaz sora
csoportositásra. Ha akár csak egy oszlop is szerepel a GROUP BY mögött, akkor az összes
oszlopot, ami szerepel a SELECT kulcsszó után az oszloplistában, fel kell sorolni a GROUP
BY után is, kivétel abban az esetben van, ha az adott oszlop oszlopfüggvényben szerepel.
A Jeggyakrabban előforduló oszlopftlggvények a következők :
Név Jelenlis
MIN Minimum érték.
MAX Maximum érték.
AVG Atlag.
SUM Összeg.
COUNT Sorok száma.
Amennyiben a csoportokra szereménk feltételt meghatározni, azt nem tehetjük meg a
WHERE kulcsszó után. A HAVING kulcsszó szolgál arra, hogy a GROUP BY k:ulcsszóval
kialakitott csoportokra tehessünk k:ülönbözö megkötéseket, hasonlóan, ahogy az egyes
sorokra a WHERE feltétel után tehetünk.

26
2.Az SQL nyelv áttekintése lváncsy Renáta

2.4.5. Az ORDER BY

Az ORDER BY lrulcsszó használatával adható meg, hogy az eredményhalmaz mely


oszlopok értékei alapján kerüljön sorrendezésre. Az ASC lrulcsszó megadásával adhatjuk
meg, hogy növekvő, a DESC lrulcsszóval, hogy csökkenő sorrendben kerüljön sorrendezésre
az eredmény. Az alapértelmezett a növekvő sorrend.

2.4.6. Halmazmfiveletek

Az egyes lekérdezések eredményét lehetőség van különböző halmazmüveletekkel


kapcsolatba hozni egymással. Dyen halmazmüveletek a következök lehetnek:
Halmazmfivelet Jelentés
UNION Unió, az azonos sorok közül csak egyszerepelaz eredményben
UNION ALL Unió, az azonos sorok annyiszor szerepelnek, ahányszor elöállítódtak.
INTERSECT Metszet.
MINUS Különbség.
A halmazrnüveletek utasítását a lekérdezések közé keU írni. Halmazmüveletek használata
esetén fontos, hogy a két lekérdezés kompatibilis legyen egymással. Ez azt jelenti, hogy az
oszlopok számának és a típusoknak meg kell egyeznie a két lekérdezésben.

2.4.7. Allekérdezések

Az allekérdezések egy lekérdezésen belül megfogalmazott újabb lekérdezések. Az


allekérdezés állhat a FROM listában, a WHERE után és a HA VIN G után. Az allekérdezésekel
zárójelek között kell megfogalmazni. Amennyiben egy kifejezésben szerepel a lekérdezés,
akkor annak a jobb oldalán kell állnia. Az allekérdezés nem tartalmazhat ORDER BY
kifejezést. Az allekérdezéseknek három típusa létezile
• Egysoros allekérdezés: az egysoros allekérdezés esetén a lekérdezés egyetlen
értékkel tér vissza (egy oszlop, egy sor). A felhasználható összehasonlító
operátorok a következők:=,>,<,<=,>=, és<>.
• Több soros allekérdezés: a több soros lekérdezés esetén az allekérdezés
eredménye nem egyetlen skalár, hanem egy tömb (egy oszlop, de több sor).
Ebben az esetben nem használhatók az egysoros lekérdezésnél felsorolt
operátorok, helyette az IN, ANY, ALL, EXISTS operátorokat kell alkalmazni.
• Több oszlopot tartalmazó allekérdezés: a több oszlopot tartalmazó allekérdezés
t esetén a SELECT listában nem csak egyetlen oszlop szerepelhet, banern több is.

27
2.Az SQL nyelv áttekintése Jváocsy Renáta

Ebben az esetben a lekérdezés eredményét, mint egy táblát kezelhetjük. Tipilrusan


a FROM kulcsszó után szok.ás használni.

2.S.Új sor beszúrása táblába


Új sort egy adott táblába az INSERT utasítássallehet beszúrni. Szintaktikája a következő:
INSERT INTO táblanév [oszloplista]
VALUES {kifejezés};
A táblanév és a V ALUES kulcsszó között akkor kell felsorolni az oszlopok neveit, ha
nem az összes oszlopnak adunk meg értéket a V ALUES után a zárójelben. A V ALUES
kulcsszó mögött a zárójelben pontosan annyi adatot kell megadni, ahány oszlopa van a
táblának. illetve ahány oszlopot felsoroltunk az oszloplistában.
Abban az esetben, ha az SQL Serveren valamelyik oszlopnak IDENTITY megkötést
adtunk. akkor nem lehet explicit értéket megadni neki az INSERT utasitásban. Ha mégis
explicit szeretnénk az ilyen oszlopok értékét állítani, akkor a beszúrás előtt ki kell adni a
következő parancsot:
SET IDENTITY INSERT táblanév ON
Ezt a funkciót a következő utasítással szüntethetjük meg:
SET IDENTITY INSERT táblanév OFF
A beszúrandó érték helyén beírhatjuk a DEFAULT kulcsszót, ekkor a tábla definiálásánál
megadott alapértelmezett érték kerül beszúrásra. Ha nincs megadva alapértelmezett érték, és
az oszlop elfogad NULL értéket, akkor ebben az esetben NULL érték kerül beszúrásra. SQL
Serveren IDENTITY megkötéssel rendelkező oszlopra nem használható a DEFAULT
kulcsszó. A beszúrandó érték lehet explicit NULL, ha az oszlop megengedi a NULL értéket.
Harmadik lehetőség érték beszúrására, ha valamilyen kifejezést adunk meg, aminek az
eredményét az adott oszlopba be kell szúrni. Ez leggyakrabban egy konstans.

2.5.1. INSERT INTO SELECT


Lehetőség van a beszúráskor egy egész lekérdezés eredményét beszúrni. Ekkor a
VALUES kulcsszó kihagyásával egy allekérdezést kell megfogalmazni. Ekkor figyelni kell
arra, hogy az allekérdezés pontosan annyi oszloppal térjen vissza, amennyi oszlopot be
szeretnénk szúrni a táblába, valamint az oszlopoknak típushelyesen kell szerepelniük.

2.6.Sorok törlése táblából


Sorokat a DELETE utasítással törölhetünk egy táblából. Szintaktikája a következő:
DELETE FROM táblanév [WHERE keresési_feltétel];

28
2.Az SQL nyelv áttekintése Iváncsy Renáta

Abban az esetben, ha nem adunk meg WHERE feltételt, a tábla összes sora törlésre kerül.
Egyéb esetben a WHERE kulcsszó után meg kell adni egy feltételt, ami azokat a sorokat
választja ki, amiket törölni szeretnénk.
Amennyiben az összes sort ki szeretnénk törölni a táblából, használhatjuk a TRUNCA TE
utasítást.
TRUNCATE TABLE táblanév
A TRUNCATE használatával lényegesen gyorsabban törölhetünk, mint egy feltétel
nélküli DELETE utasítással, ami szintén az összes sort törölné. Szintén gyorsabb, mint
eldobni az egész táblát, és újra létrehozni azt, ugyanis ebben az esetben az összes triggert és
egyéb, a táblával kapcsolatos objektumot újra létre kellene hozni.

2.7.Mező módosítása
A lábiában egy mezö az UPDATE utasilás segitségével módosítható, szintaktikája SQL
Serveren a következő:
UPDATE táblanév
SET oszlopnév= { kifejezés l DEFAULT l NULL} [, ... n]
[FROM { táblanév l nézetnév} [, ... n]]
WHERE keresési feltétel;
A SET kulcsszó után kell megadni a tábla módositani kivánt oszlopait, és az adott mezö
új értékét. Az új érték, hasonlóan az INSERT utasításnál látottakkal, lehet egy kifejezés, a
DEFAULT kulcsszó (ilyenkor a definiálásnál megadott alapérték lesz a mezö új értéke) vagy
a NULL. A FROM kulcsszó után kell megadni azokat a táblákat, amikhez tartozó oszlopok a
WHERE kulcsszó után. a keresési feltételben szerepeinek és nem a módosftani kivánt tábla
oszlopai. Ha nincs ilyen tábla, akkor a FROM kulcsszót el kell hagyni.
Oracle-ben nincs lehetőség megadni a FROM kulcsszót! Abban az esetben, ha az Oracle
táblában egy másik tábla adatai alapján szeretnénk módosítani, egy allekérdezés segítségével
lehet kiválasztani a megfelelő sorokat.
Az UPDATE utasilás szintaktikája Oracle esetén:
UPDATE táblanév
SET oszlopnév= {kifejezés l DEFAULT l NULL} [ , ... n]
WHERE keresési feltétel;

2.8.Nézet létrehozása
A nézetek olyan virtuális táblák, amik egy vagy több fizikai tábla alapján kerülnek
létrehozásra, és a táblákban tárolt adatokat az eredeti tárolási logikától eltérő logikai
rendszerezés alapján tartalmazzák. A nézetek nem tárolnak adatokat, csak más nézetböJ

29
2.Az SQL nyelv áttekintése lváncsy Renáta

mutatják az adatbázis adatait Nézetet a CRETAE VIEW utasítással hozhatunk létre, melynek
szintaktikája a következő:
CREATE VIEW nézetnév [ (oszlopnév [, ... n]) J AS lekérdezés [WITH
CHECK OPTION] ;
A nézetnév az újonnan létrehozott nézet neve. A névnek meg kell felelnie az elnevezési
konvencióknak. A nézetnév után fel lehet sorolni az oszlopokat, amikböJ a nézet állni fog.
Ezzel felül lehet definiálni a lekérdezésben megadott oszlopneveket Kötelező megadni az
oszlopneveket, ha a lekérdezésben származtatott értékek, kanstansok vagy oszlopfilggvények
vannak. illetve ha több oszlopnak azonos neve lenne. Az AS kulcsszó után meg kell adni egy
lekérdezést, aminek az eredményét szeretnénk nézetként látni.
A WITH CHECK OPTION k:ulcsszó segitségével az adható meg, hogy a nézet
létrehozásakor megadott feltételek a nézeten keresztüli beszúráskor is figyelembe legyenek
véve. Ha például a nézet azokat a sorokat tartalmazza egy táblából, aminek az azonosítója
nagyobb mint 100, akkor ha a WITH CHECK OPTION be van kapcsolva. akkor a nézeten
keresztül csak olyan sorokat tudunk beszúmi, aminek az azonosítója nagyobb, mint l 00. Ha a
WITH CHECK OPTION el van hagyva, akkor bánnilyen azonosító értékkel rendelkező sor
beszúrható a nézeten keresztül a táblába, noha a nézeten keresztül továbbra is csak azok
Játszódnak. amiknek az azonosítója nagyobb, mint l 00.

2.9.Nézet törlése
Nézetet a DROP VIEW utasítássallehet törölni.
DROP VIEW nézetnév;

2.10. Nézet módosítása


Nézetet módosítani az ALTER VIEW utasítással lehet, szintaktikája:
ALTER VIEW nézetnév [ { oszlopnév [, ... n])] AS lekérdezés [WITH
CHECK OPTION];
Nézet módosítása esetén a teljes lekérdezést meg kell Imi, ami alapján a nézet az adatokat
megjeleníti.

2.11. Sor beszúrása nézetbe


Sort a nézethe az INSERT utasítással szúrhatunk be. Az INSERT utasítás szintaktikája
megegyezik a táblánál leírtakkal, annyi különbséggel, hogy a táblanév helyett a nézet nevét
kell beírni. Az utasítás használatának a feltétele, hogy az adott nézet módosítható legyen. Az
INSERT utasítás a nézetre csak egy olyan táblát érinthet, amiböJ a nézetet származtattuk.
Amennyiben egy nézet több táblából származik, a beszúrás megvalósítására triggert kell írni.

30
2.Az SQL nyelv áttekintése lváncsy Renáta

2.12. Sor törlése nézetböJ


Sort törölni a DELETE utasítással lehet egy nézetbőL A szintaktikája megegyezik a
tábláknál leírtakkal, annyi különbséggel, hogy a táblanév helyett a nézet nevét kell megadni.
A nézetnek módosíthatónak kell lennie, és csak egy táblából szabad szánnaznia.

2.13. Mezö módosftása nézetben


Nézetben mezö definíciót módosítani az UPDATE utasítással lehet. Szintaktikája
megegyezik a táblák:nálleírtakkal, annyi különbséggel, hogy a tábla neve helyett a nézet nevét
kell megadni. A nézetnek módosíthatónak kell lennie, és az UPDATE utasítás nem érinthet,
csak egy táblát, amiböl a nézet szánnaztatva lett.

2.14. Minta adatbázisok


A jegyzet további részében a szerver oldali elemek bemutatására készült példák
többségében az alább ismertetett három minta adatbázison készültek.

2.14.1. A tanár-diák adatbázis

A tanár-diák adatbázis egy tanulmányi rendszer adatbázisát képzi. A tanulmányi


rendszerben lehetőség van a diákok, tanárok, tárgyak adatainak tárolására. Az egyes
szemeszterekben a tárgyakból kurzusokat indítanak, amely k:urzusokra a diákok
jelentkezhetnek, valamint a kurzushoz hozzá kell rendelni tanárt vagy tanárokat. A
k:urzusokhoz vizsgák is ki írásra kerülnek, amire a hallgatók szintén jelentkezhetnek.
Az adatbázis részletes leírása és a hozzájuk tartozó séma ábrázolása az alábbiakban
található.
STUDENT
A STUDENT tábla tárolja el az egyes diákok adatait.
Oszlop név Tipus Jelentés
stud id CHAR{6) Neptun kód, diák elsődleges kulcsa
stud fname V ARCHAR{50) Diák keresztneve
stud lname V ARCHAR{50) Diák vezetékneve
stud maii V ARCHAR(80) Diák e-mail címe

31
2.Az SQL nyelv áttekintése lváncsy Renáta

TEACHER
A tanár adatait tárolja.
Oszlop név Tipus Jelentés
tea id CHAR(6) Neptun kód, a tanár elsödlc:ges kulcsa
tea fname VAR CHAR(50) Tanár keresztneve
tea lname VARCHAR(50) Tanár vezetékneve
tea_grade CHAR(2) Fokozat.
tea status INT A tanár státusza, idegen kulcs a sort status táblára.
tea dept CHAR(4) A tanát tanszéke, idegen kulcs a department táblára
tea maii VARCHAR(80) Tanár e-mail címe

SORT_STATUS
Az egyetemen szereplö státuszok elnevezése. Az azonosftók sorrendje alapján a
státuszokat sorrendbe is lehet rendezni, így meg lehet mondani, hogy a tanszékvezető legyen a
legmagasabb fokozat stb.
Oszlop név Típus Jelentés
status id INT A státusz kódja
status name VARCHARJ30) A státusz megtt_evezése

SORT_SUBJECTTYPE
A tárgyak tipusát sorolja fel. A tárgy tipusa azt határozza meg, hogy az adott tárgy melyik
képzésen kerül oktatásra (villamosmémöki alapozó, informatikus szakirányú stb.)
Oszlop név Tipus Jelentés
st id INT A tíj)_us kódja
st _typ_ename VARC~(50)_ A ti!l_us megnevezése

SUBJECT
A SUBJECT tábla tárolja el az egyes oktatott tárgyak adatait. Ezek azok az adatok., amik
állandóak, nem váltomak félévröl-félévre.
Oszlop név Tipus Jelentés
sub id CHAR{8) A tárgy kódja, mint pl. VIAU9159
sub name VARCHAR(50) A tárgy megnevezése
sub outcome CHAR( l) A követelmény. V-vizsga, F-félévközi, G-gyakorlat
sub credit NUMBER(2, l) A kredit érték
sub vdklink VARCHAR(200) A tárgy honlapja
sub _type INT A tárgy tipusa, idegen kulcs a sort subjecttype-ra

32
2.Az SQL nyelv áttekintése Iváncsy Renáta

SEMESTER
A szemeszterek adatait tartalmazza.
Oszlop név Típus Jelentés
sem name CHAR(5) A szemeszter kódja. Az első négy jegy az évet jelenti,
az ötödik szám a naptári évben vett félév sorszámát,
tahát az egyes szerepel a tavaszi és kettes az őszi félév
esetén.
sem be!lli!_ DATE A szemeszter kezdete
sem end DATE A szemeszter vége
sem exambegin DATE A vizsgaidöszak kezdete
sem examend DATE A vizsgaidöszak vége

CO URS E
A tárgyakhoz félévenként különbözö lrurzusokat lehet kiírni. Ez azért van igy, mert egy
tárgyat egy félévben más-más tanár oktathat, és természetesen más diákok is járnak rá. Egy
tárgyhoz egy félévben több Irurzust is ki lehet írni (pl. több labor gyakorlatot) amiket
sorszámmal kell ellátni.
Oszlop név Típus Jelentés
cou id INT A 1rurzus azonosítója
cou subjectid CHAR(8) A tárgy azonosítója, amihez a lrurzus ki lett írva
cou semestemame CHAR(5) A szemeszter, amikor a kurzus meg lett hirdetve
cou_type CHAR( l) A 1rurzus típusa. E-előadás, G-gyakorlat, L-labor
cou coursenumber INT A 1rurzus sorszáma
cou limit INT A Irurzusra jelentkező hallgatók számának korlátja

STUDENT_ COURSE
Ha egy diák egy Irurzusra jelentkezik, a STUDENT _COURS E táblába kerül egy
bejegyzés, ami tartalmazza a diák és a lrurzus azonosítóját, valamint a jelentkezés dátumát.
Oszlop név Tipus Jelentés
sc studentíd CHAR(6) A diák azonosítója.
sc courseid INT A 1rurzus azonosítója
sc date DATE A Irurzusra való jelentkezés dátuma

33
2.Az SQL nyelv áttekintése Iváncsy Renáta

COURSE TEACHER
A lrurzust egy vagy több tanár oktathatja, de ha több tanár is oktathatja, valamelyikük
meg van jelölve felelős tanárként.
Oszlop név Tipus Jelentés
ct id INT A tábla azonosítója
ct teacherid CHAR(6) A tanár azonosítója
ct courseid INT A lrurzus azonosítója
ct masterteacher INT Ha a tanár a felelős, értéke l, egyébként O.

EXAM
Minden lrurzushoz ki lehet írni vizsga időpontokat.

Oszlop név Tipus Jelentés


ex id INT A vizsga azonosítója
ex cmu-seid INT A kurzus azonosítója
ex date DATE A vizsga időpontja
ex limit INT A vizsgára jelentkezök számának korlátja

STUDENT EXAM
A vizsgára való jelentkezést egy sor beszúrása jelenti a STIJDENT_ EXAM táblába.
Ekkor beszúrásra kerül a vizsga azonosítója, a diák azonosítója, valamint a jelentkezés
dátuma. Amennyiben a diák le is vizsgázott, az osztályzat oszlop is ki töltésre kerül.
Oszlop név Tipus Jelentés
sx studentid CHAR(6) A diák azonosítója
sx examid INT A vizsga azonosítója
SX date DATE A vizsgára jelentkezés időpontja
SX _grade INT Az osztályzat

BUILDING
A rendszerben nyilván tartjuk az egyes épületeket is, ahol a termek előfordulhatnak.

Oszlop név Típus Jelentés


build id INT Az épület azonosítója
build name VARCHAR(20) A épület neve
build zipcode VARCHAR(4) Az irányítószám
build city VARCHAR(30) A város
build street VARCHAR(30) Az utca neve
build number VARCHAR( l O) A házszám

34
2.Az SQL nyelv áttekintése Iváncsy Renáta

DEPARTMENT
A tanszékek adatait tárolja.
Oszlop név Típus Jelentés
dept code VARCHAR(4) A tanszék azonosítója
dept name VARCHAR(50) A tanszék hosszú elnevezése
dept_building INT Az épület azonosítója. amiben a tanszék
adminisztrációja van.
dept floor V ARCHAR(l5) Az emelet, ahol a tanszék található az épületen belül

ROOM
A terem adatait tárolja el.
Oszlop név Tipus Jelentés
room id INT Az terem azonosítója
room building INT A terem melyik épületben van
room number VARCHAR(lO) A terem száma
room places INT A terem férőhelyeinek száma
room dept VARCHAR(4) A terem melyik tanszékhez tartozik.
room tel V ARCHAR(l5) A terem telefonszáma. ha van
room _type INT A terem típusa, idegen kulcs a room _type táblára

ROOM TYPE
A terem típusát határozza meg (elöadó terem, labor, tanáriszoba stb.).
OuJop név Tipus Jelentés
rt id INT A típus kódja
rt_type V ARCHAR(30) A típus megnevezése

TECHAER ROOM
Azt határozza meg, hogy melyik tanár melyik szobában van elhelyezve hivatalosan. Egy
tanár több teremhez is tartozhat, és egy teremben több tanár is ellehet helyezve.
Oszlop név Típus Jelentés
tr teacherid CHAR(6) A tanár azonosítója
tr roomid INT A terem azonosítója
tr default NUMBER( l ,0) A tanár alapértelmezett szobája.

EXAM_ROOM
Azt határozza meg, hogy melyik vizsga melyik teremben van. Több-többes kapcsolat,
mert egy vizsgát több teremben is lehet tartani, ha olyan sok a hallgató, de egy teremben lehet
több vizsgát is tartani, ha például azonos tanár tartja a két vizsgát.
OuJop név Tipus Jelentés
u examid INT A vizsga azonosítója
u roomid INT A terem azonosítója

35
....
~
Vl
t•adw (opeo) ,o
co~.~mN.melo.ti t,;;ö -. t"'

~
sort_tubjKttype (op60) rrt ....J te• '' che• ....J
[Jc<bmíia 1o.. iii>t ~ veoch.oo
~ea_fr,~rrt- v~(het
<
~~-•: rt :J~a:J. _ _.O<>(\- l J ~~<~-~· ~ v 4f'(h!r

w~_t.,.-:l." .YT'Ie ., ~, c ~·~· ,cb _"-'<ome <h« ted _(1.!11'! :h!r


~
L: ..::J
§ ~.b treót
s...tl~·.-d,Jri
~u :- _f"ftle
r"'(
v&c h a·

..::J
:
tea _~atus

tea_dect
te.!l_ff'l<!l ~
".,:
.. ~.:.,:•
..-~ .: ~• ! •

..::J
e:
(\.
!':

~ (t_rr.~~~·teacher r.t
~ ..::J

.,
1:1" D«• TYOI ...
- -,
[
•>
·-t

....,
c~ ·J_'> u::>.ec~.-j teat.r...room (opeo)
P>--<>fl cou_i.etrlM:enwne '""' ~..::;.n..... ,OOtl!'ll"'_ ..
'""' D.ia T)'Olt
.-.
~
cou_t-,pe tr_teo..:~~·d c ~oat
D C'Ju_CO'.JI'seni.IT'Iber '""
·· t
v,yc'1ar -'l tr_r()Qtl'lod rr(
_J

c::u H rr( ~· -·1el-!ut b-:


da~:etne
..::J
~ÍÓ2tri!~
<M
a- ".: ..::J
é: [j''->9-f·~·~~e datetne
..::J ~ :e~<_o::ade v<~rdw :J
•==
Q,
1
ttudent (opeo'
i
r - - - - - - - - C - j!
u : ept_r'lan'le
:ept_t:uldrQ lr'lt
:ept floo r
\' ~(t\&1

v <!ll'd\41'

l
=

D - ..::J
=-
1:1"

..~ ·.~-~~) -
l 1Coi\IM-..
'"
1o;,a l ,po •J
!
l
1~
~ , "'""'-~ :.JF--
a i room b JOnq r.: buldlncl (opeo)
.!:

....
..::J; '
.
~.~·ooiTI _r...JMber
1 room _;l ~ es
,-y:t'I.Y
rnt r .. •
,.,...l1J'.um~It>«•T-
"- ·~-"' ~

F----'
l
room
H'l•.::om_~e l
itj'(o)l'rl_:rt>e
:~t ,-."j,.or
,-or: l\ar
•rt
IS"-"" no~•
~.. t>Ytl _zoc. oo.
~J6j _ ((",
lat(~rJjr

-,~r(l'\ar

\"~ (~~
studont_..." (opeo)
l " " - - l Oat•T.i» ..::J :uk1 ~··eret ·.-~ e NI'

r ,::joold:"'"be· -.-ar(h.ir

1;_, .
~··-~ ·,", -t,.j =·~· ....J
~s·_~:,yn.;l nt ..::J
L-1~·-=dt~
., _;· ~
;4tetsne
nt

..::J "f~~~'.oöj i..


X·t-·d n
'<
: •t type
-, -
varo:h.ar
..::J
i
2.Az SQL nyelv áttekintése lváncsy Renáta

2.14.2. A cukrász adatbázis

A cukrász adatbázisban receptek kerülnek eltárolásra. illetve a cukrászatban szereplö


anyagok mennyiségére vonatkozó adatok. A cukrászatban az alapanyagokból félkész
termékeket állítanak elö, mint pl. a piskóta lap vagy tejszinhab stb. A félkészekből, és egyéb
anyagokból pedig elöállítják a terméket

EGYSEG
Az egység táblában tároljuk el, hogy az egyes alapanyagokat, félkész termékeket és kész
tc:rmékeket milyen egységben értelmezzük, pl. kg, liter, darab, lap, szelet stb.
Ti us
INT
nev VARC

ANYAG
Az anyag táblában kerülnek eltárolásra azok az összetevők, amikböJ elöállftják a félkész
ál a kész termékeket.

FELKESZ
A félkész termékek olyan készitmények, amiket a termékek előállításához kell használni,
azonban önmagukban is már különbözö alapanyagokból tevödnek össze. Félkész termék lehet
például a piskóta tészta, amit még a csoki torta elkészítéséhez fel fognak használni, vagy akár
a tejszinhab is.
Oszlop név Tipus Jelentés
felkesz id INT A félkész azonosítója
felkesz nev VARCHAR( l 00) A félkész neve
felkesz _mennyiseg INT A félkész mennyisége az adott egységböl, ami a
recept alapján elkészül.
felkesz egyseg INT A félkész egysége
felkesz raktardb FLOAT A félkészből a raktárban található mennyiség
felkesz minraktar FLOAT A raktárban minimum ennyi félkésznek kelllennie

37
2.Az SQL nyelv áttekintése Iváncsy Renáta

TERMEK
A termékek olyan készitmények, amik már eladásm kerülnek. Ezek tartalmazhatnak
félkész termékeket, és közvetlenül alapanyagokat is.
Oszlop név Tipus Jelentés
termek id INT A termék azonosítója
termek nev VARCHAR(IOO) A termék neve
termek_mennyiseg INT A termék mennyisége az adott egységböl, ami a
recept alapján elkészül.
termek egyseg INT A termék egysége

FELKESZ ANYAG
Azt határozza meg, hogy adott mennyiségű és egységű félkészhez milyen és mennyi
anyag szükséges.
Oszlop név Tipus Jelentés
fa felkeszid INT A félkész azonosítója
fa anyagid INT Az anyag azonosítója
fa mennyiseg FLOAT Az anyagból szükséges mennyiség

TERMEK_FELKESZ
A táblában tárolt adatok azt határozzák meg, hogy egy adott termékhez milyen, és
mekkom mennyiségű félkész szükséges.
Oszlop név Tipus Jelentés
tf termekid INT A termék azonosítója
tf felkeszid INT A félkész azonosítója
tf mennyiseg FLOAT A félkészböJ szükséges mennyiség

TERMEK ANYAG
Azt határozza meg, hogy a termékhez milyen anyag kell közvetlen. Pl a porcukor a süti
tetején stb.
Oszlop név Tipus Jelentés
ta termekid INT A termék azonosítója
ta anyagid INT Az anyag azonosítója
ta mennyiseg FLOAT Az anyagból szüksé~es mennyiség

38
"'
~
U)
~
r"'

~
ANYAG
<
~
PK AtfiA~ ID NUMBER
5-
;--------------H FK1
ANYAG_NEV
ANYAG_EGYSEG
VARCHAR2(100)
NUMBER
TERMEK_ANYAG f
l
ANYAG_EGYSEGAR FLOAT
l
l
l
ANYAG_RAKTARDB FLOAT H--------- -o FK2 TA_TERMEKID NUMBER
l ANYAG_MINRAKTAR FLOAT
l FK1 TA_ANYAGID NUMBER
~ l ANYAG_ MAXRAKTAR FLOAT
TA_MENNYISEG FLOAT

c:r
ill FELKESZ_ANYAG l
> l
l
n l

~
l
l
....
'1:1
FK2 FA_FELKESZID NUMBER EGYSEG l
:z:
N FK1 FA_ANYAGID NUMBER
FA_MENNYISEG FLOAT
PK !;;~YSi;;~ ID NUMBER
TERMEK
,..
~ EGYSEG_NEV VARCHAR2(20)
tO
PK !!;;BMi;;IS ltl NUMBER
&
~- -=
;;;· TERMEK_NEV VARCHAR2(100)
TERMEK_MENNYISEG NUMBER
~ FK1 TERMEK_EGYSEG NUMBER
8
e.
l» :z:
l
FELKE SZ l
l
TERMEK_Fe\..KESZ l
PK E!;;LIS!;;SZ ltl NUMBER l
l
_______________ J l
FELKESZ_NEV
FELKESZ_MENNYISEG
VARCHAR2(100)
NUMBER
H------ \..1"1
FK2 TF _TERMEK ID NUMBER
~
FK1 FELKESZ_EGYSEG NUMBER FK1 TF _FELKESZID NUMBER
FELKESZ_RAKTARDB FLOAT TF _MENNYISEG FLOAT <
FELKESZ_MINRAKTAR FLOAT
[
'<

i
2.Az SQL nyelv áttekintése lváncsy Renáta

2.14.3. A Forma-l adatbázis


A Forma-l adatbázis egy egyszerű adatbázis Forma-l-es pilóták., csapatok és futamok
adatainak a tárolására.

SZEZON
A szezon táblában tároljuk el az egyes Forma-l-es szezonok kezdő és végdátumát Az
elsődleges Irules a szezon évszáma.
Oszlop név Tipus Jelentés
ev INT A szezon azonosítója, lényegében az évszám.
kezdodatum DATE A szezon kezdete.
vegdatum DATE A szezon vége.

PlLOTA
A pilóta táblában tároljuk az egyes pilóták alapvető adatait.
Oszlop_ név Tipus Jelentés
pi lotaid INT A pilóta azonosítója.
nev NVARCHAR2( l 00) A pilóta teljes neve (a vezeték és a keresztnév is).
szuletesidatum DATE A pilóta születési dátuma.
nemzetiseg NV ARCHAR2(50) A pilóta nemzetisége.
magassag INT A pilóta magassaga cm-ben.
suiy INT A pilóta súlya kg-ban.

CSAPAT
A csapat táblában olyan adatok kerülnek eltárolásra, ami a csapat jellemzője, és a
szezonok során nem változik. Az itt felvett mezők definíciószerüen nem változnak.
Oszlop név Tipus Jelentés
csapatid INT A csapat azonosítója.
nev NVARCHAR2(50) A csapat neve.
szekhely NVARCHAR2(50) A csapat székhelye.

40
2.Az SQL nyelv áttekintése Iváncsy Renáta

CSAPAT_SZEZON
A csapat_szezon táblában adjuk meg, hogy mely szezonban mely csapatok indultak és
m.ilyen egyéb tulajdonságokkal rendelkeznek az adott szezonban. Dyen például a fönök neve,
a használt gumi abroncs vagy a motor típusa.
Oszlop név Tipus Jelentés
Csaoatszezonid INT A tábla azonosítója.
Csapatid INT A csapat azonosítója.
Ev INT A szezon azonosítója
Fonoknev NV ARCHAR2(1 00) A csapat fönökének a neve az adott szezonban.
Abroncs CHAR( l) A csapat által használt abroncs típusa az adott
szezonban. M = Michelin, B = Bridgestone
Motor NV ARCHAR2(5ó) A motor típusa.

CSAPAT_PILOT A
A csapat pilóta táblában tároljuk el, hogy egy-egy szezonban mely pilóták versenyeztek
az egyes csapatoknál.
Oszlop név Tipus Jelentés
csapatszezonid INT A csapat szezon azonosítója.
pilotaid INT A pilóta azonosítója.
pi Iotatipus CHAR(!) A pilóta típusa. l = elsö számú pilóta, 2 =
másodszámú pilóta, T = teszt pilóta

HELYSZIN
A helyszín táblában tároljuk el az egyes futamok lehetséges helyszíneit, és a helyszínhez
kötődö legfontosabb információkat
Oszlop név Tipus Jelentés
helyszini d INT A helyszín azonosítója.
nagydij NVARCHAR2(5ő) A nagydij neve.
palya NVARCHAR2(50) Ha van a pályának külön neve, akkor azt ebben az
oszlopban lehet megadni.
palvahossz FLOAT A pálya hossza méterben.
korokszaroa INT A körök száma, amit egy versenyen meg kell tenni
korrekord FLOAT A pályán elért eddigi legjobb eredmény
másoduercben.
korrekordpilotaid INT A lelriobb eredményt elért pilóta azonosítója.

41
2.Az SQL nyelv áttekintése Iváncsy Renáta

FUTAM
A futam táblában az egyes szezonokban a különbözö pályákon megrendezett futamok
adatait tároljuk el.
Oszlop név Tipus Jelentés
Futamid INT A futam azonosítója
helyszinid INT A helyszín azonosítója
ev INT A szezon azonosítója.
datum DATE A futam pontos dátuma.
leggyorsabbkorido FLOAT A futamon elért legjobb kör ideje másodpercben.
leggyorsabbkorpi Iota INT A legjobb kört elért pilóta azonosítója.

FUT AM_PILOT A
A futam _pilota tábla az egyes futamokon az egyes pilóták által elért eredményt
tartalmazza.
Oszlop név Tipus Jelentés
futamid INT A futam azonosítója
pilotaid INT A pilóta azonosítója
helyezes INT A pilóta által elért helyezés.
ido FWAT A pilóta ideje másodpercben. Ha az adott pilótát
lekörözték, akkor ez az érték nulla.
teljesitettkorokszama INT A pilóta által teljesített körök száma.
rajtracs INT A rajtrács, ahonnan apiióta indult.
esemeny NV ARCHAR2(50) Esetleges esemény, anu a pilóta ki esését
eredményezte, illetve a lekörözöttek eselén a
lekörözés mértékét tartalmazza.

SZPONZOR
A csapatokat évente szponzorálha~ák különbözö szponzorok. A szponzor tábla a
szponzorok adatait tárolja.
Oszlop név Tipus Jelentés
szponzorid INT A szponzor azonosítója.
nev NV ARCHAR2( l 00) A szponzor neve.
szelehely NV ARCHAR2( l 00) A szponzor székhelye.

CSAPAT_SZPONZOR
A csapat_szponzor tábla azt határozza meg, hogy mely évben mely szponzor mely
csapatot mennyivel támogatott.
Oszlop név Típus Jelentés
cs~atszezonid INT A csapatszezon azonosítója
szponzorid INT A szponzor azonosítója
osszeg_ INT A támogatási összeg.

42
2.Az SQL nyelv áttekintése lváncsy Renáta

CSAPAT CSAPAT_SZPONZOR

PK !:;SA~AIIIl NUMBER PK,FK1 CSé,PA!SZEZON!Il NUMBER


~ PK,FK2 SZfQ~QBIIl NUMBER
NEV CHAR(10)
SZEKHELY CHAR(10) üSSZEG NUMBER

? ~
~ SZPONZOR
CSAPAT_SZEZON PK SZPQ!!IZ:QBIIl NUMBER
PK !;;~é.~AISz:ii;Z:Qttlll NUMBER NEV CHAR(10)
SZEKHELY CHAR(10)
FK1 CSAPAliO NUMBER
FK2 EV NUMBER
FONOKNEV CHAR(10) CSAPAT_P!L.QTA
ABRONCS CHAR(1)
MOTOR CHAR(10) PK,FK1 CSé,Pé,TSZ:EZONIIl NUMBER
PK,FK2 ~ILQIAIIl NUMBER
~ l P!LOTATIPUS CHAR(1)
l

~
)

SZEZON
PILOTA
PK ~ NUMBER
PK PILQIAIQ NUMBER
KEZDODATUM DATE
VE GOATUM DATE NEV CHAR(10)
1------------------ -o+ SZULETES!OATUM DATE

? l
l NEMZETISEG CHAR(10)

~
MAGASSAG NUMBER
2 SULY NUMBER

PK ElJIAMlll
FUTAM

NUMBER
?
)
FK2 HELYSZINIO NUMBER
FK1 EV NUMBER FUTAM_PILOTA
OA TUM DATE
LEGGYORSABBKORIDO FLOAT ~ PK,FK1 EI.!Ié.MIIl NUMBER
FK3 LEGGYORSABBKORPILOT A NUMBER PK,FK2 ~ILQIAIIl NUMBER

~
l
HELVEZES
IDO
NUMBER
FLOAT
TELJESITETTKOROKSZAMA NUMBER

~ RAJTRACS
E SEME NY
NUMBER
CHAR(10)
HELYSZIN

PK HELYSZ:INIIl NUMBER

NAGYDIJ CHAR(10)
PALYA CHAR(10)
PALYAHOSSZ FLOAT
KOROKSZAMA NUMBER
KORREKORD FLOAT
FK1 KORREKOROPILOTAIO NUMBER

3. Ábra A Forma-l adatbázis sémája

43
3.A PUSQL áttekintése Iváncsy Renáta

3. A PL/SQL áttekintése
A PUSQL (Procedural Language/SQL) az Oracle adatbázis-kezelő rendszer procedurális
nyelve. Segítségével létrehozhatunk olyan programokat, amik tartalmaznak programvezérlő

utasításokat (feltételek, ciklusok), alprogramokat (ftlggvények., eljárások) valamint különbözö


modulokat (blokkoltat, csomagokat és objektumokat). Mivel kifejezetten az adatbázis
kezeléshez kifejlesztett nyelv, így természetesen nagymértékben támogatja azt. A PUSQL
programban a PUSQL nyelvbeli elemeken kívül használhatunk nagyon sok adatmanipuláló
SQL utasítást is, mint pl. a SELECT, INSERT, DELETE, UPDATE stb. utasításokat. Másik
példaként említhető a %TYPE és a %ROWTYPE operátorok, melyek segítségével egy változó
típusának a megjelölt oszlop (%TYPE esetén), illetve a megjelölt tábla sorának (%ROWTYPE
esetén) a típusát állithatjuk be. Szintén fontos megemlíteni a kurzorok használatát, aminek
segítségével egy több sort visszaadó lekérdezésele eredménye kezelhetö. Összefoglalva, a
PUSQL magában egyesíti az SQL adatmanipulációs és a procedurális nyelvek
adatfeldolgozási képességét.
A PUSQL el6nyei:
• Támogatja az SQI..rt, növeli annak kifejezőképességét .

• Támogatja az objektumorientált programozást.


• Képes programkódole újrahasznositására.
• Nagyobb teljesítményt nyújt, mint az SQL.
A PUSQL blokk-orientált nyelv, ami azt jelenti, hogy a programot logikai blokkokra
(block) lehet bontani. Egy blokk lehet anonim blokk (anonymus block), eljárás (procedure)
vagy fiiggvény (functíon). A blokkole természetesen egymásba is ágyazódhatnak, így alakítva
ki a program struktúráját (nested blocks). Jellemzöen egy logikai blokk egy probléma
megoldására szolgál.

3.1.Biokkok
Egy blokk három fö részből áll: az opcionális deklarációs részből (declare), a kötelező

futtatható részből (executable) és a szintén opcionális kivételkezelő részből (exception).


[<<blokk_ fejléc>>]
[DECLARE
<konstansok;>
<változók;>
<kurzorok;>
<felhasználó által definiált kivételek;>]

44
3.A PUSQL áttekintése lváncsy Renáta

BEGIN
<PL/SQL futtatható utasítások;>
[EXCEPTION
<hibakezelés;>]
END;
A dek.larációs részben kerülnek a változók. konstansok. kurzorok és a kivételek
deklarálásra és inicializálásra (kezdeti érték adásra). Erre a blokkon belül máshol nincs mód.
Minden változó deklarációnak meg kell előznie a változó elsö felhasználását. Ezt azért fontos
megjegyezni, mert előfordulhat, hogy egy változó inicializálásakor egy már addig inicializált
változót használunk fel. A futtatható részben a PUSQL utasítások helyezkednek el. A
hibakezelés az EXCEPTION és az END szó közt foglal helyet. Itt lehet megadni azokat a
PUSQL programsorokat, amiket a megadott hiba keletkezésekor szeretnénk végrehajtani.
Például ilyen lekezelendö hiba szokott lenni a nullával való osztás, ZERO _DIVI DE, vagy a
lekérdezés egyetlen sorral sem tért vissza, NO_ DATA_ FOUND rendszer kivétel. Az
alábbiakban egy minta blokkot láthatunk. Figyeljük meg, hogy minden PUSQL utasítást
pontosvessző (;) zár le, és a blokkot bezáró END után is pontosvessző áll.
DECLARE
anyagnev VARCHAR2(20);
anyagid NUMBER(5) :=15;
BEGIN
SELECT anyag_nev INTO anyagnev FROM anyag
WHERE anyag_id anyagid;
EXCEPTION
WHEN NO DATA FOUND THEN
anyagnev := 'Hiba';
END;
A három említett blokktípus a következő szintaktikával rendelkezik:
Anonim blokk:
[<<blokk fejléc>>]
[DECLARE
<deklarációk>]
BEGIN
<utasítások>
[EXCEPTION
<hibakezelés>]
END;

45
3.A PUSQL áttelrintése Iváncsy Renáta

Eljárás:
PROCEDURE nev[(<paraméterek>)] IS
[<deklarációk>]
BE GIN
<utasítások>
[EXCEPTION
<hibakezelés>]
END;
Függvény:
FUNCTION nev[(<paraméterek>)J
RETURN adattípus IS
[<deklarációk>]
BE GIN
<utasítások>
RETURN érték;
[EXCEPTION
<hibakezelés>]
END;
Az alprogramok (ftlggvények, eljárások) a program olyan részei, melyek paramétereket
kaphatnak és több helyröl, többször meghívhatóak. Az eljárás müveletek elvégzésére, a
függvény értékek kiszámítására szolgál.
ABEGIN és az END kulcsszavak között DML (Data Manipulalion Language) utasítások,
programvezérlő utasítások és tranzakció kezelő utasítások szerepelhetnek. Függvények esetén
a DML utasítások közlll csak a SELECT utasítás szerepelbet, az INSERT, UPDATE, vagy
DELETE utasítás nem.

3.2. Változók deklarálása, inicializálás&, értékadása


Változók bármilyen SQL vagy PUSQL adattipusúak lehetnek (mínt pl.SQL-ben a
CHAR, a DATE vagy a NUMBER vagy PUSQL-ben a BOOLEAN vagy a
BINARY _INTEGER). Tegyük fel, hogy a nev változóban egy maximum 20 hosszú karaktert
szeretnénk eltárolni, míg a fe rf i változóban egy igaz vagy hamis értéket. Ekkor a változó
deklarálása a következöképpen fog kinézni :
nev VARCHAR2(20);
_ ferfi BOOLEAN;
A változókat a deklaráláskor azonnallehet inicializálni is, de a blokk más részén is kaphat
'
érétket. Változók a következő módon kaphatnak értéket:
• A := operátor segítségéveL
• Lekérdezésből a SELECT oszlopnév INTO változó FROM ... formula
segítségéveL

46
3.A PUSQL áttekintése Iváncsy Renáta

• Kurzorból a FETCH Imrzornév INTO változó ... formula segítségéve!.


• Eljárás vagy ftlggvény kimenő paramétereként.

3.3.Kurzorok
Az ORACLE az SQL parancsok futtatásához munkaterületet használ, erről a területről
nyerhetjük ki az információt. A Imrzor nevü PUSQL konstrukció lehetőséget ad arra, hogy
elnevezzünk egy ilyen munkaterületet, így kapva lehetőséget az általa tárolt információ
eléréséhez. Kétfajta Imrzor létezik, az implicit és az explicit. A PUSQL m.inden olyan
utasításhoz, ami pontosan egy sort ad vissza. készít egy implicit kurzort. A többsoros
lekérdezésekre a programozónak explicit kell defmiálnia a kurzort.
DECLARE CURSOR Cl IS
SELECT anyag nev,anyag id FROM anyag;
A kurzort, a deklarációs részben hozzá kell rendelni egy lekérdezéshez. Használat előtt

meg kell nyitni (OPEN), ekkor a kurzor az eredményhalmaz legelső sorára mutat. Az egyes
sorokat a FETCH utasítással nyerjük ki belőle, ilyenkor visszaadja azt a sort, amin állt, majd a
következő sorra ugrik. Használat után a kurzort le kell zámi (CLOSE). A kurzorokat általában
ciklusban szokták felhasználni, ahol m.inden egyes iterációban egy sort dolgozunk fel.
A kurzorváltozók hasonlóak a kurzorokhoz, azzal a különbséggel, hogy a kurzorváltozót
több lekérdezésre is meg lehet nyitni, új értéket kaphat, és alprogramok paramétere is lehet. A
kurzorváltozókhoz, ellentétben a kurzorokkal, nem a deklarációs részben rendelünk
lekérdezéseket, hanem a futás során.

3.4.Attribútumok
A PUSQL változóknak és kurzoroknak attribútumai vannak, aminek segítségével
utalhatunk egy elem adattipusára és struktúrájára anélkül, hogy azt állandóan
megismételnénk. Az attribútum jelölésére a %jel szolgál. Példaként nézzük meg a változókra
használható %TYPE és %ROWTYPE attribútumokjelentését.
ltfo TYPE: A %TYPE attribútum egy változó vagy adatbázisbeli tábla oszlopának
adattípusát adja meg.
ltfoROWTYPE: A PUSQL-ben rekordok szolgálnak a logikailag összetartozó adatok
csoportba gyűjtésére. A %ROWTYPE egy rekordot ad meg, melynek elemeinek típusa rendre
megegyezik a hivatkozott tábla oszlopainak a tfpusával.
l anyag rec anyag%ROWTYPE;

47
3.A PUSQL áttekintése Iváncsy Renáta

3.5.Programvezérlő utasítások
A programvezérlő utasítások a PUSQL legfontosabb kiterjesztése az SQL-hez képest. A
PUSQL nem csak azt engedi meg, hogy az adatot manipuláljuk az adatbázisban, hanem
lehetőséget ad ciklusok. feltételek definiálására, használatára. Ezáltal az adatokat könnyen fel
lehet dolgozni.
A feltételes utasítás
Gyakran egy feltétel alapján más utasítást akarunk végrehajtani. Ennek megoldására
szolgál az IF-THEN-ELSE utasítás, ami az IF kulcsszó mögött álló kifejezést kiértékeli, és
ha annak az eredménye igaz, elvégzi a THEN lrulcsszó után álló utasításokat, ha hamis, az
ELSE után állókat hajtja végre.
Ciklusok
Ciklusok segítségével egy utasítássorozatot tetszőleges számban ismételhetünk meg. Erre
valók a LOOP, a WHILE LOOP és a FOR LOOP utasítások. A LOOP segítségével egy
végtelen ciklust szervezhetünk meg. A WHILE LOOP addig hajtja végre az utasításokat, amig
a WHILE után álló kifejezés igaz. A FOR LOOP segítségével pontosan meghatározhatjuk a
végrehajtandó ciklusok számát.

3.6.Modularitás
A modularitás segítségével a programot logikailag kisebb egységekre lehet bontani. Így
egy komplex problémát meg lehet oldani több, egyszerű probléma megoldásávaL A PUSQL-
ben a modularitást a blokkokkal (blocks), alprogramokkal (subprograms) és csomagokkal
(packag es) biztosították.
Az alprogramokról (filggvények. eljárások) már esett szó, és későbbiekben részletesen
lesz tárgyalva.
A csomagok két részből állnak. A specifikációból és a törzsből. A specifikáció az
interfész a csomag és a program között, deklarálja a típusokat, konstansokat, változókat,
kivételeket, lrurzorokat és az elérhető filggvényeket és eljárásokat. A törzs definiálja a
lrurzorokat és megvalósítja a filggvényeket, eljárásokat.
A csomagok lényege, hogy a programok csak a deklarációt látják és érik el, a törzs rejtve
marad előlük. Csomagokat az Oracle szerveren is lehet fordítani és tárolni, ahol a tartalmukat
több program is megoszthatja egymás közt.

48
3.A PUSQL áttekintése lváncsy Renáta

3.7 .Kollekciók (Collections)


Tömbök, táblák
Lehetőség van tömbök és táblák definiálására. Egy tömb vagy tábla egy olyan típus,
aminek sok azonos típusú eleme van. Egy eleme azonban szintén lehet tábla vagy tömb, így
többdimenziós tömböket és táblákat is létrehozhatunk.
Relordok
A rekordok olyan adatstruktúrák, amik k:ülönbözö tipusú, de logikailag összefilggő

adatokat tartalmaznak.

3.8.0bjektumok
Az objektumok magukba foglalnak egy adatstruktúrát, és az adatok manipulálásához
szükséges filggvényeket, eljárásokat. Az objektumok változóit attribútumoknak (attributums)
nevezzük. a filggvényeket, eljárásait metódusoknak (methodes). Az objektumok, hasonlóan a
csomagokhoz szintén két részből állnak, egy specifikációból és egy törzsből.

3.9.Hibakezelés
A prograrnak végrehajtása során előfordulhatnak hibák. A PUSQL segítségével ezek a
hibák könnyen kezelhetők. Alapvetöen kétféle hiba létezik:
• rendszer által definiált hibák, amik két csoportra bonthatók tovább:
o az előre definiált (névvel ellátott) Oracle szerver hibákra, és
o az előre nem definiált (csak számmal azonosított) Oracle szerver hibákra,
• felhasználó által definiált hibák.
A rendszerhibák megadott eseményekre hívódnak meg, amiket a blokk EXCEPTION
részébe lehet lekezelni. A felhasználói hibákat deklarálni kell, majd a program egy részén a
RAISE utasítással generálni kell öket. Elkapni a felhasználói hibákat is az EXCEPTION
részben kell.

49
4.A PUSQL alapjai Iváncsy Renáta

4. A PL/SQL alapjai

4.1. Karakterek
Egy PUSQL program írásához a következő karaktereket használhatjuk:
• kis és nagybetük: a .. z, A. .Z,
• számok: 0 .. 9,
• szimbólumok: ( ) + - • l<> = ! -l\ ; : • ' @ % , " # S& _l { } ? [ ].
A PUSQL nem érzékeny a kis és nagybetükre, tehát a következő változókat azonosnak
tekinti:
LocalName
localname
l LOCALNAME
4.2.Megjegyzések
Mint minden programozási nyelvben, természetesen a PUSQL-ben is lehetőség van
megjegyzések (comments) írására a programban. Az egysoros kommenteket a dupla
minuszjellel jelölhetjOk (--). Ezzel megjelölhetünk egy kommentet a sor elején, vagy akár egy
programkód után is.
--itt kezdődik egy blokk
DECLARE
my student varchar2(20); --a my student változó deklarálása
Többsoros kommenteket a/* *l jelek közé zárva tehetünk.
/*
LOOP
i:=i+l;
END LOOP;
*l
A többsoros kommentekre megkötés. hogy nem lehet öket egymásba ágyazni.

4.3.Azonosítók
Azonosítókat a változók, konstansok, kivételek, kurzorok, kurzorváltozók, alprogramok
és csomagok azonosítására hasmálunk. Minden azonosítónak betllvel keD kezd6dnie, amit

50
4.A PUSQL alapjai Iváncsy Renáta

további betük. számok, dollátjel vagy aláhúzás követhet. Egyéb szimbólum használata az
azonosilókban nem megengedett. Az azonosiló mérete maximálisan 30 karakter lehet.
local-name --nem megengedett a kötőjel miatt
local name --megengedett
A PUSQL-ben szálnos foglalt szó van, amit nem használhatunk azonosílóként llyenek
például a tipusok. a programvezérlés szavai stb. (CHAR. BOOLEAN, WOP, IF, END,
THEN stb.).
Lehetőség van azonosítókat dupla aposztrófok (") közölt megadni. Ekkor az azonosító
bármilyen nyomtatható karaktert tartalmazhat, kivéve a dupla aposztrófot. Ezeknek az
azonosítóknak. is maximálisan 30 karakter lehet a hossza, beleértve a nyitó és záró
aposztrófokat is.
"on/off switch"
l. "local-name"
A PUSQL foglalt szavak az SQL -ben nem foglaltak, így lehetőség van olyan tábla, vagy
oszlopnevet definiálni, ami a PUSQL-ben foglalt szó. Gond akkor lép fel, ha a PUSQL-ben
ezekre a táblákra, mezők:re akarunk hivatkozni. Ha csak egyszeruen leújuk a nevüket, hibát
kapunk. Helyette aposztrófok (") közé kell őket tenni, és csupa nagybetüvel írni. Noha
megoldható, mégsem ajánlatos PUSQL foglalt szavakat használni SQL-ben.
SELECT ace, type, bal INTO ... FROM account --hibát okoz
SELECT ace, "TYPE",bal INTO _ FROM account --helyes megoldás

4.4.Literálok
A !iterál egy olyan explicit karakter, szám vagy boolean érték. ami nincs azonosílóhoz
kötve.
• Szám literálok: 6 -14 O +32568 -6.666 3,142857 2e4.
• Karakter literálok: 'z' '7' 'a'.
• Sztring literálok: 'Hello world! •.
Minden sztring, kivéve az üres és az egybetüs sztringet, ami karakter tipusú.
• Boolean literálok: true, false, null.
• Dátum literálok: '1998-12-25' '1997-10-13 10:22:14'.

4.5. Változók, konstansok


A program értékeket változókban és konstansokban tárol. A program futása során a
változók értékei változhatnak, de a konstansoké nem. Konstansokat és változókat bármely

51
4.A PUSQL alapjai Iváncsy Renáta

blokk, alprogram és csomag deklarációs részében lehet deklarálni. A deklaráció helyet foglal
az értéknek, a típusának megfelelően, és elnevezi a tárolás helyét, hogy tudjunk hivatkozni rá.
Néhány példa:
szuletesi datum DATE;
eletkor SMALLINT:=l;
Az első deklaráció elnevez egy dátum típusú változót. A második elnevez egy
SMALLINT tipusú változót, és értéket ad neki az értékadó operátor segítségéveL
A következő példában látható, hogy változó értékadó utasítás jobb oldalán állhat komplex
kifejezés is, és akár korábban deklarált, és érték.kel ellátott változó is.
pi REAL:=3.14159;
sugar REAL:=l;
terulet REAL:=pi * sugar**2;
Ha deklaráláskor nem adunk értéket egy változónak. akkor az NULL értékű lesz.
Megtehetjük azt is, hogy egy változónak megtiltjuk, hogy NULL értéket vegyen fel, ezt a NOT
NULL kulcsszó használatával érhetjük el. Ekkor azonban deklaráláskor mindenképp értéket
kell adni a változónak.
Konstans deklarálása a CONSTANT kulcsszó segítségével történik, és rögtön értéket kell
neki adni. Késöbb már nem is lehet, hiszen a konstans értéke a program során nem változhat.
Változók, konstansok inicializálására az értékadó operátor (:=) helyett használhatjuk a
DEFAULT kulcsszót is. Ez megadja az alapértelmezett értéket. Lássunk most néhány példát az
itt elmondottakra:
szuletesi datum DATE; --NULL az értéke, mert nincs
inicializál va
szuletesi datum DATE:=NULL; --NULL az értéke, mert NULL-ra
inicializáltuk
szuletesi datum DATE NOT NULL:='1979-may-02';
pi CONSTANT REAL:=3.14; --konstans deklarálása
vercsoport CHAR DEAFULT '0'; --alapértelmezett értékadás
%TYPE
A %TYPE attribútum egy változó vagy adatbázisbeli tábla oszlopának adattipusát adja
meg. Tegyük fel, hogy szeretnénk létrehozni egy változót az anyagok nevének tárolására. Az
anyag lábiában a anyag_nev oszlopban tároljuk az anyag nevét. Ehhez létrehozunk egy
my _ anyagnev változót, és azt szeretnénk, hogy típusa egyezzen meg az adatbázisban tárolt
oszlop típusával :

52
4.A PUSQL alapjai lváncsy Renáta

lmy anyagnev anyag.anyag nev%TYPE


Ennek a megoldásnak két előnye van. Egyrészt nem kell pontosan tudnunk az
adatbázisban tárolt adat tipusát, másrészről az adatbázisban ennek az oszlopnak a tipusa meg
is változhat, amely változást a változónk futási időben követni tud.

%ROW1YPE
A PUSQL-ben rekordok szolgálnak a logikailag összetartozó adatok csoportba
gyűjtésére. A %ROWTYPE egy rekordot ad meg, melynek elemeinek típusa rendre
megegyezik a hivatkozott tábla oszlopainak a tipusávaL Tegyük fel, hogy létrehoztunk egy
táblát az adatbázisban:
CREATE table diak (azonosito number(6), vezeteknev
varchar2(50), keresztnev varchar2(20));
A PUSQL programunkban szeretnénk egy rekordot létrehozni, amiben el tudjuk tárolni
ezen tábla egy sorát. Ezt a következöképpen tehetjük meg:
lmy student diak%ROWTYPE;
Ekkor a my _st u den t rekord egyes mezöinek a tipusa megegyezik a tábla oszlopainak a
tipusávaL A %ROWTYPE a lrurzorokkal is mük.ödik:
DECLARE CURSOR cl IS SELECT azonosito, vezeteknev FROM diak;
diak kurzor rec cl%ROWTYPE;
Ha a lrurzor úgy kap értéket, hogy a SELECT utasításban nem egyszerűen egy név van
megadva, hanem valamilyen kifejezés, akkor azt a kifejezést el kell nevezni (alias), hogy a
rekord mezöjeként késöbb tudjunk rá hivatkozni.
DECLARE
CURSOR my_cursor IS SELECT anyag_maxraktardb - anyag_raktardb
rendeles FROM anyag;
Ebben a példában az alias a rendeles, hiszen a SELECT listában egy kifejezés
szerepel.

4.6.Név konvenciók
A névkonvenciók egyformán vonatkomak minden program elemre, beleértve a
változókat, konstansokat, lrurzorokat, kurzorváltozókat, kivételeket, eljárásokat, fiiggvényeket
és csomagokat. Nevek lehetnek egyszerűek (simple/unqualified), azaz nem minösítettek,
minösítettek (qualified) és távoliak (remote). Tegyük fel, hogy van egy eljárásunk, a
fizetes _ emeles (),ekkor k:ülönbözö helyről k:ülönbözö módon hivatkozhatunk rá.

53
4.A PUSQL alapjai lváncsy Renáta

fizetes_emeles(); --simple/unqualified
dolgozo_esemenyei.fizetes_emeles(); --qualified
fizetes_emeles@miskolc(); --remete
dolgozo_esemenyei.fizetes_emeles@miskolc(); --qualified and
--remote
A:z elsö esetben egyszerűen használjuk az eljárás nevét. A második esetben az eljárás az
dolgozo_ esemenyei nevü csomagban van. ezért ha hivatkozni akarunk rá, azt úgy tudjuk

megtenni, hogy megnevezzük a csomagot, egy pontot teszünk, majd megnevezzük az eljárást
Minösített nevet olyan esetben is szokás alkalmazni, amikor a séma megjelölésével
hivatkorunk egy-egy adatbázis objektumra vagy tárolt programrészre. A harmadik esetben a
@ jellel egy távoli adatbázisban tárolt eljárásra hivatkozunk. A negyedik esetben együtt
használjuk a minösitett nevet és a távoli nevet.

4. 7.N évelfedés
Egy SQL utasításban az oszlop neve elfedi a PUSQL változó nevét. Például a következő

példában a DELETE utasítás hatására az összes anyag ki lesz törölve az anyag táblából,
nem csak a 'CUKOR' nevü, mivel az SQL a WHERE feltételben szereplö mindkét
anyag_ nev változót oszlopnévnek tekinti.
DECLARE
anyag nev VARCHAR2(10) :='CUKOR';
BEGIN
DELETE FROM anyag WERE anyag . anyag nev=anyag nev;
Ennek elkerülésére érdemes mindig más változónévvel elnevezni a PUSQL változónkat,
mint az oszlopokat. A másik megoldás, ha blokk címkét használunk. és a WHERE feltételben a
PUSQL változóra a címkével hivatkozunk.
<<main>>
DECLARE
anyag nev VARCHAR2(10) : ='CUKOR';
BEGIN
DELETE FROM anyag WERE anyag.anyag nev=main.anyag nev;

54
4.A PUSQL alapjai lváncsy Renáta

4.8.Azonositók hatásköre és láthatósága


Az azonosító hatásköre az a régió (blokk, alprogram, csomag, ciklus stb.) ahol az adott
azonositóra hivatkomi lehet. Egy változót egy régióban akkor nevezünk láthatónak, ha
egyszerűen a nevével tudunk hivatkomirá (wtqualified name).
Ha egy blokkban definiálunk egy azonosítót, akkor az a blokkban lokális lesz, de az
összes alblokk számára globális lesz. Ha egy globális azonosítót felüldefiniálunk egy
alblokkban, akkor csak az alblokkban definiált azonosító lesz látható, mert a külső blokkban
definiált azonosítóra csak a qualified (blokknev. azonos i tonev) nevével tudunk
hivatkozni. Hatásköre azonban mindkettőnek megmarad, hiszen tudunk rá hivatkozni. Egy
blokkon belül nem deklarálhatunk két azonos nevü azonosítót, de két külön blokkban igen.
Dyenkor ennek a két azonosítónak semmi köze nincs egymáshoz, ha az egyiken változásokat
hajtunk végre, az nem hat a másikra és fordítva. Az azonos színtü külön blokkokban deklarált
változókra a másik blokkban nem tudunk hivatkozni, mert a változó hatásköre nem nyúlik túl
a blokkon, ezek sem globálisak, sem lokálisak a másik blokkra nézve. Az alábbi blokk a
névelfedésre mutat egy példát. A DBMS_OUTPUT.PUT_LINE eljárás a kimeneti pufferbe
való írást jelenti. Részletesen erről az előre definiált csomagokról szóló fejezetben olvasható.
<<foblokk>>
DECLARE
a INT DEFAULT 10;
BEGIN
DBMS_OUTPUT.PUT_LINE(a);
DECLARE
a VARCHAR2 (25) : = 'hopihe';
BEGIN
DBMS OUTPUT.PUT_LINE(a);
DBMS_OUTPUT.PUT_LINE(foblokk.a);
END;
END;
A főblokkban definiálásra került az a változó, amit az alblokkban felül definiáltunk. A
kimeneten ezek után a következő fog állni:

55
4.A PUSQL alapjai lváncsy Renáta

4.9.Értékadás
A változókat és konstansokat m.inden blokkban vagy alprogramban inicializálni kell.
Amig egy változó nincs inicializálva, értéke NULL. Dyen a konstansoknál nem fordulhat elő,

mert azt deklaráláskor inicializálni kell.


A változók többféle módon kaphatnak értéket. Egyrészt inicializáláskor az értékadó
operátor vagy a DEFAULT kulcsszó segítségéveL A prograrnon belül pedig az értékadó
operátoron kívüllekérdezésböl, kurzorból, valamint alprogram kimenő paramétereként.
Az értékadó operátor(:=) használatával egyszerűen értéket adhatunk egy változónak.
DECLARE
anyag id INT;
anyag_nev VARCHAR2(20);
BEGIN
anyag id := 3;

END;
A változó értéket kaphat egy adatbázis lekérdezés során is. Itt nagyon fontos azt
megjegyezni, hogy a lekérdezésnek pontosan egy sorral kell visszatémie, különben hibát
kapunic Ha a lekérdezés egyetlen sorral sem tér vissza. a NO_DATA_FOUND hibát dobja a
rendszer, ha több mint egy sorral tér vissz a lekérdezés, akkor a TOO_MANY _ROWS kivétel
generálódik. (A kivételekről részletesen egy késöbbi fejezet szól). A lekérdezés eredményét
változóha a következő szintaktikával tehetjük:
SELECT oszlopl,oszlop2, ... INTO valtozol,valtozo2, •• FROM tabla ...
A SELECT és az INTO kulcsszavak között a lekérdezendő oszlopok nevei állnak. Az
INTO kulcsszó után állnak a változók, amibe az oszlopok értékét tároljuk el. Az oszlopok
számának, sorrendjének és típusának meg kell egyezni az I NTO kulcsszó mögött álló
változók számával, sorrendjével és típusávaL
Megjegyzendő, hogy más módon lekérdezést PUSQL blokkban nem is lehet megadni,
mindenképpen vagy egy kurzorban, vagy egy változóban el kell tárolni a lekérdezés
eredményét.
DECLARE
termekid INT;
tnev VARCHAR2(20);
tmennyiseg INT;
BEGIN

56
4.A PUSQL alapjai lváncsy Renáta

termekid := l;
SELECT termek_nev, termek_mennyiseg INTO tnev, tmennyiseg
FROM termek WHERE termek id = termekid;
END;
Hasonlóan az egysoros lekérdezéshez, a változó értéket kaphat lrurzorokból is. A
lrurzorokról késöbb még részletesen lesz szó. Az értékadás szintaktikája a következő, a
változókra vonatkozó feltételek megegyeznek a SELECT INTO esetén elmondottakévaL
FETCH kurzor INTO val tozol, val tozo2, ...
Az értékadás negyedik módja, ha a változó egy eljárás vagy egy filggvény kimenő

paramétereként szerepel. A filggvény vagy az eljárás lefutása után a változó az új értéket


tartalmazza.

4.10. Kifejezések és összehasonlitások


Egy kifejezés operandusokból és operátorokból áll. Az operandus egy változó, konstans,
!iterál vagy filggvény lehet, az operátor, pedig valamilyen müvelet. PUSQL-ben két tfpusú
operátor van: az egyoperandusú (unary), ami azt jelenti, hogy egy operandusra nézve müvelet
(ilyen például a negativ elöjel), és a kétoperandusú (binary), ez két operandus közti müveletet
jelent (ilyen például az osztás).

4.10.1. Az operátor precedencia

Az operátorok elvégzésének sorrendje van. Ha egy zárójel nélküli kifejezésben többfajta


operátor is szerepel, elvégzésüknek a sorrendjét a precedenciájuk adja meg. Az alábbi
táblázatban az operátorok percedenciáját nézhetjük meg PUSQL-ben (a legmagasabb
precedenciájú operátor a táblázat tetején van):
Operátor Mdvelet
•• Hatványozás
+,- Pozitív elöjel, negatív előjel
•,; Szorzás,osztás
+,-.ll ()sszeadás,kivonás,összefüzés
=,<,>,<=,>=,<>,!=,-=,"=,IS NULL, LIKE, ()sszehasonlitó műveletek
BETWEEN,IN
NOT Logikai negálás
AND Logikai ES kapcsolat
OR Logikai VAGY kapcsolat
o o

A magasabb precedenciáJÚ műveletek kerülnek hamarabb elvégzésre. Zárójelek


segítségével a precedenciát meg lehet változtatni. PL.:

57
4.A PUSQL alapjai lváncsy Renáta

8+6/2=11

1 (8+ 6) /2=7

4.10.2. Igazság táblák

AND OR
TRUE
NULL FALSE TRUE NULL FALSE
TRUE TRUE NULL FALSE TRUE TRUE TRUE TRUE
NULL NULL NULL FALSE NULL TRUE NULL NULL
FALSE FALSE FALSE FALSE FALSE TURE NULL FALSE
..
Ha egy kifeJezés több logikat operátort használ, és már az elsö lépésekben eldől, hogy mi
a kifejezés eredménye, akkor a PUSQL nem megy végig az összes operátoron, hanem ahol
megvan az eredmény, ott abbahagyja a Iciértékelést Például, ha több V AGY kapcsolatban a
PUSQL legalább egy TRUE értékűt talál, akkor nem folyatatja tovább a kiértékelést, hiszen
mindenképp TRUE lesz az eredmény.

4.10.3. Összehasonlftó operátorok


Operátor Jelentés
= Egyenlő
<> '=-= /\=
,. t , Nemegyenlő
< Kisebb
> Nagyobb
<= Kisebb vagy egyenlő
>= Nagyobb vagy egyenlő
Az IS NULL operátor
Az IS NULL operátor TRUE-val tér vissza, ha az operandus NULL, és FALSE-al, ha az
operandus nem NULL.

A LIKE operátor
A LIKE operátor karakterek, sztringek és CLOB értékek összehasonlítására szolgál.
Értéke TRUE, ha az összehasonlított sztringek megegyeznek, és FALSE, ha nem. Az
összehasonlító kifejezés két speciális karaktert tartalmazhat. A _ egy karaktert jelent, aminek
az értéke bármilyen lehet, a % nulla vagy több tetszőleges karaktert jelent. A LIKE operátor
után megadható egy escape karakter az ESCAPE kulcsszó segitségével. Dyenkor ennek a
karakternek a segítségével tudunk olyan karakterekre is rákeresni, amik eredetileg valamilyen
jelentéssei bírnak ( pl. aláhúzás, százalékjel, aposztróf).
l SELECT kamat from szamla WHERE kamat LIKE '5\%' ESCAPE '\'

58
4.A PUSQL alapjai lváncsy Renáta

A BETWEEN operátor
A BETWEEN operátor azt vizsgálja, hogy egy érték a megadott határokon belül van-e.

Nagyobb vagy egyenlö, mint az alsó határ és kisebb vagy egyenlö, mint a felsö határ. Ha igen,
TRUE-t ad vissza, ha nem FALSE-t.

Az IN operátor
Azt vizsgálja, hogy az adott érték egy halmazban megadott értékek valamelyikével
egyenl ö-e.

Az összefíiz6 operátor (ll)


Sztringek összefűzésére használható.

4.11. Beépített ffiggvények


A PUSQL-ben számos beépített ftlggvény támogatja a hatékonyabb programozást.
Vannak numerikus beépített filggvények, mint például az ABS, COS stb., vannak
karakterekkel operáló filggvények, mint például a CONCAT, REPLACE, TRIM stb., vannak
konverziós filggvények, mint például a TO_ DATE vagy a TO_ CHAR, vannak dátumokkal
foglalkozó filggvények, mint például a CURRENT_ DATE vagy a LAS T_ DA Y.
A TO_ DATE ftlggvénynek két bemenö paramétere van. Az elsö a dátum sztring típusként,
míg a második a formázó sztring. Például:
ITo DATE('2003-11-15','YYYY-MM-DD'l;
Gyakran használatos ftlggvény az NVL ftlggvény. Az NVL függvény elsö paramétere egy
oszlop, míg második paramétere egy érték. Ha az adott oszlop értéke null, akkor helyette a
második paraméterként szereplö érték kerül a lekérdezés eredményébe.

59
5.PUSQL programvezérlö utasítások lváncsy Renáta

5. PL/SQL programvezérlő utasítások


Program három alapvető programvezérlő struktúrából épülhet fel, a szekvenciális
utasításokból, az elágazó utasításokból és a ciklusokbóL
A szekvencia egyszeruen sorra végrehajtja az utasításokat. Az elágazó utasítás esetén egy
feltétel kerül kiértékelésre, melynek eredménye igaz vagy nem igaz lehet. Ha igaz (TRUE)
volt az eredmény, a program az egyik ágon folytatja az utasítások végrehajtását, ha nem igaz
(FALSE vagy NULL), akkor a másikon. A ciklus utasítások szekvenciáját hajtja végre
ismételve addig, amíg a feltétel igaz.

S.l.Feltételes utasitások
Az IF utasítás segítségével feltételtől ftlggően lehet végrehajtani egy utasítás sorozatot,
vagy egy másikat. Az IF utasitásnak három formája van. Az IF-THEN, az IF-THEN-ELSE
és az IF-THEN-ELS IF.

S.l.l. Az IF-THEN utasftás

IF feltétel THEN
<utasítások;>
END IF;
Ha a feltétel eredménye igaz, a THEN és az END IF kulcsszavak közötti utasítások
hajtódnak végre. Ha a feltétel eredménye hamís, vagy NULL, az END IF kulcsszó utáni
utasítással folytatódik a program. A feltétel részben több feltétel is megadható az AND vagy
az OR kulcsszavak hasmálatával. Az első esetben ÉS kapcsolatba, a második esetben V AGY
kapcsolatba kerülnek az egyes feltételek.

5.1.2. Az IF-THEN-ELSE utasítás

IT feltétel THEN
<utasitásokl;>
ELSE
<utasitások2;>
END IF;
Ha a feltétel kiértékelésének eredménye igaz, az utasí tá so kl fut Je, majd az END IF
után folytatódik a program. Ha a feltétel hamís vagy NULL eredményt ad, az utas i tások2
fog )efutni. Az ELSE ág további IF-THEN vagy akár IF-THEN-ELSE utasításokat
tartalmazhat.

60
S.PUSQL programvezérló utasítások lváncsy Renáta

5.1.3. Az IF-THEN-ELSIF utasítás

Ha több feltétel alapján szeretnénk dönteni, az IF-THEN- ELS IF utasítást lehet


választani.
IF feltétell THEN
<utasitásokl;>
ELSIF feltétel2 THEN
<utasitások2;>
ELSE
<utasitások3>
END IF;
Az IF utasitásnak bármennyi ELS IF tagja lehet, az ELSE pedig akár el is hagyható. A
feltételek kiértékelése sorban történik, a következő csak akkor kerül kiértékelésre, ha az elözö
eredménye FALSE volt vagy NULL. Ha egy feltétel eredménye igaz volt, az utána következő

utasítások végrehajtódnak, majd a vezérlés az END IF utáni sorra ugrik.

5.1.4. A CASE utasftás

A CASE utasítás használatával szintén egy utasítás sorozatot választhatunk ki lefuttatásra


egy feltételnek megfelelöen. Itt azonban a feltétel leginkább nem egy Boolean kifejezés,
hanem egy ún. szelektor.
[<<cimke>>]
CASE szelektor
WHEN kifjezésl THEN utasitások __ sorozatal;
WHEN kifjezés2 THEN utasitások..sorozata2;

WHEN kifjezésN THEN utasitások sorozataN;


[ELSE utasitások_ sorozataN+l;]
END CASE [cimke];
A CASE utasítás funkcionálisan megegyezik az IF-THEN-ELSIF utasítással, ha az
ELSIF utasításokban mindig ugyanarra a változóra adunk meg feltételt. A CASE utasítás
sokkal olvashatóbb, világosabb a struktúrája és rövidebb leírni, mint az IF-THEN-ELSIF
programvezérlő utasítást, ezért gyakran érdemesebb a CASE utasítást használni. Nézzünk meg
egy példát:
IF osztalyzat = '5' THEN
dbms_output.put_line('Jeles');
ELSIF osztalyzat = '4' THEN
dbms_output.put_line('Jo');
ELSIF osztalyzat = '3' THEN
dbms_output.put_line('Kozepes');
ELSIF osztalyzat = '2' THEN

61
5.PUSQL programvezérlő utasltások lváncsy Renáta

dbms output.put_line('Elegseges');
ELSIF osztalyzat = 'l' THEN
dbms_output.put line('Elegtelen');
ELSE
dbms_output.put line('Ilyen osztalyzat nem letezik');
END IF;

CASE osztalyzat
WHEN '5' THEN dbms - output.put line ('Jeles') ;
WHEN l 4 l THEN dbms _output.put_ l i ne ( 'J o' ) ;
WHEN '3' THEN dbms - output. put line('Kozepes');
WHEN '2 THEN dbms - output.put line('Elegseges');
l

WHEN ' l ' THEN dbms _output.put_ line('Elegtelen');


ELSE dbms_output.put_line('Ilyen osztalyzat nem letezik');
END CASE;
Mindkét esetben az osztalyzat változó értékétől ftlggően más és más lesz kiírva a
képernyőre. A CASE utasítás a CASE kulcsszóval kezdődik, majd utána található egy
szelektor. Ez a példánkban a osztalyzat változó volt. A szelektor lehet komplex kifejezés
is, akár ftlggvényhívást is tartalmazhat. A szelektor értéke nem kell, hogy boolean legyen,
lehet bármilyen más típusú is. A példában például karakter típusú. A szelektor kifejezés csak
egyszer hajtódik végre. A WHEN utasítások szekvenciálisan lesznek kiértékelve. A szelektor
értéke alapján választódik ki az az utasítás, ami végre lesz hajtva. Pl. Ha az osztályzat értéke 4
volt, a második WHEN utáni utasítás fog végrehajtódni, tehát a képernyőn a ,,Jo" eredmény fog
megjelenni. Ha egy WHEN-re már illeszkedett a szelektor értéke, akkor a WHEN utáni
utasítások végrehajtása után a vezérlés nem ugrik a következő WHEN-re, hanem az END
CASE utasítás után folytatódik a program.
Ha egyik WHEN feltételre sem illeszkedett a szelektor értéke, az ELSE mögött levő

utasítások fognak lefutni. Ha nem definiáltunk ELSE ágat, a program a CASE_ NOT_ FOUND
hibát generálja. A CASE utasítás, hasonlóan a blokkokhoz, címkét kaphat.

62
5.PUSQL programvezérlő utasltások Iváncsy Renáta

5.1.5. A SEARCHED CASE utasilás

A CASE utasítás egy másik formája a SEARCHED CASE utasiás. Ennek általános
formája a következő:
[<<címke>>]
CASE
WHEN keresési feltétell THEN utasítások_sorozatal;
WHEN keresési feltétel2 THEN utasítások sorozata2;

WHEN keresési feltételN THEN utasítások sorozataN;


[ELSE utasitások_sorozataN+l;]
END CASE [cimke);
A searched case utasításnak nincsen szelektora. A keresési fel tétel
eredményének boolean típusúnak kell lennie, nem lehet semmilyen más típusú.
CASE
WHEN osztalyzat='S' THEN dbms_output.put line('Jeles');
WHEN osztalyzat='4' THEN dbms_output.put line('Jo');
WHEN osztalyzat='3' THEN dbms_output.put line('Kozepes');
WHEN osztalyzat='2' THEN dbms_output.put_line('Elegseges');
WHEN osztalyzat='l' THEN dbms_output.put line('Elegtelen');
ELSE dbms_output.put_line('Ilyen osztalyzat nem letezik');
END CASE;
A kereső feltételek szekvenciálisan hajtódnak végre. Ha egy igazat adott, lefut a mögötte
álló utasítás. Ha egy WHEN utasítás lefutott, a program a következő utasításra ugrik. Az ELSE
ág ugyanúgy müködik., mint a CASE utasítás esetén. Ha egyik WHEN sem adott igazat, az
ELSE ág fut le. Ha az ELSE ág kimaradt, a PUSQL implicit a következő ELSE utasítást teszi
be:ELSE RAISE CASE_NOT_FOUND;

5.2.Ciklusok
A cik.lusok segítségével utasítások sorozatát tudjuk lefuttatni többször egymás után. A
ciklusoknak három formája van a PUSQL-ben: a LOOP, a WHILE-LOOP és a FOR-LOOP.

5.2.1. LOOP
A cikJus legegyszerűbb formája a LOOP.
[<<címke>>]
LOOP
<utasítások sorozata;>
END LOOP [címke];

63
5.PUSQL programvezérlő utasítások Iváncsy Renáta

A ciklus m.inden iterációjában az utasítások szekvenciája lefut, majd a vezérlés ismét a


ciklus elejére ugrik. Ha ki akarunk lépni a ciklusból, akkor az EX I T utasítást kell
használnunk. Ha nem szerepel EX I T utasítás a ciklusban, a ciklus végtelen ciklus lesz.

S.:Z.:Z. Az EXIT utasitás


A ciklusból kilépő utasításnak két formája van: az EXIT és az EXIT-WHEN. Az EXIT
utasítás hatására feltétel nélkül tudunk kiugran i a ciklusbóL Természetesen, ha egy IF
utasításon belül használjuk, akkor az IF feltétel alapján fog végrehajtódni. Az EXIT
utasítással kiugorhatunk egy ciklusból, de oem ugorhatunk ki egy blokkból.
LOOP

IF credit rating < 3 THEN

EXIT; -- azonnal kiugrik a ciklusból


END IF;
END LOOP;
- - Az EXIT után a vezérlés ide kerül
Az EXIT-WHEN utasításnál megadhatunk egy feltételt, amire a ciklusból kiugrunk.
ii:=l ;
LOOP

ii:=ii+l;
EXIT WHEN ii=lO; -- kilép a ciklusból, ha a feltétel igaz

END LOOP;

Amíg a feltétel kiértékelésének az eredménye hamis, a ciklus folytatódik, ha igaz, a


vezérlés kiugrik a ciklusbóL Ezért fontos, hogy ha nem akarunk végtelen ciklust, a feltétel
értékének változnia kell a cikluson belül. A példánkban az i i núnden egyes alkalommal
megnöveli eggyel az értékét Ha eléri a l O-t, a ciklus véget ér. Ha egymásba ágyazott ciklusok
vannak az EX I T csak abból a legbelső ciklusból lép ki, amiben ő található. Ha egy külsö
ciklusból is ki szeretnénk ugrani, az EXIT után meg kell adni annak a ciklusnak a cimkéjét,
amiböJ ki szeretnénk ugrani.

64
S.PUSQL programvezérlő utasítások lváncsy Renáta

<<outer>>
LOOP

LOOP

EXIT outer WHEN ... - mindkét ciklusból kiugrik


END LOOP;

END LOOP outer;

5.2.3. WIDLE-LOOP
A WH I LE ciklus megad egy feltételt, amíg az igaz, a ciklus lefut, ha hamis vagy NULL ,
az END LOOP utáni utasításon folytatja a program a végrehajtást. Formája:
WHILE <feltétel> LOOP
<uatsitások __ sorozata;>
END LOOP;
Mielött a ciklus lefutna, a feltétel kiértékelődik, és az eredménynek megfelelöen vagy
belép a ciklusba, vagy átugorja azt. Mivel ez elöl tesztelős ciklus, előfordulhat, hogy egyszer
sem hajtódnak végre a cikluson belüli utasítások.
WHILE osszraktar <= 25000 LOOP

SELECT anyag_raktardb INTO raktar FROM anyag WHERE ...


osszraktar .- osszraktar + raktar;
END LOOP;
A fenti példában nem tudjuk pontosan, hogy hányszor fog lefutni a ciklus, de ha a
osszraktar nagyobb lesz, mint 25000, akkor befejeződik.

5.2.4. FOR-LOOP
Az eddigiekben olyan ciklusokat láttunk, ahol a ciklusok végrehajtásának a számát nem
tudtuk előre, valamilyen kifejezés értéke alapján léptünk ki a ciklusbóL Lehetőség van
azonban olyan ciklus létrehozására, ahol pontosan tudjuk, hogy hányszor fog végrehajtódni.
Ilyen ciklus a FOR-LOOP. Formája a következő:
<<cimke>>
FOR ciklus_ számláló IN [REVERSE) alsó határ .. felső határ LOOP
<utasitások_ sorozata;>
END LOOP;

65
5.PUSQL programvezérlő utasítások lváncsy Renáta

A FOR ciklusban definiálunk egy szám.lálót, amely m.inden egyes ciklus lefutáskor ~
növeli az értékét Az alsó_határ és a felső_határ között veszi fel az értékét,
induláskor az alsó_határ az értéke, és amikor eléri a felső_határ-t, a ciklus leáll.
Lehetőség van arra is, hogy a ciklusváltozó lefele számoljon. Ha a REVERSE kulcsszót is
beleíJjuk a FOR ciklus formájába, akkor a felső_határ-tól fog indulni, és egyesével
csökken, míg el nem éri az alsó_határ-t. Ha a két határérték értéke megegyezik, a ciklus
pontosan egyszer fog végrehajtódni. Ha az alsó_határ értéke nagyobb, mint a
felső_ határ-é, akkor a ciklus egyszer sem hajtódik végre. A FOR ciklus ciklusszámlálóját
nem kell külön deklarálni, az implicit deklarálódik a ciklusba lépéskor. A FOR ciklus
számlálója nem kaphat értéket a cikluson belül, de állhat értékadás jobb oldalán. Ha a ciklus
befejezödött, a ciklus számlálójára már nem is hivatkozhatunk, mert a cikluson kívül
érvénytelen változó. A FOR ciklus számlálójának dinamiirusan is megadhatjuk az értékét
Ha a FOR ciklus számlálójának neve megegyezik a blokk egy globális változójának
nevével, akkor a FOR cikluson belül a számláló elfedi a globális változót. Ha mégis a globális
változóra szeretnénk hivatkozni, akkor a blokknak eimkét kell adni, és azon keresztül kell
hivatkozni a globális változóra:
<<main>>
DECLARE
ctr INTEGER;
BEGIN
FOR ctr IN 1 .• 25 LOOP
IF main.ctr > 10 THEN -- refers to global variable
END IF;
END LOOP;
END main;
A láthatóság ezen szabálya érvényes az egymásba ágyazott ciklusokra is. A FOR ciklus is
kaphat címkét, és ha egy belső cikluson belül a külső ciklus számlálójára szeretnénk
hivatkozni, használni kell a külső ciklus cimkéjét.
Az alábbi példában a járat táblát szeretnénk automatikusan kitölteni. A város tábla
minden városába megy egy járat Budapestről, és másnap visszafele is jön egy járat. A
megoldásban a tábla legkisebb és legnagyobb város azonosítói alapján megyünk végig, és ha
tartozik az adott ciklusváltozóhoz város, akkor a megfelelő adatokat beszúrjuk a járat táblába.

66
S.PUSQL programvezérlö utasítások lváncsy Renáta

DECLARE
Varasminid varas.varas id%TYPE;
Varasmaxid varas.varas id%TYPE;
Isvarasid INT;
Bpid INT;
Cel jarat.jarat celhely%TYPE;
BEGIN
SELECT min(varas id), max(varas id)
INTO varasminid, varasmaxid FROM varas;
SELECT varas id INTO bpid FROM varas
WHERE UPPER(varas_nev) = UPPER('BUDAPEST');
FOF i IN varasminid .. varasmaxid-1 LOOP
IF (i != bpid) THEN
SELECT COUNT(varas_nev) INTO isvarasid
FROM varas WHERE varas id = i;
IF isvarasid != O THEN
SELECT varas nev INTO cel FROM varas
WHERE varas id = i;
INSERT INTO jarat VALUES
(jaratseq.NEXTVAL,50,'Budapest',cel,sysdate);
INSERT INTO jarat VALUES
(jaratseq.NEXTVAL,SO,cel,'Budapest',sysdate+l);
COMMIT;
END IF;
END IF;
END LOOP;
END;

67
5.PUSQL programvezérlö utasítások lváncsy Renáta

S.l.S. A GOTO utasitás

Lehetőség van a prograrnon belül megadott eimkére ugrani. Oyenkor a programvezérlés a


megadott címkét követő utasításon folytatja a programot. A GOTO utasítás csak futtatható
sorra mutathat vagy egy blokk elejére. Ha mégis olyan helyre szeretnénk ugrani, ahol nincs
futtatható sor, például egy FOR ciklus végére (END), akkor hasmálhatjuk a NULL utasítást,
ami nem csinál semmit, de mégis futtatható utasitásként szerepel:
FOR i IN 1 .. 50 LOOP
IF done THEN
GOTO end_loop;
END IF;

<<end_loop>>
NULL; futtatható utasítás
END LOOP;
Megkötések a GOTO utasftásra:
• GOTO utasítással nem ugorhatunk egy IF utasításba be
• GOTO utasítással nem ugorhatunk be a blokkon belüli alblokkba
• GOTO utasítással nem ugorhatunk ki egy alblokkból
• GOTO utasítással nem ugorhatunk az EXCEPTION részből az ahhoz tartozó blokk
futtatható részébe

68
6.PUSQL adattípusok lváncsy Renáta

6. PL/SQL adattipusok
Minden változónak. konstansnak és paraméternek meg kell adni, hogy milyen tipusú. A
típus határozza meg, hogy milyen formában kell tárolni az adatokat, milyen megkötések
érvényesek rá, és hogy milyen tartományon belül vehetik fel az értékeiket. A PUSQL-ben
léteznek előre definiált adattípusok, és a felhasználó által definiált altipusok.

6.1.Eiőre defmiált adattipusok


A skalár típus egyetlen értéket tárol, míg az összetett (composite) tipus több, külön
kezelhetö belső értékből áll. A referenciatipus mutatókat tárol, ami más program elemre
mutat. A LOB tipus ún. LOB lokátorokat tárol, ami megadja a nagy objektumok helyét (pl.
grafikus képek).
A skalár tipusoknak 4 családja van:
• Number
• Character
• Boolean
• Date
A character és number tipusok további altipusokkal rendelkeznek, melyek az
alaptipusra épülnek, ahhoz képest megkötéseket tartalmaznak.

6.1.1. Alap skalár típusok

NUMBER[ (precision,scale)]:
Numerikus értékek (fix, lebegőpontos) tárolásának alaposztálya.

CBAR[(maximum _length [CHARJBYTE])]


Fix hosszúságú alfanumerikus értékek tárolására szolgáló adattipus alaposztálya. A
maximum hossza 32767 byte lehet. Ha nem adunk meg paraméterben semmit, l hosszúságú
karaktert definiáltunk. Megadható, hogy a hosszat karakterben vagy byte-ban adjuk meg.
Figyelni kell arra, hogy egy karakter nem feltétlenül egy byte hosszú, vannak 2, illetve 3 byte
hosszú karakterek is. A maximális hosszt nem lehet változó segítségével megadni, numerikus
literált kell hozzá használni.
Ha nem adjuk meg, hogy miben adtuk meg a hosszt, az alapértelmezett érték az
NLS _LENGTH_ SEMANT !CS inicializáló paraméterben található meg.

69
6.PUSQL adattipusok lváncsy Renáta

Azt is meg kell jegyezni, hogy noha a PUSQL-ben a karakter hossza elég nagy lehet, az
adatbázisban csak 2000 byte hosszú karaktereket tudunk eitároini

V ARCHARl(maximum_Iength[CHARIBYTE])
Változó hosszúságú karakter alaptípusa. Hossza maximálisan 32767 byte lehet. Itt is
megadható, hogy karakterben vagy byte-ban értjük a maximális hosszat. Ha nem adjuk meg,
hogy miben adtuk meg a hosszt, az alapértelmezett érték az NLS_LENGTH_SEMANTICS
inicializáló paraméterben található meg. Az adatbázisban tárolható méret 4000 byte.

LONG
Változó bosszúságú karakter alaptípusa. A LONG adatbázis mezö maximális hossza
214783647 byte lehet. A visszafele kompatibilitás támogatása érdekében használható, helyette
basználjunk inkább LOB típusú oszlopokat adatbázis táblákban.

DATE
Dátumot és időt lehet tárolni benne. Mezői: év, hónap, nap, óra, perc, másodperc, időzóna

óra, időzóna perc, időzóna régió. Tartománya i.e. 4 712 jan. l és 9999. dec. 31 között mozog.

LONGRAW
A bináris adat és byte sztringek alaptípusa. Hossza maximálisan 32760 byte lehet. LONG
RAW nincs a PUSQL-ben interpretálva.

BOOLEAN
Alaptípus, ami három értéket tud tárolni: TRUE, FLASE vagy NULL.

BINARY_INTEGER
Egész számok tárolására alkalmas. Értéktartománya: -2147483647 és 2147483647
(-2 31 -1...2 31 -1) közötti.

PLS INTEGER
Előjeles egészek tárolására alkalmaz. Értéktartománya -2147483647 és 2147483647
(-2 -1...2 -1) között lehet. Tárolása kevesebb erőforrást igényel, mint a NUMBER típusú
31 31

adatok tárolása. A PLS _INTEGER müveletek gyorsabbak., mint a NUMBER és


BINARY _INTEGER müveletek. mert nem könyvtári aritmetikát használnak, hanem hardver

aritmetikát. Ugyan a BINARY_INTEGER és a PLS_INTEGER értéktartománya megegyezik,


a két tipus mégsem egyforma, mert ba a PLS _I NT EGER túlcsordul, kivétel generálódik, mig
ba a BINARY INTEGER csordul túl, de egy NUMBER típusúnak adjuk értékül, nem
keletkezik hiba.

70
6.PUSQL adattipusok Iváncsy Renáta

6.2.LOB típusok
A LOB tipussal strukturálatlan, nagy adathalmazokat lehet tárolni az adatbázisban, vagy
az operációs rendszer fájlrendszerében. Az adat mérete elérheti akár a 4Gbyte-t is. llyen
adathalmaz lehet pl. Text, grafikus kép, videó klipek stb.

B FILE
A BFILE (binary file) nagy bináris fájlok tárolására szolgál az operációs rendszer
fájlrendszerében, az adatbázison kívül.

BLOB
A BLOB (binary large object) nagy bináris objektumok tárolására szolgál az adatbázisban.

CLOB
A CLOB (character large object) egy byte-os karakterek nagy blokkjainak a tárolására
szolgál az adatbázisban.

N C LOB
Az NCLOB (national language character object) NCHAR tipusú adatok nagy blokkjainak
tárolására szolgál az adatbázisban.

6.2.1. Altipusok
Az altípusok az alaptfpusra épülö tipusok, melyek valamilyen megszorítást tartalmaznak
az alaptipushoz képest.

BINARY_INTEGER altipusok
Az alábbi altípusok mind valamilyen megszorítást tartalmaznak az alaptipushoz képest.
NATURAL Nem negativ vagy QOzitiv számok
NATURALN Mint a NATURAL, csak nem veheti fel a O-t értékként.
POSITIVE Pozitiv számok
POSITIVEN Mint a POSITIVE, csak nem veheti fel a O-t értékként.
SIONTYPE Ertéke -1,0,1 lehet.
NUMBER altipusok
DEC Fixpontos szám, maximum 38 tizedes j egyen ábrázolva
DECIMAL Fixpontos szám, maximum 38 tizedes j egyen ábrázolva
DOUBLE PRECISION Lebegőpontos szám, maximum 126 bináris digiten ábrázolva
FLOAT Lebegőpontos szám, maximum 126 bináris digiten ábrázolva
INTEGER Egész szám, maximum 38 tizedes j egyen ábrázolva
INT Egész szám, maximum 38 tizedes j egyen ábrázolva
NUMERIC Fixpontos szám, maximum 38 tizedes j egyen ábrázolva
REAL Lebegőpontos szám, maximum 63 bináris digiten ábrázolva
SMALLINT Egész szám, maximum 38 tizedes j egyen ábrázolva

71
6.PUSQL adattípusok lváncsy Renáta

V ARCHARl altfpusok
STRING
VARCHAR

6.3.Programozó által definiált tipusok


A programozónak is lehetősége van tipusok definiálására. Ezek az előredefiniált tipusok
altipusai lesznek bizonyos kívánt megkötésekkeL
SUBTYPE altipus_név IS alaptipus[(megkötés)] [NOT NULL];
Néhány példa:
SUBTYPE CHARACTER IS CHAR;
SUBTYPE mytype IS NUMBER NOT NULL;
SUBTYPE mychar IS CHAR(lO);

6.4.Adattfpus konverzió
Néha szükség van egy adattípusból egy másikba váltani. A PUSQL támogatjamind az
explicit, mind az implicit adatkonverziót

6.4.1. Explicit konverzió


Vannak a PUSQL-ben beépített ftlggvények, amelyek segítségével bizonyos adattipusok
között tudunk váltani. Például ha egy karakter típusú értéket dátumként vagy számként
szeretnénk megjeleníteni, használhatjuk a TO_ DATE vagy a TO_ NUMBER beépített
filggvényeket, vagy fordítva, dátumból vagy számból karakterré a TO_ CHAR filggvénnyel
konvertálhatunk.

6.4.2. Implicit konverzió


Ha van értelme, a PUSQL implicit is elvégzi az adatkonverziót Ennek következtében
lehetőségünk van más tipusú változókat, literálokat és paramétereket használni, mint amilyet
az adott helyen használni kellene. Az alábbi példában a start_time és a finish_time
sztring értékeket tartalmaznak, az éjfél óta eltelt idöt adják meg. A kettő különbségének
értékét egy NUMBER típusú változóha kéne betölteni. A PUSQL ezt a konverziót
automatikusan megteszi:

72
6.PUSQL adattipusok Iváncsy Renáta

DECLARE
start time CHAR(5);
finish time CHAR(5);
elapsed_time NUMBER(5);
BEGIN
/* Rendszeridő kiolvasása . */
SELECT TO_CHAR(SYSDATE, 'SSSSS') INTOstart time FROM
sys.dual;
valamit csinál
/* Rendszeridő ismételt kiolvasása*/
SELECT TO_CHAR(SYSDATE, 'SSSSS') INTO finish time FROM
sys.dual;
/* Az eltelt idő kiszámítása. */
elapsed_time := finish time - start time;
INSERT INTO results VALUES (elapsed_time, ... );
END;
Noha a PUSQL, amikor lehetséges, megteszi az adatkonverziót, mégis érdemes az
explicit adatkonverziót használni, hiszen így biztosak lehetllnk benne, hogy azt az eredményt
kapjuk, amit vártunk.

73
7.PUSQL összetett adattípusok lváncsy Renáta

7. PL/SQL összetett adattipusok


Az összetett adattípusok (Composite datatypes) olyan adattípusok, melyek tartalmaznak
belső komponenseket A PUSQL-ben három összetett adattípus létezik: a rekord (record)
típus, a tábla (table) típus és a tömb (varray) típus. A rekord típus jellegzetessége, hogy
elemeinek típusa változó lehet. A tábla és a tömb típusok (amiket gyűjtőnévvel Collections-
nak is szoktak nevezni) elemeinek a típusa azonban azonos.

7.1.A PL/SQL rekord tipus


A rekord valamilyen szempont szerint összetartozó elemek csoportja, amiket a rekord
mezőiben tárolunk. Minden elemnek saját neve és adattípusa van. Tegyük fel, hogy egy diák
adatait szereblénk eltárolni. A diák tárolni kívánt adatai a következők: név, lakcím, születési
dátum, törzsszám és egyetem kezdésének időpontja. Ezek az adatok logikailag kapcsolatban
vannak egymással, hiszen egy diákot irnak le, de típusuk különböző . Tárolhatnánk őket külön
változókban, de ha már több diákunk van, akkor lassan elvesznénk a változóink között. A
másik, és ajánlatos, megoldás egy rekord típus definiálása. Ekkor egy rekord egy diákot ir le.
A rekord mezöi pedig a tárolni kívánt adatokra fognak hivatkozni. A diákot leíró változót
ekkor a definiált rekord típusúra kell definiálni.
DECLARE
TYPE diak record_tipus IS RECORD
(nev varchar2(50),
eim varchar2(100),
szuletett date,
torzsszam number(6),
kezdet date);
diak diak_record_tipus;
BEGIN

END;
A rekord típus deklarálásának formája:
TYPE tipus_név IS RECORD (mez6_deklaráció[,mező_deklaráció] ... )
Ahol a mezö deklaráció formája a következő:
mezó_név mező_tipus [[NOT NULL] {: = l DEFAULT} kifejezés]
A típus_név a rekord típus neve lesz. A mező_név a rekordon belül tárolt mezők

nevei. Egy mező típusa bármely PUSQL típus lehet, kivéve a REF CURSOR típust. A rekord

74
7.PUSQL összetett adattípusok lváncsy Renáta

típus deklarálása után létre kell hozni egy változót, ami az adott típusú változó lesz. Ilyen
módon létrejön egy rekord. A rekord egyes mezöire a
rekord- név.mező - név
szintaktikával hivatkozhatunk.
A rekordnak többféleképpen lehet értéket adni. Az egyik mód, hogy az egyes mezöknek
külön adunk értéket az értékadó operátor segítségéveL Másik lehetőség a rekord
értékadásának a SELECT-INTO vagy a FETCH-INTO utasítás használata. Ekkor ügyelni
kell arra, hogy a rekord és a SELECT-ben vagy a lrurzorban szereplő adatbázis tábla használt
oszlopainak a típusa megegyezzen. Egyik rekordot értékül adhatunk egy másiknak. ha azonos
típusúak.
Mint ahogy arról már korábban volt szó, rekordot létrehozhatunk a %ROWfYPE
operátor segítségéveL Ekkor a rekord mezöinek neve és típusa sorra a hivatkozott tábla
oszlopainak neve és típusa lesz.
Bármely a felhasználó által definiált rekord soha nem lesz azonos típusú egy %ROWTYPE-
allétrehozott rekorddaL
A rekordokra jellemző tulajdonságok:
• Minden rekordnak annyi mezője lehet, amennyire szükség van.
• Rekordnak deklaráláskor is értéket lehet adni, és használhatjuk rá a NOT NULL
kulcsszót.
• Ha a rekord valamelyik mezöjét nem inicializáljuk, értéke NULL lesz.
• A rekord mezöinek definiálásakor használható a DEFAULT kulcsszó.
• Rekordot bármely alprogram, blokk és csomag deklarációs részében
deklarálhatunk.
• Rekord eleme is lehet rekord, így lehetőség van beágyazott rekordok használatára.
Az alábbi példában három rekordot hozunk létre. Az u t as_ re c_ type típus az utasok
adatainak a tárolására szolgál. A hotel_rec rekord a hotel adatai tárolására szolgál, a
%ROWTYPE segítségével került deklarálásra. A jarat_rec_type a járat adatait tárolja,
ahol az egyes mezők deklarálására a %TYPE operátor is felhasználásra került.
DECLARE
TYPE utas rec_type IS RECORD

id int,
nev varchar2(50),
utlevelszam char(8)

75
7.PUSQL összetett adattipusok I váncsy Renáta

) ;

utas rec utas rec type;


hotel rec hotel%ROWTYPE;

TYPE jarat rec type IS RECORD

id jarat.Jarat id%type,
ind jarat.jarat indulasihely%type,
cel jarat.jarat_celhely%TYPE,
ferohely int NOT NULL DEFAULT 80
) ;

jarat rec jarat rec type;

BEGIN
SELECT utas id, utas nev,utas utlevelszam INTO utas rec
FROM utas where utas id = l;
DBMS OUTPUT. PUT LINE (utas re c. id l l 1

1
ll
utas rec.nev);
SELECT * INTO hotel rec FROM hotel WHERE hotel id = l;
DBMS_OUTPUT.PUT_LINE(hotel rec.hotel_nev l l 1 1
ll
hotel rec.hotel_varos);
SELECT jarat.jarat_id, jarat.jarat_indulasihely,
jarat.Jarat celhely, jarat.jarat ferohely
INTO jarat rec
FROM jarat WHERE jarat id = l;
DBMS_OUTPUT.PUT_LINE(Jarat rec.ferohely);
SELECT jarat.jarat_id, jarat.jarat_indulasihely,
jarat.jarat_celhely, jarat.jarat ferohely
INTO jarat_rec
FROM jarat WHERE jarat id = ll;
DBMS OUTPUT.PUT_LINE(jarat rec.ferohely);
END;

76
7.PUSQL összetett adattípusok lváncsy Renáta

7.2.PUSQL tömb tipusok (varrays)


A tömbök sok. azonos típusú elemet tartalmaznak. Az egyes elemek sorban követik
egymást a tömbben, rájuk hivatkozni indexszel lehet. Ha például van egy szamok nevű

tömbünk, amiben NUMBER típusú adatokat tárolunk, akkor a tömb 5. elemére a szamok (5)
szintaktíkával lehet utalni. (Az index kerek zárójelben van!) A tömbök előnye, hogy az
adatokat egyszerre is tudjuk kezelni, de egyesével is tudunk hivatkozni a tömb bármely
elemére. A tömböknek meg kell adni a maximális méretét, amit a deklarációs részben
tehetünk meg. A tömbnek fix alsóhatára van (a legkisebb index mindig l), de növelhető

felső határa. Ha például egy maximum l O hosszúságú tömbben csak 4 elem van, akkor a felső

határa 4, de növelhetö újabb elemek hozzáadásával. Ezt a növelést azonban csak addig
folytathatjuk. míg el nem érjük a maximális méretet.

7.2.1. Tömb deklar'l'sa


Egy tömb deklarálásának szintaktíkája a következöképpen néz ki:
TYPE tipus _név IS {VARRAY l VARYING ARRAY} (maximális_méret)
OF elem_tipus [NOT NULL];
Ahol a t ip us_ név a tömb típus neve, amihez késöbb rendelhetünk tömböt. A
maximális_ méret egy pozitív szám, ami megadja a tömb maximális méretét. Az
e l em_ t í p us a tömbben tárol elemek típusát adja meg, ami bármilyen típusú lehet az
alábbiakat kivéve:
• BINARY_INTEGER, PLS INTEGER
• BOOLEAN
• BLOB, CLOB (csak a varray-ra megkötés)
• LONG, LONG RAW
• NATURAL, NATURALN
• NCHAR, NCLOB, NVARCHAR2
• BLOB vagy CLOB attribútumokkal rendelkező objektum
tipusok (csak a varray-ra megkötés)
• TABLE vagy VARRAY attribútumokkal rendelkező objektum
típusok
• POSITIVE, POSITIVEN
• REF CURSOR
• SIGNTYPE
• STRING

77
7.PUSQL összetett adattipusok Iváncsy Renáta

7.2.2. Tömb inicializálása


Amíg nem inicializáltuk, a tömb tipusú változó automatikusan NULL értékü. Ez azt
jelenti, hogy maga a kollekció NULL értékü, nem pedig azt, hogy az egyes elemeinek az
értéke NULL. A tömb inicializálásához konstruktort kell használni, ami egy rendszer által
definiált függvény, ugyanazzal a névvel, ami a tömb tipus neve is. A ftlggvény bemenő

paraméterei a tömb inicializáló elemei. Meghívásakor feltölti a tömböt a bemenetként


megadott elemekkeL Nem kell az egész tömböt inicializálni. Amennyiben egyetlen elemet
sem adunk meg, úgy létrejön egy üres, de nem NULL tábla. Az inicializálást rögtön a
deklarálásnál is megtehetjük.
Példa tömb deklarálására és inicializálására:
DECLARE
TYPE tomb_tipus IS VARRAY(5) OF INT;
tomb tomb_tipus;
BE GIN
tomb .- tomb tipus(1,7,8); --a tömb inicializálása 3 elemmel
FOR i IN 1 .. 3 LOOP
DBMS OUTPUT.PUT LINE(tomb(i));
END LOOP;
tomb(3) .- 14;
END;
A tömb sürű kollekció. Ez azt jelenti, hogy az elemei szorosan követik egymást. A
második elemet addig nem adhatjuk meg, amig az első nem került inicializálásra. Mivel a
tömböket lehet úgy is inicializálni, hogy nem adjuk meg az összes elemet, valahogy
lehetöséget kell adni arra is, hogy a többi elemnek is értéket adhassunk. Erre szolgál az
EXTEND metódus. Az EXTEND metódussal eggyel meg tudjuk növeini a tömb méretét,
mindaddig, míg el nem érjük a deklaráláskor megadott maximális méretet. A tömb maximális
méretét a LIMIT metódussal kérdezhetjük le. Az alábbi példa létrehoz egy l O elemű tömböt,
és feltölti páros számokkal.
DECLARE
TYPe tomb_tipus IS VARRAY(10) OF INT;
tomb tomb_tipus;
BEGIN
tomb := tomb tipus();
FOR i IN l .. tomb.LIMIT LOOP

78
7.PUSQL összetett adattipusok lváncsy Renáta

tomb.EXTEND;
tomb (i) . - 2* i;
END LOOP;
END;

7.2.3. Hivatkozás a tömb elemeire


A tömb elemeire az index segítségével lehet hivatkozni. Az index l-től a deklaráláskor
megadott maximális méretig mehet.
tombvaltozo(index);
Amennyiben egy függvény visszatérési értéke tömb típusú, úgy az elemeire a
következöképpen tudunk hivatkozni:
függvény_név(paraméter_lista) (index)

7.3.PUSQL táblák
A PUSQL-ben kétfajta tábla típust definiáltak, az úgynevezett nested táblát (nested table)
és az index-by táblát (index-by table).

7.3.1. A nested tábla


A nested táblát az adatbázisban úgy tekintjük, mint egy egyoszlopos táblát. A PUSQL
nested táblák olyanok, mint az egydimenziós tömbök. Két dologban különböznek egymástól:
egyrészről a tömbök fix hosszúságúak lehetnek, mig a nested táblák dinamikusan változtatják
méretüket. Másrészről a tömbökben az elemeknek szorosan egymás után kell következniük
(dense), a nested táblákban is szorosan követik egymást az elemek, míg k.i nem törölünk
közülük egyet. Ekkor ritkává (spare) válnak. A tömbből nem lehet törölni.
Array ol ln»gCirs

1321 l 17 l gg 1407 l 83 l 822 1105 l 1g l 87 1278 ll f1XIId


Uppor
Bcu~
X!1) ~2) ~3) ~4) X! 5) ~ 6) ~7) ~8) ~9) X(1 0)

Unbou~lld

~1) ~3) ~4) ~ 6) ~7) ~8) x(10)

Mivel a nested táblából lehet törölni, így lukak maradhatnak benne. Ez azonban nem okoz
gondot az elemek szekvenciális elérésében, mert definiálva van egy NEXT nevü függvény,
aminek segítségével mindig a következő, nem törölt elem indexét kaphatjuk meg.
Egy nested tábla típust a következöképpen adhatunk meg:
TYPE tipus_név IS TABLE OF elern_tipus [NOT NULL];

79
7.PUSQL összetett adattipusok Iváncsy Renáta

A szintaxisban szereplö típus név és elem_tipus-ra vonatkozó megjegyzések


megegyeznek azokkal, amik a tömböknél találhatóak.
A nested táblák eltárolhatóak az adatbázisban tábla oszlopaként. Egy eltárolt nested
táblára használható a SELECT, INSERT, UPDATE és DELETE utasítás.
A nested táblákat azonos módon kell inicializálni, mint a tömböket. Ha egy nested táblát
nem inicializálunk, automatikusan NULL értékű lesz. Ha meg akaijuk növeini a tábla méretét,
az EXTEND beépített filggvényt kell használnunk.
Példa nested tábla kezelésére. Figyeljük meg, hogy a ciklus a COUNT által visszaadott
értékig megy, tehát nem a tömb végéig.
DECLARE
TYPE ntabla_tipus IS TABLE OF CHAR(3);
ntabla ntabla_tipus;
BEGIN
ntabla ·= ntabla tipus(); --a tábla inicializálása
FOR i IN 1 .. 5 LOOP --a tábla feltöltése 5 elemmel
ntabla.EXTEND;
ntabla (i) := i;
END LOOP;
ntabla.DELETE(3); --a 3. elem kitorlese
FOR i IN l .. ntabla.COUNT LOOP -végigmegyünk az elemeken
IF (ntabla.EXISTS(i)) THEN --ha az i-dik elem létezik
DBMS_OUTPUT.PUT_LINE(ntabla(i));
END IF;
END LOOP;
END;

7.3.2. Index-by táblák


Az index-by táblák hasonlítanak a nested táblákhoz. Azonos a struktúrájuk, egyes
elemeiket azonos módon tudjuk elérni (indexeléssel). A legnagyobb különbség, hogy a nested
táblákat el lehet tárolni az adatbázisban, míg az index-by táblákat nem. Az index-by táblák
hasonlítanak más programozási nyelvekben található hash táblákhoz. Néhány összetett
típusokra definiált eljárás nem müködik index-by táblákra. Például a TRIM csak a tömbökre
és a nested táblákra müködik. Ha egy index-by táblát nem inicializálunk., értéke üres lesz,
tehát ellentétben a nested táblával, az IS NULL operátorral nem tudjuk megnézni, hogy lett-e
már inicializálva. Az index-by táblák előnye, hogy a PUSQL implicit konverziót hajt végre a

80
7.PUSQL összetett adattipusok lváncsy Renáta

hoszt tömbök és az index-by tömbök között. Az index-by táblák alapból ritkák. és


használhatunk rajtuk negatív indexeket is.
Az index-by tábla dek.larálása:
TYPE típus név IS TABLE OF elem_ tipus [NOT NULL)
INDEX BY BINARY INTEGER;
Ellentétben a nested táblákkal és a tömbökkel, az indexed-by táblák elemeinek a tipusai a
következök is lehetnek: BINARY_INTEGER, BOOLEAN, LONG, LONG RAW,
NATURAL, NATURALN, PLS INTEGER, POSITIVE, POSITIVEN, SIGNTYPE

és STRING.
A tábla növelésére nem kell külön fiiggvényt használnunk, elég, ha nagyobb indexet
használunk. Az index-by táblák ritkák. így meg van az az előnye, hogy például használhatjuk
indexként a benne tárolt adatok elsődleges kulcsát is.
Ha egy táblában (akár nested akár index-by) rekordokat tárolunk, a rekordok egyes
mezőire a következöképpen tudunk hivatkozni:
tábla_név(index).mez6_név

7 .4.Az összetett adattipusok összehasonlítása


Varrays Nested Tables lndes.-by Tables
Méretének deklaráláskor
meg kell adni a felső Nincs felső korlátja, de Nincs felső korlátja,
Méret korlátját, EXTEND az EXTEND eljárással egyszeruen nagyobb
metódussal kell növeini a kell növeini a méretét indexre kell hivatkozni
méretét a max. méretig
Sürü vagy Sürü, de törölhetünk
Sürü Ritka
ritka belőle, így ritkává válik
Tárolható
Igen Igen Nem
adatbázisban
Index Csak pozitív lehet Csak pozitiv lehet Lehet negativ is
Inicializálás
Automatikusan NULL Automatikusan NULL Üres
nélkül
Kollekctókat értékül adhatunk egymásnak, ha azonos a típusuk (nem elég, ha az
elemeinek a típusa azonos). Ha egy NULL értékű kollekciót adunk értékül egy másik
kollekciónak, akkor a másik kollekció is NULL értékű lesz, ftlggetlenül attól, hogy előtte már
volt inicializálva vagy sem. Ekkor újra kell inicializálni. Kollekciókat nem hasonlíthatunk
egymással össze, még ha azonos típusúak, akkor sem. Kollekciók nem szerepelhetnek
DISTINCT, GROUP BY és ORDER BY listában (ezekhez össze kellene öket hasonlítani).
Létre lehet hozni olyan kollekciókat is, aminek az elemei maguk is kollekciók.

81
7.PUSQL összetett adattipusok lváncsy Renáta

7.5.Metódusok táblákra és tömbökre


Az alábbi metódusok segítik a kollekciók kezelését. Néhányról már az eddigiekben is
esett szó, itt az összes metódus listája található. A leírás után abban az oszlopban található
pipa, amilyen összetett adattipusra az adott metódus használható.
Metódus Leirás Varray N ested Index-by
EXlSTS(n)
Eredménye igaz, ha a PUSQL tábla n-dik
eleme létezik
., ., .,
CO UNT
A táblában aktuálisan tárol elemek
számával tér vissza
., ., .,
LIMIT
Nested táblára NULL-lal tér vissza,
varray-ra a deklarációban megadott
., .,
maximum tömbhosszal.
Az első és utolsó Oegkisebb és
FIRST
LAST
legnagyobb) indexszel tér vissza, ami a
kollekcióban van. Ha Ores, NULL-lal tér
., ., .,
vissza.
PRIOR(n)
Azzal az indexszel tér vissza, amt
megelőzi az n indexet
., ., .,
NEXT(n)
Azzal az indexszel tér vissza, ami az n
indexet követi.
., ., .,
EXTEND()
Egy null elemet illeszt a kollekció végére.
Ha egy nested táblánál vagy varray-nál
használtuk a NOT NULL opciót, ezt nem
., .,
használhatjuk a növelésére.
EXTEND(n)
N darab null elemet illeszt a kollekció
végére
., .,
N darab elemet illeszt a kollekció végére,
aminek tartalma megegyezik az J.
EXTEND(n,i) elemmel
., .,
Semelyik EXTEND filggvény nem

TRIM
használható az Index-by tábláknáL
Eltávolít egy elemet a kollekció végéről.
.,., .,
.,.,
TRIM(n)
DELETE
Eltávolít n elemet a kollekció végéröl
Minden elemet töröl a kollekcióból
., .,
DELETE{n)
Az n. elemet eltávolitja az index-by vagy
a nested táblából
., .,
DELETE(m,n)
Eltávolítja az m. elemtöl az n.-ig az
elemeket
., .,

82
8.PUSQL kurwrok lváncsy Renáta

8. PL/SQL kurzorok
A szerver oldali programozAst biztosító nyelvekben a kurzorok szolgálnak a több sort
visszaadó lekérdezések eredményének tárolására. A PUSQL-ben kétfajta lrurzor létezik., az
implicit és az explicit. Minden SQL adatmanipulációs utasítás számára a PUSQL implicit
létrehoz egy lrurzort, beleértve azokat a lekérdezéseket is, amiknek csak egy sor az
eredménye. Az olyan lekérdezéseknek, amiknek az eredménye több mint egy sor, a
programozónak kell explicit definiálnia kurzort.

8.l.Explicit kurzorok
Egy lekérdezés eredménye lehet nulla, egy, vagy több sor, attól filggöen, hogy mennyi sor
egyezett meg a felhasználó által megadott feltételnek. Ha a lekérdezés több sort ad vissza,
explicit hozzárendelhetünk egy kurzort. Kurzort bármely PUSQL blokk, alprogram és
csomag deklarációs részében deklarálhatunk.

8.1.1. Kurzor deklarálása


Kurzort a következő szintaktik.át használva deklarálhatunk:
CURSOR kurzor . név [(paraméter[, paraméter] ... )]
[RETURN visszatérési_ tipus] IS lekérdezés;
Ahol a visszatérési_típus-nak egy rekor<lra vagy egy adatbázis tábla sorára kell
hivatkoznia, és a paramétereknek a következő szintaktikája van:
paraméter_név [IN] adattipus [{:= 1 DEFAULT} kifejezés)
Lássunk két példát lrurzor deklarálására:
DECLARE
CUSROS cl IS SELECT hotel_nev, hotel varos FROM hotel;
CURSOR c2 RETURN hotel%ROWTYPE IS SELECT * FROM hotel WHERE
hotel id > 5;
A lrurzor egy nem deklarált azonosító, nem pedig egy PUSQL változó neve. Nem
adhatunk értéket egy lrurzornak, és nem használhatjuk egy kifejezésben sem. A kurzorok
láthatósági köre (scope) megegyezik a változókévaL A lrurzorok kaphatnak paramétereket,
amik megjelenhetnek a lekérdezésben azokon a helyeken, ahol konstansok is szerepelhetnek.
A lrurzor paraméterének bemenő paraméternek kell lennie (IN). Egy kurzor paraméterének
nem köthetjük ki, hogy nem lehet NULL érétkü. Egy kurzor paraméternek megadhatunk
DEFAULT értéket. A kurzor paraméterének láthatósága lokális a kurzoron belül, azaz csak a
kurzoron belüli lekérdezésben használható.

83
8.PUSQL lrurzorok Iváncsy Renáta

8.1.2. A kurror használata


A lrurzort használat előtt meg kell nyitni (OPEN). Ekkor futtatja le az Oracle a lrurzor
deklarálásakor megadott lekérdezést, ezután a lrurzor az eredményhalmaz legelső sorára
mutat. Az egyes sorokat a FETCH utasilással nyerhetjük ki a lrurzorból, ilyenkor visszaadja
azt a sort, amin állt, majd a következő sorra ugrik. Használat után a kurzort le kell zárni

(CLOSE).
A lrurzort az OPEN utasítással kell megnyitni.
OPEN kurzor_név[(<paraméterek>)];
Paramétereket a lrurzor megnyitásakor adhatunk át. Minden definiált paraméternek
értéket kell adni az OPEN utasításkor, ha nem akarjuk elfogadni a DEFAULT értéket: A
következő példában egy lrurzort deklarál unk, aminek két bemenő paramétere van:
DECLARE
student student.stud id%TYPE DEFAULT 'FBSDFH';
year DATE DEFAULT '02-mar-2003'
CURSOR cl (diak VARCHAR2, év DATUM) IS SELECT ...
A következő utasítások bánnelyike megnyitja a lrurzort:
OPEN cl(student, '12-jun-2001');
OPEN cl('DR45TF', year);
OPEN cl(student, year);
A lrurzorból egy sort a FETCH utasítássallehet megkapni. Minden FETCH utasítás után a
kurzor a következő sorra lép.
FETCH kurzor név
[BULK COLLECT)
INTO {változó_név[, változó_név) ... l rekord_név};
Az INTO után álló listában szereplő változók típusának, vagy a rekord mezőinek a
típusának meg kell felelnie a lrurzorban szereplő oszlopok típusávaL A FETCH utasítást
általában ciklusban szokás használni, hogy az összes sort megkapjuk az eredménytáblából. Az
alábbi táblában a ciklusból akkor lépünk ki, ha az utolsó sort is lekérdeztü.k a lrurzorból. Ezt a
%NOTFOUND lrurzor attribútummal tudjuk megtenni. Erről a későbbiekben még részletesen
lesz szó.
DECLARE
CURSOR cl IS SELECT anyag_nev FROM anyag ORDER BY anyag_id;
nev anyag.anyag_nev%TYPE;
BEGIN
OPEN cl;

84
8.PUSQL lrurzorok Iváncsy Renáta

LOOP
FETCH cl INTO nev;
EXIT WHEN cl%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(nev);
END LOOP;
CLOSE cl;
END;
A kunort a CLOSE utasítássallehet bezárni.
CLOSE kurzor_név;
Az explicit kunorok legelterjedtebb használati módja a cikluson belüli FE TCH utasítás. A
cikluson kívül megnyitjuk a kunort, majd a ciklusban addig olvassuk ki az egyes sorokat,
amíg a kunor üressé nem válik. Ekkor kilépünk a ciklusból és bezáJjuk a kunort.
Lehetőség van az eredményhalmaz egy lépésben való kinyerésére is. Ekkor nem kell
ciklust használni, hogy soronként megkapjuk az értéket, viszont definiálni kell egy kollekciót,
amiben az eredményt eltárolhatjuk. Ezt a lehetőséget a BULK COLLECT k:ulcsszó
használatával tudjuk elérni. (Az ORACLE9i-ben BULK COLLECT használata még nem
müködik rekordokra, tehát a kollekció elemei nem lehetnek rekordok.)
DECLARE
CURSOR cl IS SELECT anyag_nev, anyag id FROM anyag;
TYPE nevtype IS TABLE OF anyag.anyag_nev%TYPE;
TYPE idtype IS TABLE OF anyag.anyag_id%TYPE;
nevtomb nevtype;
idtomb idtype;
BEGIN
OPEN cl;
FETCH cl BULK COLLECT INTO nevtomb, idtomb;
CLOSE cl;
END;
A kunorokban használhatunk allekérdezésekel (subquery) is. Az allekérdezés egy olyan
lekérdezés, ami egy másik adatmanipulációs SQL utasításban jelenik meg. Allekérdezésekel
általában a WHERE után vagy a FROM után szoktak használni.

85
8.PIJSQL lrurzorok I váncsy Renáta

8.2.Implicit kurzorok
Az Oracle implicit nyit lrurzort minden olyan SQL utasítás végrehajtásához, amihez nem
rendeltünk explicit kurzort. Implicit Imrzorokra nem használhatjuk az OPEN, FETCH, és
CLOSE utasftásokat. de Imrzor attribútumok segitségével információt nyerhetünk az
legutoljára futtatott SQL utasításróL A Imrzor attribútumokról késöbb lesz szó részletesen.

8.2.1. A kunor-FOR ciklus


Sok esetben, amikor explicit lrurzort használunk, lehetőség van a Icu r z o r- FOR ciklus
( cursor for loop) használatára, ami implicit használja a lrurzort. llyenkor nem kell a
programozónak megnyitni a lrurzort, kivenni az adatokat és bezárni, azt megteszi helyette a
kurzor-FOR ciklus. A kurzor-FOR ciklus implicit deklarálja a ciklusváltozóját
%ROWTYPE rekordként. megnyitja a kurzort, ciklikusan kiveszi az eredményhalmazból az
adatokat a rekord mezöibe, és bezáJja a kurzort, ha az eredményhalmaz végére ért.
FOR ciklusváltozó_rekord IN kurzor_ név[(<paraméterek>)] LOOP
<ciklusváltozó_rekord.mezőnév használata, egyéb utasítások >
END LOOP;
Az alábbi példában kurzor- for ciklus segitségévellistázzuk ki az anyag tábla elemeit
a kimeneti pufferbe.
DECLARE
CURSOR cl IS SELECT anyag_nev, anyag_id FROM anyag ORDER BY
anyag_ id;
BEGIN
FOR cl rec IN cl LOOP
DBMS_OUTPUT.PUT_ LINE(cl_rec.anyag_id l l '·' l l
cl rec.anyag_nev);
END LOOP;
END;

A kurzor-FOR ciklusban nem használhatunk olyan kurzort, ami épp nyitva van.
Minden iterációs lépésben az eredményhalmaz egy sora bekerül az implicit deklarált
rekordba. A rekord mezöire a rekord név.mezó név szintaktikával utalhatunk. A
- -
rekord csak addig létezik, amíg a FOR cikluson belül vagyunk. Ha kilépünk onnan, a rekordra
már nem hivatkozhatunk. Ha vége a ciklusnak, a Imrzor automatikusan bezárásra kerül. A
Imrzor akkor is bezáródik., ha EXIT, GOTO vagy hibamiatt hagyjuk el a FOR ciklust.

86
8.PUSQL kunorok Iváncsy Renáta

A lrurzor-FOR ciklus egy másik változata, amikor egyáltalán nem hozunk létre explicit
lrurzort, helyette a kurzor lekérdezését a lrurzor-FOR ciklusban fogalmazzuk meg. Ennek
szintaktikája a következő :
FOR ciklusváltozó rekord IN (lekérdezés) LOOP
<ciklusváltozó__ rekord.mezőnév használata, egyéb utasitások >
END LOOP;

8.3.Kurzorváltozók
A kurzorváltozó, hasonlóan a lrurzorboz, egy több sort eredményező lekérdezés eredmény
halmazának egy sorára mutat. A lrurzorok annyiban különböznek a kurzorváltozóktól, mint a
konstansok a változóktót Míg a lrurzor statikus, a lrurzorváltozó dinamikus, mert nincs egy
konkrét lekérdezéshez kötve. Egy lrurzorváltozót bármely azonos típusú lekérdezésre
megnyithatunk. A lrurzorváltozónak új értéket adhatunk, és átadhatjuk paraméterként lokális
és tárolt fiiggvényeknek, eljárásoknak.
A lrurzorváltozó olyan, mint a mutató egy C vagy Pascal programban. azaz nem magát az
elemet tárolja, hanem csak az elem eimét, ahol az megtalálható. A PUSQL-ben a mutatóknak
REF x típusuk van, ahol a REF a REFERENCE (mutató) rövidítése és x egy objektum
osztályát jelöli. Tehát a kurzorváltozónak a típusa REF CURS OR.
Az Oracle megnyit egy munkaterületet, hogy lefuttasson egy több sort visszaadó
lekérdezést. Hogy elérjük az információt, vagy explicit lrurzort használunk, ami elnevezi ezt a
területet, vagy a lrurzorváltozót, ami a munkaterületre mutat. Amíg a kurzor mindíg ugyanarra
a munkaterületre hivatkozik, addig a lrurzorváltozó különböző munkaterületekre is mutathat.
Kurzorváltozókat föként akkor használunk, amikor eredmény halmazokat szerelnénk
átadni PUSQL tárolt alprogramok és kliensek között.
Kurzorváltozót két lépésben tudunk létrehozni. Először definiálni kell egy REF CURSOR
típust, utána deklarálni egy ilyen típusú lrurzorváltozót. Egy REF CURSOR típust az alábbi
szintaktikával tudunk definiálni bármely blokkban, alprogramban vagy csomagban:
TYPE ref_tipus_név IS REF CURSOR [RETURN visszatérési_tipus];
A lrurzor visszatérési típusa azt határozza meg, hogy milyen rekorddal tér vissza az adon
kurzor. A lrurzorra csak akkor használhatjuk a %ROWTYPE operátort, ha megadtuk a
visszatérési típusát.

87
8.PUSQL lrurzorok Iváncsy Renáta

8.3.1. Korzorváltozók kezelése

A kurzor változók kezeléséhez három utasítást használunk: OPEN-FOR, FETCH és


CLOSE. Először kinyitjuk a kurzort egy lekérdezésre. Ezután kivesszük a sorokat az
eredményhalmazból, amit a lekérdezés generált. Végül bezárjuk a kurzorváltozót.
Az OPEN- FOR utasítás hozzárendel egy lekérdezést a kurzorváltozóhoz, lefuttatja a
lekérdezést, és azonosítja az eredményhalmazt. Ennek a szintaktikája itt látható:
OPEN {kurzor változó l :host _kurzor változó} FOR
{lekérdezés
l dinamikus sz tr ing [US ING bind _argument [, b ind argument] ..• ]
};
A host_ kurzor _vá l to z ó egy olyan kurzorváltozó, amit a PUSQL környezetben
deklaráltak. A kurzorokkal ellentétben a kurzorváltozó nem kaphat paramétereket. Ezzel
azonban nem vesztettünk az alkalmazkodó képességéböl, hiszen paraméterek helyett egész
lekérdezéseket adhatunk meg. Egy kurzorváltozót megnyithatunk különbözö Iekérdezések
számára. Egy új lekérdezéshez nem kell bezárni az előzöt, de tudni kell, hogy ha újra
megnyitjuk ugyanazt a kurzorváltozót, a régi értékét elveszti.
A FETCH utasítással tudunk sorokat kinyerni az eredményhalmazbóL
FETCH {kurzor változó_név l :host_kurzor változó név}
[BULK COLLECT]
INTO {változó_név[, változó_név] ••. l rekord_név};
A BULK COLLECT használatával a kurzor változók esetében is lehetőség van arra, hogy
az eredményt egy lépésben megkapjuk.
A kurzorváltozót a CLOSE utasítással zárhatjuk be:
CLOSE {kurzor változó név l :host_kurzor_változó_név);
A BULK COLLECT használatával a kurzor változók esetében is lehetőség van arra, hogy
az eredmény egy lépésben megkapjuk. A kurzorváltozókat azonban nem lehet feldolgozni a
kurzor-for ciklus segitségével!
A követ.kezö példában egy kurzorváltozó segítségével lekérdezzük az anyag tábla
neveit, majd pedig a student táblában szereplö vezetékneveket
DECLARE
TYPE cl_type IS REF CURSOR;
Cl cl_type;
nev VARCHAR2(50);
BEGIN
OPEN cl FOR SELECT anyag_nev FROM anyag;
LOOP

88
8.PUSQL kunorok lváncsy Renáta

FETCH cl INTO nev;


EXIT WHEN cl%NOTFOUND;
DBMS _ OUTPUT.PUT_LINE(nev);
END LOOP;
OPEN cl FOR SELECT stud lname FROM student ;
LOOP
FETCH cl INTO nev;
EXIT WHEN cl%NOTFOUND;
DBMS - OUTPUT.PUT - LINE(nev);
END LOOP;
CLOSE cl;
END;

8.4.Kurzor attribútumok
Minden explicit k:urzornak és k:urzorváltozónak négy attribútuma van: %ISOPEN,
%NOTFOUND, %FOUND és %ROWCOUNT. A kurzor attribútumokat nem hasmálhatjuk az SQL
utasításokban, csak a procedurális utasításokban.

8.4.1. Explicit kurzor attribútumok


Attribútum Típus Leírás
%ISO PEN Boolean TRUE az értéke, ha a Irurzor nyitva van, FALSE, ha nincs
nyitva.
%NOTFOUND Boolean Az elsö FETCH elött értéke NULL, FALSE az értéke, ha a
FETCH sorral tért vissza és TRUE, ha nem adott vissza sort.
Ha nincs nyitva a Irurzor, akkor INV ALID_ CURSOR hibát
generál.
%FOUND Boolean Miután a kurzort megnyitottuk, de az elsö fetch elött NULL-t
ad vissza. Ezután minden sikeres FETCH után TRUE az értéke,
és FALSE, ha a FETCH nem ad vissza sort. Ha a Irurzor nincs
megnyitva, az INV ALID CURSOR hibát generálja.
%ROWCOUNT Number Amikor a k:urzort megnyitjuk, a %ROWCOUNT nullázva lesz.
Az elsö FETCH elött nulla az értéke. Késöbb az addig
sikeresen megkapott sorok számát adja meg. Ha a Irurzor nincs
nyitva, az INVALID CURSOR hibát generálja.
..
Néhány példa az exphc1t kurzor attnbútumok hasmáiatára

%FOUND:
LOOP
FETCH cl INTO nev, ev;
IF cl%FOUND THEN -- a FETCH sikeres volt

89
8.PUSQL kurzorok lváncsy Renáta

ELSE a FETCH nem volt sikeres, kilépünk a ciklusból


EXIT;
END IF;
END LOOP
0
/oiSOPEN:
IF cl%ISOPEN THEN -- a kurzor nyitva van

ELSE a kurzor zárva van, tehát kinyitja


OPEN cl;
END IF;
%NOTFOUND:
LOOP
FETCH cl INTO nev, ev;
EXIT WHEN cl%NOTFOUND OR cl%NOTFOUND IS NULL;

END LOOP

8.4.2. Implicit kurzor attribútumok

Az implicit Irurzor attribútumok információt szolgáltatnak az INSERT, UPDATE,


DELETE és SELECT INTO utasítások lefutásáróL A lrurzor attribútumok értéke mindig a
legutoljára lefutott SQL utasításra vonatkoznak, még akkor is, ha az egy alprogramban
szerepelt. Mielött az Oracle megnyitja az SQL Irurzort, az attribútumok értéke NULL. Az
implicit Irurzor attribútumokra az
SQL%attribútum
szintakti.kával hivatkozhatunk.
Attribútum Típus Leírás
%ISO PEN Boolean Mindig FALSE az értéke, mert az Oracle minden végrehajtott
SQL utasítás után bezárja az SQL kurzort.
%NOTFOUND Boolean TRUE az értéke, ha az INSERT, UPDATE és DELETE egy
sort sem érintett vagy ha a SELECT INTO egy sorral sem tért
vissza, egyébként FALSE.
%FOUND Boolean Amíg nem futott le egyetlen SQL utasítás sem, értéke NULL.
Utána TRUE, ha az INSERT, DELETE és UPDATE utasítás
egy vagy több sort érintett, illetve ha a SELECT INTO egy
vagy több sort adott vissza, egyébként FALSE.
%ROWCOUNT Number A sikeresen végrehajtott sorok szmát adja vissza INSERT,
UPDATE és DELETE esetben, illetve a SELECT INTO
esetben a kiválasztott sorok számát adja meg. Ha az INSERT,

90
8.PUSQL lrurzorok lváncsy Renáta

UPDATE és DELETE egy sort sem érintett, O az értéke, illetve


akkor, ha a SELECT INTO egy sorral sem tért vissza. Ha a
SELECT INTO utasítás több mint egy sorral tér vissza, a
PUSQL a TOO_MANY_ROWS hibát generálja, és a
%ROWCOUNT a visszaadott sorok száma helyett l lesz.
o o

Néhány példa tmphctt k:urzor attnbútumok használatára:


o/eROWCOUNT
DELETE FROM varasWHERE varas nev LIKE 'P%';
IF SQL%ROWCOUNT > 10 THEN

END IF;
Fontos! Amennyiben egy lekérdezés egyetlen sorral sem tér vissza, a rendszer a
NO_DATA_FOUND kivételt generálja. Ebben az esetben az SQL%NOTFOUND
attribútumot már csak az EXCEPTION részben lehet használni. A következő példa ezek
alapján hibás, illetve a feltétel felesleges, mert a feltétel belsejébe sosem fog kerülni a
vezérlés!
SELECT utas id INTO myid FROM utas WHERE utas nev 'Kovacs';
IF SQL%NOTFOUND THEN
--ide sosem fog kerülni a vezérlés!!!
END IF;

8.5.Kurzor kifejezések
Egy k:urzor kifejezés beágyazott k:urzorral is visszatérhet. Ez annyit jelent, hogy az
eredményhalmaz m.indegy egyes sora tartalmazhat értékeket, valamint olyan k:urzorokat, amik
allekérdezések eredményeképpen jönnek létre. Dyen módon lehetőség van egy lekérdezésben
összefüggö adatok halmazát megkapni. Az eredményhalmazt egymásba ágyazott ciklusokkal
lehet feldolgozni úgy, hogy a külsö ciklus végigmegy a külsö lekérdezés eredményének
sorain, míg a belső ciklusok a lekérdezésben szereplö k:urzorok által visszaadott értékeken
halad végig.
Kurzor kifejezés használható k:urzor deklarációban, REF CURSOR deklarációban és ref
cursor értékeként egyaránt, szintaktikája a következő:
CURSOR (allekérdezés)
A beágyazott kurzor implicit megnyitásra kerül, amikor a sor feldolgozásra kerül, és a
következő esetekben záródik be:
• A felhasználó explicit bezáJja
• A szülö k:urzor újra lefut

91
8.PUSQL lrurzorok lváncsy Renáta

• A szülö kurzor bezáródik


• Hiba keletkezik a szülö kurzorok adatkivétele közben.
Az alábbi példa egy beágyazott kurzort mutat be. A cél a félkész termékek összetevőinek

a listázása. A k:ülső kurzor lekérdezi a félkész termékek nevét ABC sorrendben, a belső

kurzor lekérdezése pedig meghatározza az aktuális félkész termék összetevőit.


DECLARE
CURSOR cl is
SELECT felkesz nev, CURSOR(SELECT anyag_nev,
fa_mennyiseg,
egyseg_nev
FROM anyag, felkesz_anyag, egyseg
WHERE anyag_id = fa_anyagid
AND fa felkeszid = f.felkesz id
AND egyseg_id anyag egyseg
)
FROM felkesz f ORDER BY felkesz_nev;
TYPE refcursor IS REF CURSOR; -- a belso kurzor feldolgozasara
nev varchar2(100);
TYPE anyagadattype is record
(nev varchar2(100),
menny float,
egyseg varchar2(20)
) ;
anyagadat anyagadattype;
mycur refcursor;
BE GIN
OPEN cl;
LOOP
FETCH cl INTO nev, mycur;
EXIT WHEN cl%NOTFOUND;
dbms output. put l i ne ( 1 A ' l l nev l l 1 osszetevoi: 1 ) ;
LOOP
FETCH mycur INTO anyagadat;
EXIT WHEN mycur%NOTFOUND;
dbms_output.put_line( 1 1
ll anyagadat.nev ll 11

l 1 anyagadat.menny l l 1 1
l l anyagadat.egyseg);
END LOOP;
END LOOP;
CLOSE cl;
END;

92
9.PUSQL alprogramok lváncsy Renáta

9. PUSQL alprogramok
Az alprogramok olyan PUSQL blokk.ok, amik paramétereket tudnak fogadni. A PUSQL-
nek kéttípusú alprogramja van, a filggvények (functions) és az eljárások (procedures).
Általában az eljárások müveletek elvégzésére szolgálnak, a filggvények értékek kiszámítására.
Hasonlóan az anonim blokk.okhoz, az alblokk.ok is három részböl állnak, a deklarációs
részböl, a futtatható részből és a kivételkezelő részböL A deklarációs rész konstansok,
változók, kurzorok, kivételek és beágyazott filggvények deklarációját tartalmazza. Ezek az
elemek lokálisak, és megszünnek, ha kilépünk az alprogrambóL A futtatható rész különbözö
utasításokat, értékadásokat, programvezérlő utasításokat és adatmanipulációs utasításokat
tartalmaz. A kivételkezelő rész a kivételkezelést oldja meg.
Az alprogramok előnye, hogy általuk a feladatot több, kisebb komplexitású feladattá
bonthatjuk, egy-egy különálló feladatra készíthetünk külön eljárásokat és filggvényeket,
amiket aztán a program több helyéről különböző paraméterekkel meghívhatunk.

9.1. PUSQL eljárások


A PUSQL eljárások olyan alprogramok, amik speciális feladat elvégzésére íródtak. A
PUSQL eljárás szintaktikája a következő:
[CREATE [OR REPLACE]]
PROCEDURB eljárás név[(paraméter[, paraméter] ... )]
[AUTHID {DEFINER l CURRENT_USER}] {IS l AS}
[PRAGMA AUTONOMOUS_TRANSACTION;]
[<lokális deklarációk;>]
BEG IN
<futtatható_utasítások;>
[EXCEPTION
<hiba _ kezelés;>]
END [eljárás_név];
A CREATE utasítás segítségével egyedülálló eljárást lehet készíteni, ami az Oracle
adatbázisban kerül eltárolásra. A CREATE PROCEDURE utasítást futtathatjuk interaktívan a
SQL*PLUS-ból, vagy a PUSQL Developerböl, vagy programból dinamikus SQL
használatávaL A REPLACE kulcsszó használata esetén az azonos névvel rendelkező már
létező eljárás kerül felülírásra. Az AUTHID utasítás azt adja meg, hogy a tárolt eljárás milyen
jogokkal fusson: a létrehozó jogaival (DEFINER) vagy az aktuális felhasználó jogaival
(CURRENT USER), aki futtatja az eljárást. Az AUTONOMOUS TRANSACTION pragma
megadja a PUSQL fordítónak, hogy az eljárást autonóm tranzakcióként kezelje.

93
9.PUSQL alprogramok lváncsy Renáta

Egy eljárás két részböl áll. A specifikációból és a törzsböl. Az eljárás specifikáció a


PROCEDURE kulcsszóval kezdödik és az eljárás nevével vagy a paraméter listával végzödik.
A paraméter lista opcionális, ha egy eljárásnak nincs paramétere, akkor zárójel nélkül kell
írni. A törzs az IS (vagy AS) kulcsszóval kezdődik és az END Irulesszóra végződik. Az eljárás
törzsének három része van, a deklarációs rész, a futtatható rész és a kivételkezelö rész.
A paraméterek megadásának módja a következö:
paraméter_név [IN l OUT [NOCOPY] l IN OUT [NOCOPY]) adattipus
[{:: l DEFAULT} kifejezés)
A paraméternek nem adhatunk meg korlátokat, tehát például a következö példa hibás,
mert a CHAR típusú paraméternek a hosszra vonatkozóan megkötést ad:
l PROCEDURE reconcile (acct id CHAR(5)) IS ... HIBAS!! !!
Ha mégis meg szeretnénk adni bizonyos korlátozásokat a paramétemek. ennek az a
módja, hogy definiálunk egy altípust, amiben az alaptípushoz képest megadjuk a
korlátozásokat, és ezek után az eljárás paraméterének ez az altípus lesz a típusa.
Példaként az alábbi tárolt eljárás egy új diákot vesz fel az adatbázisba:
CRETAE OR REPLACE PROCEDURE new student
(id CHAR,kernev VARCHAR2,veznev VARCHAR2,mail VARCHAR2)
AS
INSERT INTO student VALUES (id,kernev,veznev,mail);
END;

9.2.PUSQL függvények
A PUSQL filggvény olyan alprogram, ami valamilyen értéket számol ki. A filggvények
és az eljárások szerkezetükben hasonlítanak egymásra, azzal a kivétellel, hogy a
filggvényeknek van visszatérési értékük, valamint a függvényben csak SELECT SQL utasítás
adható ki, adabnódosító nem. A visszatérési értéket a RETURN kulcsszóval lehet megadni.
Egy függvény szintaktikája a következöképpen néz ki:
[CREATE [OR REPLACE]]
FUNCTION függvény_név((paraméter[, paraméter) ... ))
RETURN adattipus} IS
[PRAGMA AUTONOMOUS _ TRANSACTION;]
[<lokális_deklarációk;>)
BEGIN
<futtathat6_ utasitások;>
RETURN visszatérési_érték;
[EXCEPTION
<híbakezelés;>J
END [függvény_név);

94
9.PUSQL alprogramok Iváncsy Renáta

A fiiggvény két részből áll, a specifikációból és a törzsből. A specifikáció a FUNCT I ON


lrulcsszóval kezdődik és a RETURN kifejezéssel fejeződik be. A RETURN k:ulcsszó után meg
kell adni, hogy milyen típusú értékkel tér vissza a ftlggvény. A fiiggvény törzse az Is vagy
AS k:ulcsszóval kezdődik és az END k:ulcsszóval fejeződik be. A törzs három részből állhat, a
deklarációs részből, a futtatható részből és az opcionális kivételkezelő részbőL A futtatható
résznek tartalmaznia kell a RETURN utasítást, ahol meg kell adni azt az értéket, amivel a
ftlggvény vissza fog térni. A futtatható részben több helyen is ki lehet adni a RETURN
utasítást, de ha kiadtuk. a fiiggvény visszatér, és a vezérlés átadódik annak a blokknak vagy
alblokknak, ami a fiiggvényt meghívta. Az alábbi fiiggvény BOOLEAN típussal tér vissza
annak megfelelően, hogy egy adott kurzusra még van-e hely vagy sem:
CREATE FUNCTION vanhely (targyid CHAR, ev char) RETURN BOOLEAN
AS
kurzusid INT;
korlat INT;
jelentkezettek INT;
BEG IN
SELECT cou id INTO kurzusid FROM course
WHERE cou subjectname = targyid AND cou semestername ev;
SELECT cou limit INTO korlat FROM course
WHERE cou id = kurzusid;
SELECT COUNT(*) INTO jelentkezettek FROM student course
WHERE sc_courseid = kurzusid;
IF (jelentkezettek < ferohely ) THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END;
A ftlggvény bemenete egy tárgy azonosítója és egy félév azonosító. A fiiggvény először

lekérdezi a bemenetként megkapott paraméterekhez tartozó kurzus azonosítóját. Ezek után a


már ismert azonosító segítségével lekérdezi, hogy egy adott kurzusra hányan jelentkezhetnek,
valamint egy másik lekérdezésben megszámlálja, hogy eddig hányan jelentkeztek az adott
lruzrusra. Amennyiben a jelentkezettek száma kisebb mint a limit, a fiiggvény igazzal tér
vissza, egyébkétn pedig hamis értékkel. A fiiggvényt egy kifejezés részeként hívhatjuk meg.

95
9.PUSQL alprogramok lváncsy Renáta

l IF vanhely('VIAU9159','20031') THEN-

9.3.Aiprogramok deklarálása
AJprogramot bármilyen blokk, alprogram vagy csomag deklarációs részében
deklarálhatunk. Ügyelni kell arra, hogy alprogram deklarálása a deklarációs rész végén
történjen, minden más elem deklarálása után. A deklarációnak mindig meg kell előznie a
hivást. Ezért ha egy alprogram törzsében egy másik alprogramot hívunk meg, akkor azt az
alpragramot kell hamarabb deklarálni, amit a másik alprogram használ. Ez nem mindig
járható út. hiszen előfordulhat. hogy két eljárás egymást hívja. Ekkor azt kell tenni, hogy az
egyik eljárást elöre deklarálni kell. Ennek az a módja, hogy csak a ftlggvény vagy eljárás
specifikációját adjuk meg használat előtt, pontosvesszövei lezárva, és csak késöbb magát a
program törzset. Alprogramokat összegyüjthetünk egy csomagba is, ami az adatbázisban van
eltárolva. Az alprogramok specifikációja a csomag specifikációs részébe kerül, az alprogram
törzse pedig a csomag törzsébe. Oyen megoldással az alprogramokat megosztha~a egymás
között több program is. Lehetőség van arra is, hogy egy csomagban úgy deklaráljuk
alprogramot, hogy annak specifikációját nem adjuk meg a csomag specifikációjában. Az ilyen
alprogramokat azonban csak a csomagon belül használha~uk. A csomagokról részletesebb
leírást egy későbbi fejezet tartalmaz.

9 .4. Alprogramok paraméterezése


Az alprogramok paramétereken keresztül kapnak információkat A ftlggvény vagy eljárás
híváskor a paraméter listában szereplö változókat aktuális paramétereknek, az alprogram
specifikációjában használt paraméter neveket formális paramétereknek hívjuk. Ajánlatos
különböző nevű aktuális és formális paraméter nevet használni a könnyebb átláthatóság
kedvéért. Ha meghívunk egy alprogramot. az aktuális paraméterek kiértékelödnek és értékük
átkerülnek a formális paraméterekbe. Ha szükséges, a PUSQL átkoovertátja a típusokat.
mielött hozzá rendelné az aktuális paraméterek értékét a formális paraméterekhez. Ha olyan
paraméterhivást végzünk el, ahol az implicit tipuskonverzió müködik, akkor a PUSQL
megteszi, ha viszont nincs implicit tipuskonverzió, akkor nem tudja megtenni.
Paraméterhíváskor az aktuális paramétereket kétféleképpen rendelhetjük hozzá a formális
paraméterekhez. Egyrészt pozíció alapján (positional notation), másrészt név alapján (name
notation).
A pozíció szerinti paraméter átadás azt jelenti, hogy olyan sorrendben kell megadni az
aktuális paramétereket, amilyen sorrendben specifikálva lettek a formális paraméterek. Az

96
9.PUSQL alprogramok lváncsy Renáta

első aktuális paraméter az első formális paraméterhez lesz rendelve, a második aktuális
paraméter a második formálishoz és így tovább.
A név szerinti paraméter átadás azt jelenti, hogy az aktuális paraméterek sorrendjének
nem kell megegyezni a formális paraméterek sorrendjével, de a=> operátor segítségével meg
kell adni, hogy az adott formális paraméterhez melyik aktuális paraméter tartozik. Ennek az
az előnye, hogy nem kell tudni a paraméterek sorrendjét, viszont tudni kell, hogy a
filggvényben milyen formális névvel szerepeltek.
DECLARE
targy CHAR (8) : = 'VIAU9159';
Szemeszter CHAR(5) DEFAULT '20031';
FUNCTION vanhley (targyid CHAR, ev CHAR) RETURN BOOLEAN IS

BEGIN
IF vanhely (targy, szemeszter) THEN ... END IF;
-- pozíció szerinti paraméterezés
IF vanhely(targyid=>targy, ev=>szemeszter) THEN _ END IF;
-- név szerintin paraméterezés
IF vanhely(ev=>szemeszter, targyid=>targy) THEN_ END IF;
-- név szerintin paraméterezés
IF vanhely(targy,ev=>szemeszter) THEN _ END IF;
-- kevert paraméterezés
IF vanhely(targyid=>targy,szemeszter) THEN _ END IF; --HIBA
END;
A kétfajta paraméter átadási módszert keverni is lehet, de olyan megkOtéssel, hogy a
pozíció alapján történő hozzárendelésnek meg kell előznie a név alapján történőt Tehát a
következő kevert hozzárendelés nem müködik:
l vanhely(targyid=>targy,szemeszter); --HIBÁS!!!!
Paraméter átadáskor nem csak konstansokat vagy változókat használhatunk, hanem
lehetőség van kifejezések megadására is:

9.S.Paraméter módok
A paraméter módokat arra használjuk, hogy meghatározzuk a paraméterek viselkedését.
Három paraméter mód létezik: a bemenő (IN), a kimenő (OUT) és a kétirányú (IN OUT). Ha
nem adunk meg módot, az alapértelmezett mód az IN. Ajánlatos a filggvényeknél elkerülni a
kimenő és a kétirányú paraméter használatát, a függvénynek úgyis van visszatérési értéke.

97
9.PUSQL alprogramok Iváncsy Renáta

9.5.1. Az IN mód
A bemenő paraméterek az alprogramon belill úgy visel.kednek, mint a konstansok. Nem
kaphatnak értéket, de szerepelhetnek kifejezésben. Az aktuális paraméter, ami az adott IN
formális paraméterre utal, lehet konstans, !iterál, inicializált változó vagy kifejezés. A bemenő
paraméternek meg lehet adni alapértelmezett értéket is.

9.5.2. AZ OUT mód


A kimenő pamméteren keresztül a hívó értéket kaphat vtssza az alprogramtóL Az
alprogramon belül a kimenő paraméter úgy viselkedik, mintha egy változó lenne. Szerepelhet
például értékadó utasítás bal oldalán. A formális kimenő paraméterhez tartozó aktuális
paraméternek változónak kell lennie, nem lehet sem konstans, sem kifejezés.
A kimenő paraméternek hívás előtt lehet értéke, de az híváskor elvész, kivéve, ha
megadjuk a NOCOPY kulcsszót, mert ebben az esetben nem az értéke adódik át a változónak,
hanem csak egy mutató rá. A kimenő paraméter NULL értéküre van inicializálva, tehát nem
lehet egy kimenő paraméter olyan altípus, aminek meg van tiltva a NULL érték felvétele. Ha
mégis olyan, híváskor a VALUE _ERROR kivétel generálódik. Mielőtt visszatérünk egy
alprogramból, minden kimenő formális paraméterének értéket kell adni, különben NULL lesz
az értékük. Ha sikeresen térünk vissza egy alprogram hívásból, a PUSQL átadja a formális
paraméterek értékét az aktuális paramétereknek. Ha azonban egy kezeletlen kivétel miatt
térünk vissza az alprogramból, a PUSQL nem ad értékeket az aktuális paramétereknek.

9.5.3. AZ IN OUT mód


A kétirányú paraméterekkel inicializálhatjuk az alprogram paramétereit. Ezek a kezdeti
értékek felülíródnak az alprogram visszatérésekor. A kétirányú paraméterek az alprogramon
belill úgy visel.kednek, mint a változók, tehát állhatnak értékadó utasítás bal oldalán. Egy
kétirányú formális paraméterhez tartozó aktuális paraméternek változónak kell lennie, nem
lehet sem konstans, sem kifejezés. Ha sikeresen térünk vissza egy alprogram hívásból, a
PUSQL átadja a formális paraméterek értékét az aktuális paramétereknek. Ha azonban egy
kezeletlen kivétel miatt térünk vissza az alprogramból, a PUSQL nem ad értékeket az aktuális
paramétereknek.

98
9.PUSQL alprogramok Iváncsy Renáta

9.6.Aiprogram túlterhelés
PUSQL-ben lehetőség van az alprogramok túlterhelésére. Ez azt jelenti, hogy ugyanazzal
a névvel létre lehet hozni különböző alprogramokat, azzal a feltétellel, hogy a formális
paramétereik különböző számúak, sorrendűek vagy típusúak legyenek. A túlterhelt
alprogramokat lehet használni azonos blokkon, alprogramon vagy csomagon belül. A PUSQL
a formális paraméterei alapján dönti el, hogy épp melyik lett meghívva.

Korlátozások az alprogram túlterhelésre:


• Adatbázisban tárolt, egyedülálló alprogramokat nem lehet túlterhelni
• Nem lehet két alprogram neve azonos, ha csak a formális paramétereik nevében, vagy
paraméter módjában különböznek.
• Nem lehet két alprogram neve azonos, ha paramétereik különböző típusúak, de
típusaik azonos tipus családba valóak (pl. Az egyik ftlggvény paramétere INTEGER a
másiké REAL, akkor azokat nem lehet azonos névvel ellátni)
• Hasonlóan az előzőhöz, ha a paramétereik csak altípusokban különböznek, és az
altlpusok azonos alaptipusra épülnek., nem lehet azonos nevet adni két alprogramnak.
• Nem lehet két ftlggvény azonos nevű, ha csak visszatérési tipusukban különböznek,
még akkor sem, ha azok különböző tipus családba tartoznak.

99
IO.PUSQL hibák kezelése Iváncsy Renáta

10. PL/SQL hibák kezelése


Egy program futása során előfordulhatnak hibák. mint például a nullával való osztás,
vagy üres eredményt ad vissza egy SELECT utasítást stb. Egy hiba esetén a hibának
megfelelő hibaüzenet generálódik, és a program befejezi a müködését. A PUSQL-ben
lehetőség van a hibák kezelésére és a program további müködtetésére. PUSQL-ben a hibákat
exception-nak (k.ivételnek) hívják. Gyakran a hibakezelés és a kivételkezelés ugyanazt az
eljárást fedi: megtudni, hogy milyen hiba keletkezett és annak megfelelöen utasításokat
végrehajtani. A PUSQL-ben kétfajta kivétel létezik, az egyik típus a belső kivételek (pl.
didvided by zero vagy out of memory), a másik a programozó által definiált kivételek. A
belsö kivételek egy részének van elöre definiált neve, mint pl. a ZERO _DIVIDE vagy a
STORAGE _ERROR, más kivételeknek lehetöségilnk van nevet adni. Ha egy hiba keletkezik,

egy kivétel generálódik. Ez azt jelenti, hogy a normál futás megáll, és a programvezérlés az
alprogram vagy a blokk kivételkezelő részére kerül. A belső kivételek automatikusan
generálódnak egy hiba keletkezésekor, mig a felhasmáló által definiált kivételeket generálni
(RAISE) kell a megfelelő helyen. Egyébként lehetőség van a belső hibák generálására is. A

hibák kezelésére külön rutinokat kell irni, melynek neve kivételkezelök (exception handlers).
Ha egy kivételkezelő eljárás lefutott, a vezérlés a blokkol tartalmazó blokk (befoglaló blokk)
következő utasítására tér át. Ha nincs befoglaló blokk, akkor a futtató környezet kapja meg a
vezérlést.
A kivételeknek három tipusa van:
• rendszer által definiált hibák
o előre definiált (névvel ellátott) Oracle Server hibák (predefined Oracle Server
Errors)
o előre nem definiált (névvel nem ellátott) Oracle szerver hibák (non predefined
Oracle Server Errors)
• felhasználó által definiált hibák (user defined errors).

10.1. A kivételek elkapása


Ha egy kivétel generálódon a blokk vagy alprogram normális futása megáll, és a
hibakezelő rész kapja meg a vezérlést. A hibakezel ö rész szintaktikája a következő :
DECLARE

BEGIN

100
IO.PUSQL hibák kezelése Iváncsy Renáta

EXCEPTION
WHEN kivetel nevl THEN <utasitasol>;
WHEN kivetel nev2 THEN <utasitasok2>;

WHEN kivetel nevN THEN <utasitasokN>;


WHEN OTHERS THEN <utasitasokN+l>;
END
Annak érdekében, hogy elkapjunk egy hibát, kezeJöt (handler) kell Imi hozzá. Minden
kezelő része a WHEN kifejezés, ami megadja a kivételt, majd utána azokat az utasításokat
tartalmazza, amit a kivétel hatására le akarunk futtatni. Ha egy kivétel generálódott. az
EXCEPTION részre kerül a vezérlés, és az az utasítássorozat fog lefutni, ami a megfelelő

WHEN után található. Ezután a vezérlés nem kerül vissza oda, ahol a hiba keletkezett. hanem
kilép a blokkból és a blokkot tartalmazó blokkban folytatódik a program futása. Ha mégis azt
szeretnénk, hogy a hiba kezelése után ott folytatódjon a program, ahol abbahagytuk, tegyük
alblokkba a kívánt részt, saját hibakezelöveL Ha hiba keletkezik, a hibakezelő lefut a belső

blokkban és a program a külsöben folytatja a futást.


Az opcionális OTHERS kulcsszó segítségével lehet biztositani, hogy nem hagyunk
egyetlen kivételt sem kezeletlenül. Ha egy WHEN-re sem illeszkedik a kivétel, és van OTHERS
része a kivételkezelő résznek, akkor az ott található utasítások fognak lefutni.
Ha ugyanazokat az utasításokat szeretnénk lefuttatni több különbözö kivételre, akkor a
WHEN kulcsszó mögött a különböző utasítások nevét VAGY kapcsolatba hozhatjuk az OR
kulcsszóval. Az OTHERS kulcsszó nem szerepelhet vagy kapcsolatban, annak mindig k.ülön
kell állnia, és mind.ig neki kelllennie a WHEN-ek sorozatában az utolsónak.
Ha a kurzor-FOR ciklusban generálódik hiba, a kurzor magától bezáródik, így a
kivételkezelő részben nem hivatkozhatunk az explicit kurzor attribútumokra.
Egyéb fontos tudni valók a kivételkezelésröl:
• Ha a deklarációs részben keletkezik a hiba, azt nem tudjuk elkapni abban a blokkban,
ahol a hiba keletkezett, csak a befoglaló blokkban.
• Ha a kivételkezelő részben generálódik egy hiba, akkor azt sem lehet már ugyanabban
a blokkban lekezelni, ahol generálódott, hanem csak egy külsö blokkban, ami azt a
blokkot tartalmazza.
• A GOTO utasítással nem ugorhatunk be egy kivételkezelöbe és nem is ugrohatunk
vissza a kivételkezelöböl a blokk törzsébe. Viszont a kivételkezelöböl ki ugorhatunk a
blokkot befoglaló blokkba.

!Ol
IO.PUSQL hibák kezelése lváncsy Renáta

l 0.2. Elöre definiált kivételek


Minden Oracle hibának van egy száma, de a kivételeket név szerint lehet lekezelni. A
PUSQL elöre definiált néhány gyakran előforduló hibát, mint kivételt. A PUSQL az elöre
definiált kivételeket a STANDARD csomagban deklarálja. Az elöre definiált hibákat nem kell
deklarálni, és generálni sem kell, mert az automatikusan megtörténik. Mindazonáltal
lehetőségünk van generálni a RA Is E utasítás segitségével. Az alábbi táblázatban az előre

definiált kivételek listája található:


A kivétel neve Orac:le Server Error Number l SQLCODE Value
ORA-06530 l -6530
ACCESS_INTO_NULL A program nem inicializált (automatikusan NULL
értékű) objektum attribútumának próbál értéket adni.
ORA-06592 l -6592
A CASE utasítás egyetlen WHEN feltételére sem
CASE_NOT_FOUND
illeszkedett a kifejezés, és nincsen ELSE ága az
utasításnak.
ORA-06531 l-6531
A program egy nem inicializált (automatikusan NULL
értékű) nested tábla vagy varray összetett adattípusra
COLLECTION_IS_NULL
próbál használni az EXISTS-töl eltérö metódust, vagy a
program nem inicializált nested tábla vagy varray
elemének értéket akar adni.
ORA-06511 l -6511
A program egy már megnyitott lrurzort próbál
megnyitni. A kurzort be kell zárni, mielött újra meg
CURSOR_ALREDY_OPEN
lehetne nyitni. A lrurzor-for ciklus automatikusan
megnyitja a hivatkozott lrurzort, így a cikluson belül már
nem lehet ismét megnyitni a lrurzort.
ORA-00001 l -l
A program két azonos értéket próbál meg eitároini az
DUP_VAL_ON_INDEX
adatbázisban egy olyan oszlopban, ahol egyedi index
került definiálásra.
ORA-01001 l-1001
INVALID CURSOR A program illegális kurzor müveletet hajtott végre, mint
például bezárt egy még ki sem nyitott lrurzort.
ORA-01722 l -1722
Az SQL utasításban a karakter sztring számmá való
INVALID_NUMBER konvertálása sikertelen, mert a sztring nem egy értényes
számot tartalmaz. (Ha procedurális utasítás közben
történik ez meg, VALUE ERROR hiba generálódikj_.
ORA-01017 l -1017
LOGIN_DENIED A program érvénytelen felhasználói névvel vagy
jelszóval próbált belépni az Oracle-re.
ORA-01403 l +100
NO_DATA_FOUND A SELECT INTO utasítás egyetlen egy sorral sem tér
vissza, vagy a program egy nested tábla törölt elemére

102
IO.PUSQL hibák kezelése Iváncsy Renáta

vagy egy index-by tábla nem inicializált elemére


hivatkozik.
Az oszlopfilggvények. mint pl. az A VG vagy a SUM
mindenképp visszatérnek valamilyen értékkel vagy a
NULL értékkel, így az olyan SELECT INTO utasítás,
ann oszlopfilggvényeket használ soha nem generál
NO DAT A FOUND kivételt.
ORA-01012 l -1012
NOT_LOGGED_ON A program úgy próbál adatbázis müveletet végrehajtani,
hogy nincs kapcsolódva az adatbázishoz.
PROGRAM_ERROR
ORA-06501 l -6501
A PUSQL-nek belső problémája van.
ORA-06504 l -6504
ROWTYPE_MISMA TCH Az értékadó utasításban szereplö kwzor változónak
inkompatibilis visszatérési értéke volt.
ORA-30625 l -30625
SELF_IS_NULL A program egy NULL objektum példányon próbált
megruvni egy metódust.
ORA-06500 l -6500
STORAGE_ERROR A PUSQL kifut a memóriából, vagy a
memóriahivatkozás hibás.
ORA-06533 l -6533
A program a nested tábla vagy a varray olyan elemére
SUBSCRIPT_BEYOUND_COUNT
hivatkozik. aminek indexe nagyobb, mint a kollekció
elemeinek a száma.
ORA-06532 l -6532
A program olyan index értékkel hivatkozik a nested
SUBSCRIPT_OUTSIDE_LIMIT
tábla vagy a varray egy elemére, ami a legális határokon
kivül esik (pl. -1 ).
ORA-01410 T-t4to
SYS_INVALID_RO WID A karakter sztring konverziója rowid tipusra hibát okoz,
mivel a sztring nem egy érvényes rowidet tartalmaz.
T~OUT_ON_RESOURCE
ORA-00051 l -51
Time-out történt, amíg az Oracle egy erőforrásra vár.
ORA-01422 l -1422
TOO_MANY_ROWS A SELECT INTO utasítás több mint egy sorral tér
vissza.
ORA-06502 l -6502
Aritmetikai konverziós, csonkolásos vagy méret
megkötéssel kapcsolatos hiba keletkezett. Dyen pl. ha az
oszlopból való lekérdezés során olyan változóha akaijuk
betenni az értéket, aminek hossza rövidebb, mint az
V ALUE_ERROR
oszlopban tárolt érték hossza.
Procedurális utasítások es etén a VALUE ERROR
kivétel keletkezik, ha a karakter sztringböl nem sikerül
számmá konvertálni. (SQL utasítás esetén az
INV ALID NUMBER kivétel generálódik)
ZERO_DIVIDE
ORA-01476 l -1476
A oro2ralll nullával próbált osztani.

103
l O.PUSQL hibák kezelése Iváncsy Renáta

Ha egy előre definiált kivételt felüldeklarálunk. akkor a lokális kivétel felülúja a


globálist. Ha a globálisra szeretnénk ismét hivatk.omi, akkor a STANDARD. kivételnév
módon kell hivatk.omi:
EXCEPTION
WHEN invalid number OR STANDARD.INVALID NUMBER THEN
- - hiba kezelése
END;
Az alábbiakban egy példa látható a NO_DATA_FOUND kivétel hasmálatára. Az eljárás
bemenetként egy diák azonosítót kap, kimenete pedig a diák neve, amennyiben létezik a
beadott azonosító. Ha nem létezik. a kimenet a "Nincs ilyen hallgato" lesz.
CREATE OR REPLACE PROCEDURE student_by_id
(studid CHAR, studname OUT VARCHAR2) IS
BEGIN
SELECT stud_lname l l ' ' l l stud_fname INTO studname
FROM student WHERE stud id = studid;
EXCEPTION
WHEN NO DATA FOUND THEN
studname := 'Nincs ilyen hallgato"
END;

10.3. Felhasználó által definiált kivételek


A PUSQL lehetőséget ad arra, hogy a felhasználó saját kivételeket készítsen. Ezeket a
kivételeket deklarální kell, majd a megfelelő helyen generálni a RAI SE utasítással.
A kivételeket csak a blollok, alprogramok és csomagok deklarációs részében lehet
deklarálni. A kivétel deklarálásának szintaxisa:
kivétel_név EXCEPTION;
Noha a kivételek deklarálása hasonlít egy változó deklarálásához, a kivétel mégsem
változó. Nem jelenhet meg sem értékadó utasításban, sem SQL utasítás ban. A láthatósági tere
(scope) azonban megegyezik a változókéval.
A kivételt a RAISE utasítássallehet generálni:
RAISE kivételnév;
Nézzünk egy példát felhasználó által definiált, generált és kezelt hibára! Az alábbi tárolt
eljárással egy diák egy vizsgára tud jelentk.emi, amennyiben még a vizsga nem múlt el, és
még van hely az adott vizsgán.

104
IO.PUSQL hibák kezelése lváncsy Renáta

CREATE OR REPLACE PROCEDURE vizsgajelentkezes


(studid CHAR, examid INT) IS
lejartvizsga EXCEPTION;
datum DATE;
roylimit INT;
jelentkezettek INT;
betelt EXCEPTION;
BEGIN
SELECT ex_date, ex limit INTO datum, roylimit
FROM exam WHERE ex id = examid;
IF datum < sysdate THEN
RAISE lejartvizsga;
END IF;
SELECT COUNT (*) INTO jelentkezettek FROM student exam
WHERE sx examid = examid;

IF jelentkezettek >= roylimit THEN


RAISE betelt;
END IF;
INSERT INTO student exam VALUES (studid, examid);
EXCEPTION
WHEN lejartvizsga THEN
DBMS_OUTPUT.PUT_LINE('A vizsga mar elmult');
WHEN betelt THEN
DBMS OUTPUT.PUT LINE('A vizsga betelt');
WHEN NO DATA FOUND THEN
DBMS_OUTPUT.PUT_LINE('A vizsga azonosita nem letezik');
WHEN OTHERS THEN
DBMS OUTPUt.PUT LINE('Hibas diak kod');
END;
Az eljárás első lépésként leellenörzi, hogy a vizsga még nem járt-e le. Amennyiben igen,
egy LEJARTVIZSGA nevükivételt generál. A program vezérlése az EXCEPTION részre
ugrik. Amennyiben a bemenetként kapott azonosító nem tartozik vizsgaalkalomhoz, az elsö
lekérdezés egy NO DATA FOUND kivételt generál. Ha a vizsga még nem járt le,

105
lO.PUSQL hibák kezelése lváncsy Renáta

megszámoljuk. hogy hányan jelentkeztek eddig rá. Ezt a JELENTKEZETTEK változóban


tároljuk el. Amennyiben ez az érték eléri a limitet, a BETELT nevü kivételt dobjuk.
Amennyiben a vizsga még nem telt be, beszútjuk a jelentkezést a STUDENT _ EXAM táblába.

l 0.4. A kivételek láthatósága


Egy kivételt nem lehet kétszer deklarálni egy blokkon belül, de két különböző blokkban
már igen. Egy blokkban deklarált kivétel lokális a blokkra nézve, de globális a blokk összes
alblokkjára nézve. Mivel egy blokkban csak lokális vagy globális kivételekre lehet hivatkozni,
így nem lehet az alblokkban deklarált kivételekre hivatkozni a befoglaló blokkból. Ha az
alblokkban felüldefiniálunk egy kivételt, akkor az alblokkban definiált kivétel elfedi a külsö
blokkbeli kivételt. Ekkor csak akkor lehet hivatkozni a külső blokk kivételére, ha a blokknak
volt címkéje. A hivatkozás szintaktikája: labelnev. kivetelnev.

10.5. Nem előre definiált hibák


A nem előre definiált hibának nincsen neve, noha a kivételeknél mi csak névvel
hivatkozhatunk egy hibára, vagy pedig az OTHERS lrulcsszó után tudjuk lekezelni. Ezért
lehetőség van az ORACLE által névvel nem ellátott hibákhoz nevet rendelni az
EXCEPTION_INIT pragmával. A pragma egy forditó direktíva, a fordítási időben fut le,
nem pedig a futási időben. A PUSQL-ben az EXCEPTION_INIT pragma megadja a
fordítónak, hogy rendelje össze a megadott kivétel nevet a megadott Oracle hibával. Ezáltal
lehetőségünk van bármely hibára névvel hivatkozni, és a kivételkezelő blokkrészben
lekezelni. Az EXCEPTION_ I NI T pragma definiálásának szintaktikája a következő :
PRAGMA EXCEPTION_INIT (kivételnév, Oracle_hiba_száma);
A kivételnév egy korábban deklarált kivétel neve. A pragmának a kivétel deklarálása
után kell szerepelnie, még ugyanabban a deklarációs részben, ahogy az a példában is látható:
DECLARE
holtpont volt EXCEPTION;
PRAGMA EXCEPTION_INIT(holtpont volt, -60);
BEGIN

EXCEPTION
WHEN holtpont volt THEN
-- a hiba kezelése
END;

106
IO.PUSQL hibák kezelése lváncsy Renáta

10.6. A RAISE APPLICATION ERROR


A RAISE_APPLICATION_ERROR eljárással lehetőségilnk van a felhasználó által
definiált hibaüzenetek készítésére. Dyen módon hibákat k:üldhetünk a programunknak és
elkerülhetjük a kezeletlen kivételeket. A RAISE_APPLICATION_ERROR hívását a
következő szintaktikával tehetjük meg:
Raise_application_ error(hiba_szám, üzenet[,{TRUE l FALSE}]);
A hiba _ szám-nak egy negatív integernek kell lennie -20000 .... -20999 között, az
üzenet pedig egy karakter sztring, melynek maximum hossza 2048 byte lehet. Ha az
opcionális paraméter TRUE, a hiba az előző hibák tetejére kerül a stackben. Ha FALSE (ez az
alapértelmezett), a hiba az összes többi hiba helyett kerül be a stackbe.
Ha egy raise_application_error generálódik. az alprogram befejeződik, és a
felhasználó által definiált hibaszámmal és üzenettel tér vissza. A hiba számot és üzenetet úgy
lehet lekezelni, mint bármely Oracle hibát.
CREATE OR REPLACE FUNCTION getStudName (studid CHAR)
RETURN VARCHAR2
Result VARCHAR2(100);
IS
SELECT stud_fname l l ' ' l l stud_lname INTO result
FROM student WHERE stud id = studid;
RETURN result;
EXCEPTION
WHEN NO DATA FOUND THEN
RAISE_APPLICATION_ERROR(-20101,'Hibas diak kod');
END;

10.7. A kivételek terjedése


Ha egy kivétel generálódott, és a PUSQL nem találja az adott blokkban vagy albioldban
a hozzá tartozó kivételkezelőt, a kivétel elkezd tetjedni. Ez azt jelenti, hogy kivétel
megjelenik a blokkot tartalmazó blokkban, és ott keresi a hozzá tartozó kivételkezelőt Ha ott
sem találja, egyel kintebb lép és így tovább, egészen addig, amíg megtalál egy hozzá tartozó
kezelőt, vagy nincs több blokk kintebb. Ha nem talált kezelőt, PUSQL egy kezeletlen kivétel
(unhandled exception) jelzéssel tér vissza a futtató környezethez. Egy kivétel távoli
filggvényhíváson nem tud keresztül menni, ezért egy PUSQL blokk nem tud elkapni egy
olyan kivételt, amit egy távoli filggvény vagy eljárás generált.

107
IO.PUSQL hibák kezelése Iváncsy Renáta

llliCiill

8ZG[J1

Il!' Y = l THilll
ll.A[:iZ A ;
lll..::it:l' 'JI = ~ THJU1

JILJJI : : : : :
· )
lllliO Il!' ;

:SYCI!PT !Dll El oeplio n B pro~ata; to


the lirslendasorg b lod<. wrth
an a~ropriaiB handler
:Sli D ;

BJ'CBFr [Cll

Eloep lio n B i; handlad .


then control pa138116 to the
ZJ1D ;
host environment

3 Ábra: A ldvitelek terjedile

10.8. Hiba kód, hiba üzenet


A SQLCODE és a SQLERRM beépített függvényekkel megkaphatjuk. hogy melyík hiba
keletkezett, és megkaphatjuk a hibaüzenetet is. Belső kivételeknél az SQLCODE az Oracle
hiba számát adja vissza, ami negatív, kivéve, ha a NO_ DATA_ FOUND hiba keletkezett, mert
akkor + 100 az értéke. Az SQLERRM a hibaüzenetet adja meg. Az üzenet az Oracle hiba
kóddal kezdődik. A felhasználó által definiált kivételeknél az SQLCODE filggvény +l-et ad
vissza, az SQLERRM a következő üzenetet: Use r- De f i ned Exception.
Egy Oracle hiba üzenet maximális hossza 512 karakter lehet. Ha nem volt hiba, az
SQLCODE nullát ad, az SQLERRM pedig a következőt: ORA-0000: normal,

successful completion.

A két függvényt nem használhatjuk közvetlen SQL utasításban, hanem előtte értékül kell
adni öket egy változónak.

108
IO.PUSQL hibák kezelése Iváncsy Renáta

DECLARE
err num NUMBER;
err_msg VARCHAR2(100);
BEGIN

EXCEPTION

WHEN OTHERS THEN


err num .- SQLCODE;
err_msg := SUBSTR(SQLERRM, l, 100);
INSERT INTO errars VALUES (err_num, err_msg);
END;

109
11 .PUSQL triggerek Iváncsy Renáta

ll. PL/SQ L triggerek


A triggerek olyan eljárások. amelyek táblák vagy nézetek módosításakor, bizonyos
felhasználói eseményekre vagy adatbázis rendszer eseményekre implicit lefutnak. azaz az
Oracle által meghívásra kerülnek és végrehajtódnak. A triggerek PUSQL vagy Java nyelven
írt eljárások, amik az adatbázisban kerülnek tárolásra, de lehetnek C hívások is. Az
események, amelyekre triggert definiálhatunk a következök lehetnek:
• DML (Data Manipulalion Language) utasítások, amik táblák adatait módosítják
(INSERET, UPDATE vagy DELETE)
• DDL (Data Definition Language) utasítások
• Rendszer események, mint például a startup, shutdown és hiba üzenetek
• Felhasználói események, mint például a Jogon és a logoff.

11.1. Trigger DML utasításra


Az INSERT, UPDATE és DELETE utasításokra írt triggerek esetén meghatározható,
hogy a trigger mikor fusson le, a kiváltó esemény lefutása előtt, után vagy helyett. Az is
megadható, hogy a trigger egy utasítás esetén csak egyszer fusson le, vagy minden, az utasítás
alapján érintett sor esetén. Ezen kívül lehetőség van feltétel megadására, így az adott utasítás
esetén nem azonnal fut le a trigger, hanem először kiértékelődik az adott feltétel, és csak
annak igaz eredménye esetén fut le.
A triggeren belül lehetőség van az éppen beszúrandó, vagy az éppen törölt adatokra
hivatkozni. A módosítás esetén létezikmind új adat. mind régi. Az új adatokat a new átmeneti
tábla tárolja el, a régieket az old nevü átmeneti tábla. A triggerben a :new. oszlopnév
vagy a :old. oszlopnév szintaktikával hivatkozhatunk az egyes oszlopokra. Ezek a táblák
átmeneti táblák a rendszerben, amiknek az oszlopai megegyeznek annak a táblának az
oszlopaival, amire éppen az aktuális trigger lefut. Fontos megjegyezni, hogy ezeket a
változókat csak sor trigger esetén használhatjuk (ld. késöbb ).
A DML utasításokra írható triggerek szintaktikája a következő:
CREATE [OR REPLACE) TRIGGER trigger név
{BEFORE l AFTER l INSTEAD OF}
{INSERT l DELETE l UPDATE [OF oszlopnévl, oszlopnév2 [, .. n))}
[OR [ ... n))
ON {táblanév l (NESTED TABLE nested table oszlop OF) nézet }
[FOR EACH ROW)
[WHEN (feltétel)]
{PL/SQL blokk l alprogram_hivás}

110
II .PUSQL triggerek lváncsy Renáta

A CREATE TRIGGER utasítással bozhatunk létre új higgert egy táblára vagy nézetre. Az
OR REPLACE kulcsszó használatával egy már meglévő higgert irhatunk felül, igy

módosításkor nem kell explicit törölni a higgert mielőtt újra létreboznánk. A


trigger_név-re a nevek általános szabályainak betartásán túl az egyetlen megkötés, hogy
ne legyen azonos nevü Irigger az adott sémában.
Miután megfelelöen megadtuk a különbözö kulcsszavakat, a PUSQL blokk következik.
Itt találhatóak azok a PUSQL utasítások, amiket le szerelnénk futtatnia triggerben. Lehetőség

van azonban arra is, hogy az utasításokat egy külön tárolt eljárásba újuk meg, és itt csak
meghivjuk az adott eljárást.

11.1.1. BEFO RE, AFTER trigger

A BEFORE és az AFTER kulcsszavakkal határozhatjuk meg, hogy az adott Irigger az


utasítás előtt (BEFORE) vagy után (AFTER) fusson le. BEFORE vagy AFTER tr iggerek

csak táblákra futhatnak le, nézetekre nem.


BEFORE higgert két esetben szokás használni. Az egyik eset, amikor a Iriggerben

szereplő utasítások alapján dől el, hogy a higgert kiváltó utasítás végrebajtódjon-e. Ha azt
szeretnénk, hogy mégse fusson le az adott utasítás, akkor a Iriggerben egy hibát kell generálni,
ilyenkor az utasítás visszagörgetödik. A másik eset BEFORE Irigger használatára, amikor
származtatott oszlop értékét szerelnénk kiszámolni még a beszúrás vagy a módosítás
végrehajtása előtt. BEFORE Irigger esetén a :new értéke irbató, de a :old értéke nem.
l
AFTER higgert akkor célszerü használni, amikor a végrebajtott utasítás alapján lehet

döntést hozni. AFTER Irigger esetén nem irbató sem a :new , sem a :old érték.

11.1.2. INSTEAD OF trigger

Az INSTEAD OF higgert olyankor kell használni, amikor a higgert kiváltó esemény


végrebajtása helyett azt szeretnénk, ba a Iriggerben leírt utasítások kerülnének végrehajtásra.
Az INSTEAD OF Irigger csak DML utasításra és csak nézetre használható. Az INSTEAD
OF Irigger segítségével megoldható, hogy egy nézetre is lehessen írni normális INSERT,

UPDATE és DELETE utasításokat, és a Irigger módosítja a nézet alatt található táblákat. Az


INSTEAD OF Irigger minden sorra aktiválva lesz, amit a nézetben módosftunk. Mind a

:new mind a :old értéke olvasható, de egyik sem irbató.

ll l
1l.PUSQL triggerc:k Iváncsy Renáta

11.1.3. INSERT, DELETE, UPDATE

Az INSERT, UPDATE és a DELETE a lrulcsszavakkal adhatjuk meg, hogy milyen


utasításra fusson le az adott trigger. Az UPDATE esetén lehetőség van oszlopnevek
megadására. ami azt jelenti, hogy a megadott oszlopok módosításakor fog csak lefutni az
adott trigger. Egy táblára egyszerre több triggert is megadhatunk. és az is lehetséges, hogy egy
adott trigger több, különböző eseményre fusson le. Dyenkor V AGY kapcsolatba hozhatjuk a
különböző eseményeket. Ezt az OR lrulcsszó segítségével tehetjOk meg.
Ha több eseményre definiáltunk egy triggert, felmerülhet az igény, hogy a triggeren belül
lekérdezzük, hogy melyik eseményre aktivizálódon a trigger. Ezt a következő utasításokkal
tehetjOk meg:
IF INSERTING THEN _ END IF; -- ha beszuras volt
IF DELETING THEN END IF; ha torles volt
IF UPDATING THEN .•. END IF; -- ha modositas volt

11.1.4. ON tibianév
Az ON lrulcsszó után kell megadni a táblanevet, vagy nézetnevet, amin a korábban
megadott utasítás végrehajtása esetén a triggemek le kell futnia.

11.1.5. FOR EACH ROW

Az opcionális FOR EACH ROW lrulcsszóval adhatjuk meg azt, hogy az adott trigger
minden sorra lefusson-e, ami érintve van a triggert kiváltó utasítás által vagy csak egyszer.
Abban az esetben, ha csak egyszer fut le, utasítás triggemek hívjuk. ha minden sorra, akkor
sor triggemek.
Sor trigger esetén a trigger annyiszor lefut, ahány sort érint a triggert kiváltó utasítás.
Például ha egy módosítás 3 sort érint, sor trigger esetén az adott trigger háromszor fog Iefutni.
Ha a triggert kiváltó utasítás egyetlen sort sem érint, akkor a trigger egyszer sem fut le. Sor
trigger használata akkor hasznos, ha a triggerben szereplő utasítások függenek a triggert
kiváltó utasítás által érintett sor adataitól. Fontos megjegyezni, hogy a new és az old táblák
soraira csak sor trigger esetén hivatkozhatunk.
Utasítás trigger esetén a trigger pontosan egyszer fut le, függetlenül attól, hogy a triggert
kiváltó utasítás hány sort érintett a táblán belül. Ha egyetlen sort sem érint a triggert kiváltó
utasítás, a trigger egyszer akkor is lefut Utasítás triggert akkor érdemes használni, ha a
triggerben szereplő utasítások nem függenek az érintett soroktóL Dyen lehet például komplex
biztonsági ellenőrzés a felhasznáJón vagy az aktuális idön.

112
ll.PUSQL Iriggereit lváncsy Renáta

11.1.6. A WHEN kulcsszó

A WHEN kulcsszó után van lehetőségünk megadni egy feltételt, ami a trigger lefutására
vonatkozik. A feltétel kiértékelésének eredménye IGAZ, HAMIS vagy NULL lehet. A trigger
csak abban az esetben fut le, ha a feltétel eredménye IGAZ.

11.1.7. Példa DML triggerre

Az alábbi BEFORE trigger arra felügyel, hogy egy Irurzusra ne tudjon több diák
jelentkezni, mint amennyit a limitben megengednek. A triggeren belül nem megengedett a
tranzakció kezelő utasítások használata, így ha meg szeretnénk akadályozni, hogy egy utasítás
lefusson, azt hiba generálásával tudjuk megoldani.
CREATE OR REPLACE TRIGGER kurzus limit
BEFORE INSERT ON student course
FOR EACH ROW
DECLARE
mylimit INT;
db INT;
BEGIN
SELECT cou_limit INTO mylimit FROM course
WHERE cou id = :new.sc_courseid FOR UPDATE;
SELECT count(*) INTOdb FROM student_course
WHE~ sc courseid = :new.sc_courseid;
IF db = limit THEN
RAISE APPLICATION_ERROR(-201002,'Mar betelt');
END IF;
END;

11.2. Trigger adatbázis eseményre és DDL eseményre


Adatbázis események, amikre triggert írhatunk a következök lehetnek:
• Adatbázis elinditás (startup) és leállítás (shutdown)
• Szerver hibaüzenetek
• LOGON, LOGOFF
Triggerek adatbázis eseményekre vagy DDL eseményekre adatbázis vagy séma szintüek
lehetnek. Az adatbázis eseményre vagy DDL eseményre definiált triggerek szintaktikája a
következő:

113
11.PUSQL triggerelr. lváncsy Renáta

CREATE OR REPLACE TRIGGER trigger név


{BEFORE l AFTER}
{adatbázis_esemény l DDL_ esemény } [OR] [ ... n]
ON {SCHEMA l DATABASE}
WHEN (feltétel)
{PL/SQL blokkl alprogram_hivás}
Az OR kapcsolat csak az adatbázis eseményeken belül vagy csak a DDL eseményeken
belül állitható fel. A különbözö adatbázis események a SERVERERROR, a LOGON, a
LOGOFF, a STARTUP, a SHUTDOWN és a SUSPEND események lehetnek:

SEKVERERROR
Segitségével egy szerver hibára állíthatunk triggert. A következő hibákra nem fut le a
trigger:
• ORA-01403: Data not found
• ORA-01422: Exact fetch returns more than requested number ofrows
l
• ORA-01423: Error encountered white checking for extra rows in exact fetch
• ORA-01034: ORACLE not available
• ORA-04030: out of process memory
A triggeren belül a kiváltó hiba számára az IS_SERVERERROR(hiba_szám)
filggvénnyel kereshetünk rá, aminek az eredménye TRUE, ha a zárójelben megadott pozitív
szám egyezik a szerver hibaszámávaL Csak AFTER trigger használható a
SERVERERROR adatbázis eseményre.
CREATE OR REPLACE TRIGGER hiba trigger
AFTER SERVERERROR ON SCHEMA
BEGIN
IF IS_SERVERERROR(00001) THEN

END IF;
END;
LOGON
A trigger akkor fut le, ha egy kliens alkalmazás belépett az adatbázisba. Csak AFTER
t r igg e r használható rá.

LOGOFF
A trigger akkor fut le, ha egy kliensalkalmazás kilép az adatbázisbóL Csak BEFORE
trigger használható rá.

114
II.PUSQL triggerek lváncsy Renáta

STARTUP
A trigger akkor fut le, ha az adatbázis megnyitásra került. Csak AFTER trigger
használható rá. Csak adatbázisra állítható be.

SHUTDOWN
A trigger lefut, ha az adatbázis egy példánya leáll. Csak BEFORE trigger használható
rá. Csak adatbázisra állítható be.

SUSPEND
A trigger akkor fut le, ha egy szerver hiba egy tranzakciót felfilggeszt. Csak AFTER
t r i g ge r használható rá.

11.2.1. F6bb DDL utasítások

A különbözö főbb DDL események az alábbiak lehetnek.

ALTER
A trigger akkor fut le, ha agy ALTER utasítással valamilyen adatbázis objektumot
megváltoztatunk. ALTER DAT ABASE utasítás esetén a trigger nem fut le.

CREATE
A trigger akkor fut le, ha CREATE utasítással valamilyen adatbázis objektumot
létrehozunk. A CREATE DATABASE és a CREATE CONTROLFILE utasítás esetén a
trigger nem fut le.

DROP
A trigger akkor fut le, ha a DROP utasítással valamilyen adatbázis objektumot letörlünk.

GRANT
A trigger lefut, ha a GRANT utasítással valamilyen rendszer szintű vagy objektum szintű
jogot vagy szerepet adunk valamely felhasználónak vagy szerepnek.

RENAME
A trigger lefut, ha a RENAME utasítással valamely adatbázis objektum nevét
megváltoztatj uk.

REVOKE
A trigger lefut, ha a REVOKE utasítással megvonunk valamilyen rendszer szintű,
felhasználói szintű jogot vagy szerepet valamely felhasználótól vagy szereptöl.

115
11 .PUSQL ttiggerek Iváncsy Renáta

11.3. Triggerek futása


Egy trigger két állapotban lehet, vagy engedélyezve van (enabled), vagy tiltva van
(disabled). Egy engedélyezett trigger lefut, ha atriggert kiváltó esemény kiadásra kerül, és a
triggerben szereplő feltétel IGAZ eredményt ad. Egy tiltott trigger soha nem fut le. A
különbözö triggerek lefutásának sorrendje a következő:
l . Összes BEFO RE utasítás trigger futtatása, ami az adott utasításhoz kapcsolódik.
2. Ciklus minden egyes érintett sorra a táblában
a. Lefuttatja az összes BEFORE sor triggert, ami az utasításhoz kapcsolódik
b. Zárolja, és módosítja a sort, és az integritás ellenőrzést elvégzi
c. Lefuttatja az összes AFTER sor triggert, ami az utasításhoz kapcsolódik
3. Végrehajtja a közvetett integritás vizsgálatot
4. Lefuttatja az összes AFfER utasítás triggert, ami kapcsolódik az adott utasításhoz.
A lefutási modell rekurzív, azaz ha a triggerben van olyan utasítás, ami egy újabb triggert
indít el, akkor annak lefutási sorrendje előröl kezdődik .

116
12.Tranzakciók PUSQL-ben Iváncsy Renáta

12. Tranzakciók PL/SQL-ben


Egy adatbázis-kezelő rendszer esetén alapvető elvárás, hogy az adatokat konkurensen,
egyszerre többen tudják kezelni. Szintén elvárás azonban, hogy a különböző száJon kezelt
adatok egymásra ne legyenek hatással. Az ilyen problémák hatékony kezelésére vezették be a
tranzakciók fogalmát
Egy tranzakció a munka egy logikai egysége, ami egy vagy több SQL utasításból állhat.
A tranzakció a munka egy logikai egysége. A tranzakció több végrehajtandó folyamat, amely
adatbázis-elérést is tartalmaz, és logikailag egyetlen egységet alkot. A tranzakciót vagy el
lehet fogadni (COMMIT), vagy vissza lehet fejteni (ROLLBACK). Ha a tranzakció valamilyen
okból megszakad, az adatbázis-kezelő rendszer automatikusan visszaállítja eredeti formájára
az adatbázist. A tranzakciónak négy tulajdonsága van, amit mindenképpen teljesítenie kell:
• Atomicitás: A tranzakció oszthatatlan. A benne szereplő utasítások vagy mindegyike
lefut, vagy egyik sem közülük.
• Konziszetncia: A konzisztencia lényegében azt jelenti, hogy az adatbázisban tárolt
adatok ellentmondásmentesek. Ami a tranzakciókat illeti, a konzisztencia alatt azt
értjük, hogy egy tranzakció az adatbázist egy konzisztens állapotából konzisztens
állapotába viszi át.
• Izoláció: Az izoláció alatt azt értjük, hogy feltételezzük, hogy a tranzakció elvárt,
korrekt eredménye az, amit akkor kapnánk, ha a tranzakció futása közben más
tranzakció nem futna.
• Tartósság: Ha egyszer végrehajtottuk a tranzakciót, akkor az általa végzett
módosítások nem vesznek el.
Az adatbázisban az adatok módosítását úgy kell elvégezni, hogy az adatbázis konzisztenciája
megmaradjon. Ez akkor okozhat gondot, ha egyszerre többen csatlakoznak az adatbázishoz.
Az adatbázis konzisztenciájának megőrzését az adatbázis-kezelő rendszer oldja meg. Az
Oarcle zárokkal (lock) tartja kézben a konkurens adathozzáférést A zár segítségével lehet
biztositani, hogy csak az tudjon módositani a táblában, vagy annak egy sorában, aki először

igényelte a hozzáférést. Mindezt addig, amíg az be nem fejezte a müveletet. Sosem kell
explicit igényelni a zárolást, azt megteszi az Oracle automatikusan. Lehetőség van azonban
adat zárak explicit kérésére, hogy ha az jobb, mint az előredefiniált zárolás.
Holtpont (deadJock) akkor alakulhat ki, ha két vagy több felhasználó egymás erőforrásaira

vár. Például A zároljaa student táblát, és a teacher táblából szeretne olvasni, míg B

117
12.Tranzakciólr. PUSQL-ben Iváncsy Renáta

zárolja a teacher táblát és a student-böl szeretne olvasni. A boltpontot az Oracle


feloldja, és hiba üzenetet küld az utolsó tranzakciónak, ami miatt létrejött a holtpont.
Ha egy táblát egy lekérdezés olvas, és ugyanakkor egy másik felhasználó módosí~a, az Oracle
egy read-consistent nézetet hoz létre a lekérdezés számára, így a lekérdezés azokat az
adatokat látja, ami a lekérdezés kezdetén érvényesek voltak. Amikor a másik felhasználó
módosít, az Oracle egy pillanatképet (snapsbot) rak el a rollback szegmensbe, és a rekordok
változásait is eltárolja. Az Oracle a rollback szegmenst arra használja, hogy a read-consistent
nézetet adja, és hogy szakség eselén visszaállíthassa (rollback) az update elötti állapotot
Oracle-ben a tranzakció kezdete az elsö végrebajtható SQL utasítás. A tranzakció vége
lehet explicit módon meghatározott, vagy implicit is befejezbetünk egy tranzakciót. Explicit a
COMMIT (véglegesít) és a ROLLBACK (visszagörget) utasításokkal fejezbetünk be egy
tranzakciót. Implicit egy DDL utasítással fejeződik be egy tranzakció. Ha egy tranzakció
befejezödött, a következő SQL utasítás ismét egy tranzakció kezdetét jelenti. Dyen formán
minden SQL utasítás egy tranzakció része. A COMM I T és a ROLLBACK utasításokkal érb~ük

el, hogy vagy mindenki által láthatóvá, vagy meg nem történtté tegyük a változtatásokat.
Lehetőség van biztonsági pontokat (SAVEPOINT) tenni a tranzakcióba, ami elnevezi az adott
pontot a tranzakcióban.

A COMMlT utasftás

A COMMIT utasítássallebet az aktuális tranzakciót befejezni. Ekkor az összes változtatás,


amit az adatbázisban tettünk a többiek számára is láthatóvá válik. Ekkor az adatok
m.indenképpen a diszkre íródnak, és az esemény naplózásra kerül. A tranzakció által kiadott
zárakat a rendszer elengedi. Amig el nem fogadjuk a változtatásokat (COMMIT), a többi
felhasználó nem láthatja a megváltoztatott adatokat, ök azokat az adatokat látják, amik azelőtt

voltak, m.ielött a változtatásokat megtettük volna. A COMMIT hatására az összes tábla és sor
zár felszabadul.
Szintén véglegesítésre kerülnek az adatok (implicit COMMIT) ba egy DDL utasítást
hajtunk végre (CREATE, DROP, RENAME, ALTER), vagy ha a felhasználó szabályosan
bezálja az adatbázis kapcsolatot.
BEGIN

INSERT INTO anyag (anyag_id, anyag_nev) VALUES (l,'liszt')


COMMIT;

END;

118
12.Tranzakciólr. PUSQL-ben lváncsy Renáta

A ROLLBACK utasítás

A ROLLBACK utasítás befejezi az adott utasítást, és visszafejti a változtatásokat, amik a


tranzakció eleje óta történtek. Az adatok visszafejtése két okból is hasznos lehet. Az egyik,
amikor hibázunk, például rossz sort törlünk ki. Ekkor a ROLLBACK utasítással vissza lehet
állítani az eredeti állapotot A második, amikor nem tudjuk befejezni a tranzakciót valamilyen
kivétel miatt, vagy egy hibásan lefutott SQL utasítás miatt.
A módosftások szintén visszagörgetésre kerülnek, ha az adatbázis kapcsolatot a
felhasználó nem szabályos módon szakitja meg.

A SAVEPOINT

A SAVEPOINT segítségével ellehet nevezni a tranzakció egyes pontjait, és a ROLLBACK


TO utasítássallehetőség van arra, hogy az adott SAVEPOINT-ig történjen csak a visszafejtés,
ne az egész tranzakcióra.
DECLARE
emp_id emp.empno%TYPE;
BEGIN
UPDATE emp SET ... WHERE empno emp id;
DELETE FROM emp WHERE ...

SAVEPOINT do insert;
INSERT INTO emp VALUES (emp_id, ... );
EXCEPTION
WHEN DUP VAL ON INDEX THEN
ROLLBACK TO do insert;
END;
Ha visszafejtjük az utasításokat egy biztonsági pontig, akkor az utána levő biztonsági
pontok megszünnek. Egy egyszerű ROLLBACK vagy egy COMMIT az összes biztonsági
pontot megszünteti.
Ha egy rekurzív függvényben használunk biztonsági pontot, minden egyes szinten
létrejön egy, de csak a legutolsóig lehet a visszafejtést megtenni. A biztonsági pontok nevei
nem deklaráltak és újra felhasználhatóak egy tranzakción belül. Ezzel a régi biztonsági pontot
az új helyére mozgatjuk.
Egy tranzakción belül korlátlan számú biztonsági pontot tehetünk.

119
12.Tranzakciók PUSQL-ben Iváncsy Renáta

Utasítás szintü visszafejtés

Minden SQL utasítás előtt az Oracle egy implicit biztonsági pontot (SAVEPOINT) tesz le.
Így, hogy ha egy utasítás valamilyen okból nem tud végrehajtódni (például egy egyedi
indexbe két azonos értéket akarunk beszúrni), akkor a hibás utasítást visszafejti az utasítás
elötti állapotokig. Így nem vész el semmilyen módosítás, csak az, ami a hibás utasításban volt.
A másik ok SQL utasítások visszafejtésére a holtpontok elkerülése. Holtpont kialalrulását az
adatbázis-kezelő automatikusan detektálja, és az egyik tranzakció utolsó utasítását utasítás
szinten visszafejti. Így a tranzakció többi utasítása nem fejtődik vissza, csak az, ami a holtpont
kialalrulásában közvetlen szerepet játszott.

PUSQL nem fejti vissza az adatbázist, ha egy alprogram kezeletlen kivétellel tér vissza.
A legjobb megoldás, ha kezeljük a tranzakciókat Ha ezt nem tesszük meg, a futtató
környezet dönti el, hogy mi történjen. Például az SQL •PLUS környezetben, ha egy PUSQL
blokk nem tartalmazza a COMMIT vagy a ROLLBACK utasítást, a tranzakció állapota attól fog
filggeni, hogy a blokk futtatása után mit csinálunk. Ha adat definiáló, adat vezérlő vagy
COMMIT utasítást adunk ki, vagy EXIT, DISCONNECT vagy QUIT parancsot adunk ki, az

Oracle láthatóvá teszi a módosításokat (commit). Ha ROLLBACK utasítást hajtunk végre, vagy
megszakítjuk az SQL•PLUS kapcsolatot, az Oracle visszafejti a tranzakciót.

12.1. Izolációs szintek


Ha egy rendszerben nincsenek zárolási mechanizmusok., és párhuzamosan futó
folyamatok ugyanazokat a táblákat is használhatják a tranzakció ideje alatt, akkor különbözö
konkurencia problémák léphetnek fel. llyenek a következők:
• Elveszett módosítások: ha két vagy több párhuzamosan futó tranzakció ugyanazt a
sort olvassa, és a sort az olvasás alapján módosítja, akkor a legutolsó módosítás
felülírja az előtte levöeket, így a többi tranzakció adata elvész. A probléma
megoldható, ha a második tranzakció nem módosíthat, amíg az első be nem fejezte a
munkáját.
• Piszkos olvasás (dirty read): a piszkos olvasás azt jelenti, hogy egy tranzakció olyan
adat alapján dolgozik, ami még nem lett kommitálva, így értéke még változhat. A
probléma megoldható, ha a második tranzakció nem olvashatná az adatot, amíg az első

nem véglegesiti a módosításait.

!20
12.Tranzalr.ciók PUSQL-ben lváncsy Renáta

• Nem ismételhető olvasás: egy tranzakció egy sort többször egymás után kiolvas,
miközben egy másik tranzakció azt az adatot megváltoztatja, ennek hatására a
többszöri olvasás más-más eredményt ad. Annyiban k:ülönbözi.k ez a probléma a
piszkos olvasástól, hogy ebben az esetben az adatot módosftó tranzakció a módosítását
kommitálta. A probléma megoldható, ha a második tranzakció nem olvashatná addig
az adatot, amíg az első be nem fejezte az adott adat írását.
• Faotom olvasás: akkor fordul elö, ha az egyik tranzakció kitöröl vagy beszúr sorokat
egy adathalmazba, míg egy másik tranzakció az adathalmazt olvasta. Ebben az esetben
a második tranzakció olyan adatokat "lát", amik esetleg már nem is léteznek, mert a
másik tranzakció kitörölte, vagy olyan adatot nem "lát", ami már létezik, mert a másik
tranzakció létrehozta. A probléma megoldható, ha a második tranzakció megválja, míg
az első tranzakció befejezi a munkát, és az olvasást is csak akkor kezdi el.
Az SQL92 szabvány négy izolációs szintet definiál a k:ülönböző konkurencia problémák
megoldására, ezek a következők :

READ UNCOMMITTED: A piszkos olvasást vagy a O szintü izolációs szintet valósítja


meg. Ez azt jelenti, hogy nem ket11lnek megosztott zárak kiosztásra, és a kizárólagos zárak
nem lesznek figyelembe véve. A tranzakció alatt lehetőség van nem véglegesitett vagy
piszkos adat olvasására, a tranzakció befejezése előtt az adatok módosulhatnak., új sorok
jelenhetnek meg, illetve tűnhetnek el az adathalmazból. Ez a legkevésbé szigorú szint a négy
szint közül.
READ COMMITTED: A piszkos olvasás elket11lése érdekében osztott zárakat használ
olvasásra, de az adat módosulhat a tranzakció befejezödése előtt, nem megismételhető

olvasást, vagy fantom adatot okozva ezzel.


REPETEABLE READ: Zárak azokra az adatokra ket11lnek., amiket az adott tranzakció
használ, így kerülve el azt, hogy az adott adatokat más tranzakció módosítson. Lehetőség van
azonban más tranzakciók által fantom sorok beszúrására, amit a zárokkal rendelkező

tranzakció egy későbbi lekérdezéskor láthat is. Mivel a konkurencia szint ebben az esetben
alacsonyabb, mint az alapértelmezett esetben, csak akkor érdemes használni, amikor feltétlen
szükséges.
SERIALIZABLE: Az adathalmazra zárat tesz, ezáltal megakadályozva, hogy más
tranzakció módosítson, vagy sort szWjon be az adathalmazba, míg a zárral rendelkező

tranzakció be nem fejeződik . Ez a szint a legszigorúbb a négy szint közül, és mivel


használatával alacsony szintü párhuzamosság érhető el, így ajánlott minél kevesebbszer
használni.

121
12.Tranzakciók PUSQL-ben lváncsy Renáta

Az alábbi táblázat összefoglalja, hogy melyik izolációs szinttel milyen probléma fordulhat
elö, és m.i az, ami ellen védelmet nyújt. Az adott sorban és oszlopban akkor szerepel IGEN, ha
az adott probléma (oszlop) előfordulhat az adottszint esetén (sor):
Izolációs szint Piszkos olvuás Nem ismételbetli olvasás Fantom
Read uncommitted Igen Igen Igen
Read committed Nem Igen Igen
Repeatable read Nem Nem Igen
Serializab le Nem Nem Nem
Az Oracle a fent definiált négy tzoláctós szmt közül kettőt valósit meg, a Read coDlDlJtted
és a Serializable izolációs szinteken. Ezen kivül definiált egy nem szabványos izolációs
szintet is, a Read Only izolációs szintet.
A tranzakciós szintet az alábbi utasítással állíthatjuk be egy tranza.kcióra:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Dletvea
SET TRANSACTION READ ONLY
utasítással állítható be, hogy egy tranzakció csak olvasó tranzakció legyen.
Ha egy folyamatban minden tranzakciónak egyszerre szeretnénk állítani az izolációs
szintjét, azt is megtehetjük kapcsolat szinten a következő utasítással:
ALTER SESSION SET ISOLATION_LEVEL {READ COMMITTED
SERil\LIZABLE}

A READ COMMITTED izolációs szint

Az Oracle rendszerben az alapbeállítási szint a Read committed izolációs szint. Ekkor egy
tranzakció minden lekérdezése olyan adatot lát, amit a lekérdezés előtt (és nem a tranzakció
megkezdése előtt) véglegesítettek. Dyen módon elmondható, hogy Oracle-ben egy lekérdezés
sosem tud piszkos adatot olvasni. A Read comm.itted izolációs szintet olyankor érdemes
használni, ha kevés tranzakció ütközik egymással.
A Read comm.itted izolációs szint sor szintű zárolásokat használ, és a tranzakció
várakozik, ba egy olyan adatot szeretne módosítani, amit egy másik, még nem véglegesített
módosított. Amennyiben a másik tranzakció véglegesítésre került, az eredeti tranzakció is
végrehajtja a módositást.

A SERIALIZABLE izolációs szint

Az Oracle által támogatott másik szabványos izolációs szint a Serializable. Ekkor egy
tranzakció lekérdezése csak olyan adatokat láthat, amik a tranzakció kezdete előtt

véglegesitve lettek, valamint természetesen látja a saját maga által végrehajtott INSERT,

122
12.Tranzakciók PUSQL-ben Iváncsy Renáta

DELETE és UPDATE utasítások eredményét. Ahogy azt korábban említettük, ezen az


izolációs szinten nem fordulhat elö sem meg nem ismételhető olvasás sem fantom olvasás.
Olyankor érdemes ezt az izolációs szintet alkalmazni, amikor:
• nagy adatbázis esetén rövid, kevés sort módosító tranzakcióink vannak,
• relatív kicsi az esélye, hogy két konkurens tranzakció ugyanazokat a sorokat
módosítsa,
• a hosszú tranzakciók inkább csak olvasó tranzakciók.
A Serializable izolációs szint is sor szintű zárolást használ, és várakozik, ha olyan sort
akar módosítani, amit egy nem véglegesített másik tranzakció módosított. Amennyiben a
másik tranzakció visszagörgetésre került (ROLLBACK), akkor a tranzakció végrehajtja a
módosítást. Amennyiben azonban a másik tranzakciót véglegesitik (COMMIT), akkor a
"Cannot serialize access error" hibaüzenetet kapjuk, és az utolsó módosító utasítás utasítás
szinten visszagörgetésre kerül.

A READ ONLY izolációs szint

A Read only izolációs szint esetén egy tranzakció csak azokat az adatokat látja, amik a
tranzakció megkezdése előtt véglegesítve lettek, nem enged meg azonban INSERT, UPDATE
vagy DELETE utasítások futtatását.
A csak olvasható tranzakciók akkor hasznosak, ba többszörös lekérdezést akarunk futtatni
egy vagy több táblán, míg más felhasznáJók módosítják ugyanazt a táblát. A csak olvasható
tranzakció alatt az összes lekérdezés ugyanarra a pillanatképre hivatkozik (snapshot),
biztositva ezáltal a read consistent nézetet. Más felhasználók ugyanúgy lekérdezhetik és
módosíthatják az adatot, mint máskor. A COMM IT vagy a ROLLBACK befejezik a tranzakciót.
A SET TRANSACTION utasításnak kell lennie az első utasításnak a csak olvasható

tranzakcióban, és csak egyszer szerepelhet egy tranzakcióban. Ha csak olvashatóra állftjuk a


tranzakciót, az ezt követő lekérdezések azokat az adatokat látják, amik még a tranzakció előtt

el lettek fogadva (commit). A csak olvasható tranzakciókban csak a következő utasítások


megengedettek: SELECT INTO, OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT és

ROLLBACK.

123
12.Tranzakciók PUSQL-ben lváncsy Renáta

Zárolások

Alapból az Oracle automatikusan használja a zárolásokat, hogy az adatstruktúrát


megvédje. Lehetőség van azonban tábla és sor szintü zárak kiadására, ha az számunkra
megfelelőbb, mint az alap zárolások. Az explicit zárolás segítségével megoszthatjuk, vagy
megtagadhatjuk a hozzáférést a táblához a tranzakció idejére. A LOCK TABLE utasítással
egy táblára tehetünk explicit zárat. A SELECT FOR UPDATE utasítás segítségével explicit
zárat tehetünk a tábla bizonyos soraira, hogy biztosak legyünk benne, hogy azok nem
változnak, mielött egy UPDATE vagy DELETE utasítást végre nem hajtottunk rajta. Az Oracle
a módosítás és törlés idejére automatikusan sorszintü zárat használ, szóval a FOR UPDATE
kifejezés az UPDATE és DELETE utasítások elötti időrezároljaa sorokat.

A FOR UPDATE utasftás

Ha egy kurzort egy CURRENT OF kifejezést tartalmazó utasilásban akarjuk használni, a


kurzort FOR UPDATE-tel kell létrehozni, hogy ne lehessen módosítani a sor tartalmát, amire
éppen hivatkozik. A CURRENT OF kifejezés lehetövé teszi, hogy egy UPDATE vagy
DELETE utasilást hajtsunk végre azon a soron, amin éppen a kurzor áll.
DECLARE
CURSOR cl IS SELECT sx_studentid, sx_examid, sx_grade
FROM student exam FOR UPDATE;
BE GIN
OPEN cl;
LOOP
FETCH cl INTO ...

UPDATE student exam


SET sx grade new_grade WHERE CURRENT OF cl;
END LOOP
A SELECT . .. FOR UPDATE utasítás határozza meg azokat a sorokat, amik ki
lesznek törölve, vagy módosítva lesznek. majd zárolja öket az eredmény halmazban. Ez akkor
hasznos, ha egy módositást akarunk végrehajtani, ami az elözö értékre alapul. Így biztosak
lehetünk benne, hogy az értékek közben nem lettek megváltoztatva más felhasznáJók által. Az
opcionális NOWAIT kifejezés azt adja meg az Oracle-nek, hogy ha az adott sor zárolva van

124
12.Tranzakciók PUSQL-ben lváncsy Renáta

más felhasználők által, akkor ne várakozzon rá, hanem térjen vissza, így más müveleteket el
lehet végezni, mielőtt újra megpróbálnánk a zárolást. Egy lrurzor megnyitásakor minden sor
zárolva lesz, nem csak az, amelyiket éppen kiolvastuk (FETCH). COMM! T vagy ROLLBACK
után a sorokellesznek engedve, így nem lehet egy FOR UPDATE lrurzorra a FETCH utasítást
kiadni COMM! T után.
Az alábbi példában az eljárás segítségével lehet egy lrurzusra jelentkezni. A jelentkezést
jelentő sor beszúrása előtt azonban össze kell számolni, hogy van-e még hely az adott
lrurzuson. Ha a CO URS E tábla co u _l im i t mezőjénél kevesebben vették eddig fel a tárgyat,
akkor az új felvétel érvényes lesz, be lehet szúrni az új sort a STUDENT _ COURSE táblába.
Annak érdekében, hogy amig az egyik felhasználó tárolt eljárása összeszámolja a
jelentkezetteket, mások ne tudjanak felvenni az adott lrurzusra új hallgatót, a COURSE tábla
adott lrurzusra vonatkozó sorát zároljuk a FOR UPDATE utasítással. Feltételezve, hogy
mindenki a tárolt eljárás segítségével próbál jelentkezni egy tárgyra, biztositva van, hogy
amig valaki elkezdte a tranzakciót, más nem fog jelentkezni az adott kurzusra, hiszen a lrurzus
táblából csak akkor tudja más meghatározni a limit értékét, ha a tranzakció elengedte az adott
sort.

create or replace procedure kurzus felvetel(studid in char,


couid in integer) is
student_limit integer;
student_number integer;
integritasi_hiba exception;
PRAGMA EXCEPTION_INIT(integritasi_hiba,-02291);
-- elnevezern az Oracle rendszerhibat, ami akkor jon,
ha nem talal szulo rekordot
begin
select cou limit into student limit from course where
cou id=couid for update;
select count(sc studentid) into student number from
student course where
sc courseid=couid;
if student number<student limit then
insert into student course values (studid, couid,
sysdate);
else

!25
12.Tranzakciók PUSQL-bcn Iváncsy Renáta

raise_application error(-20102, 'A lista


megtelt! ',FALSE);
end if;
commit;
exception
when no data found then
raise_application_error(-20103, 'Ilyen kurzus nem
letezik! ',TRUE);
ha az elso select no data found
exceptiont dob, mert nincs ilyen kurzus

when integritasi_hiba then


rollback;
-- a rollback azert kell, hogy elengedje a zarat
raise_application_error(-20101, 'Ilyen
azonositeju diak nem letezik!',TRUE);
-- ha megprohalja beszurni, de nincs ilyen
diak, akkor ez a helyzet
-- a kurzus nem letezeset mar a
no data found resznel lekezeltuk
when DUP VAL ON INDEX then
rollback;
raise_application_error(-20100, 'Erre a kurzusra
mar jelentkezett! ',TRUE);
ha letezik a diak es a kurzus, de mar
jelentkeztek, akkor
dup val_on index hiba lesz, mert ezek
egyutt unique-k
end kurzus felvetel;
Ha a lekérdezésben több táblát is használunk., a FOR UPDATE utasítással megadhatunk
külön táblákat is zárolásra akkor, ha a FOR UPDATE OF kifejezést használjuk. Egy tábla
sorai csak akkor lesznek zárolva., ha az OF után megadunk egy oszlopot, ami az adott táblához
tartozik. Például a következő példában az emp tábla zárolva lesz, de a dept tábla nem:
DECLARE
CURSOR cl IS SELECT ename, dname FROM emp, dept
WHERE emp.deptno dept.deptno AND job = 'MANAGER'
FOR UPDATE OF sal;

126
12.Tranzakciók PUSQL-beo Iváncsy Renáta

A LOCK TABLE utasftás


Ezt az utasítást akkor használjuk, ha egy egész táblát szeretnénk zároini különböző

zárolási módban, hogy ezáltal megosszuk, vagy megtagadjuk a tábla használatát A row
share mód megengedi a konkurens hozzáférést a táblához és megakadályozza, hogy más
felhasznáJók ex c l us i ve módra zárolják a táblát. Egyszerre több felhasználó is használhatja
a row share módot egy táblán, de csak egy felhasználó adhat ki exclusive zárat egy
táblára. Az exclusive zár segítségével megtilthatjuk a többi felhasználónak, hogy
beszúrjanak. töröljenek, vagy módosítsanak a táblában.

127
13.PUSQL csomagok (packages) )váncsy Renáta

13. PL/SQL csomagok (packages)


A csomag egy séma objektum, ami logikailag összefilggö PUSQL tipusokat, elemeket és
alprogramokat gyűjt egy csoportba. Ha egy csomagot megírtunk és lefordítottunk. az Oracle
adatbázisban kerül eltárolásra így több program is meg tudja osztani a tartalmát
Egy csomag két részből áll, a specifikációból (specification) és a törzsből (body). Bizonyos
esetekben a törzs nem fontos, olyankor az elmarad. A specifikáció a programok felé nyújtott
interfész, ez a tipusok, konstansok, változók, kifejezések, lrurzorok és alprogramok
deklarációját tartalmazza. A törzs a specifikációban deklarált elemek implementációját
tartalmazza. A csomag létrehozásának szintaktikája:
CREATE [OR REPLACE] PACKAGE csomag ___ név
[AUTHID {CURRENT_USER l DEFINER}]
{IS l AS}
[PRAGMA SERIALLY_ REUSABLE;)
[kollekció_ tipus _definició ••• ]
[rekord_tipus_definició ... ]
[altipus_ definíció .• • J
[kollekció_deklaráció ... ]
[konstans _deklaráció .•. ]
[kivétel_deklaráció ... l
[objektum_deklaráció .•• ]
[rekord_ deklaráció ... ]
[változó_ deklaráció . .. ]
[kurzor_specifiáció ..• ]
[függvény_specifikáció .. ]
[eljárás_specifikáció ... ]
END [csomag név);

[CREATE [OR REPLACE] PACKAGE BODY csomag név {IS l AS}


[kollekció_ tipus_definició ... J
[rekord tipus definició ..• ]
[altipus definíció ... ]
[ kollekció_deklaráció ... J
[konstans __ deklaráció ... ]
[kivétel __ deklaráció ... J
[objektum_deklaráció ... J
[rekord deklaráció ... ]
[változó deklaráció ... ]
[kurzor_specifikáció_és_törzs ... )
[függvény specifikáció és_törzs ... }
[eljárás specifikáció és_ törzs ... )
[BEGIN
utasitások_sorozatal
END [csomag_név];)

128
13.PUSQL csomagok (packages) lváncsy Renáta

A csomag specifikációja nyilvános deklarációkat tartalmaz, amiket a programok


láthatnak. Az alprogramokat a specifikáció legvégén kell deklarálni, miután minden más elem
deklarálásra került. A törzs az implementációt tartalmazza és a saját, nem nyilvános
deklarációkat, amik a programok számára láthatatlanok. A törzs deklarációs részét követően

az opcionális inicializáló rész következik, ahol a változók értéket kaphatnak. Az AUT H I D


kifejezés azt mondja meg, hogy a csomag összes alprogramja milyen jogokkal fusson, a
létrehozóéval (DEFINER) vagy a futtatóéval (CURRENT USER). Az alapértelmezett beállilás
szerint a jogok a csomag létrehozójáét öröklik.
A csomagok előnyei:
• Modularitás: a csomagok segítségévellogikailag egybetartozó típusokat, elemeket és
alprogramokat összefoghatunk és névvel ellátott PUSQL modulként tárolhatjuk.
Minden csomag egyszerűen megérthető, a csomagok közti interfészek egyszerűek.

világosak és jól definiáltak. Ez megkönnyíti a programozást.


• Egyszeri programfejlesztés: A programozás során csak a csomag specifikációjának
kell kész lennie. Meg lehet írni, és le lehet fordítani a specifikációt a törzs nélkül is.
Ezek után azokat a tárolt alprogramokat, amik használják a csomagot, szintén le lehet
fordítani. A csomag törzsét nem kell teljesen lekódolni egészen addig, amíg végül
kész nem lesz a program.
• Információ elrejtés: A csomagokban meg lehet határozni, hogy mely elemek
legyenek publikusak, mindenki által láthatóak. vagy sajátok. a többiek elöl elrejtettek.
A csomag az implementációt elrejti a többi program elöl, így valamilyen
implementációs változtatás csak a csomagot érinti.
• B6vftett funkcionalitás: a csomagok változói és kurzorai az egész kapcsolat alatt
fennmaradnak, így ezeket minden alprogram megoszthatja egymás közt, amik a
környezetben futnak . Így lehetőség van információ átadására a tranzakciók között
anélkül, hogy azokat el kéne tárolni az adatbázisban.
• Jobb teljesítmény: Amikor első alkalommal meghívjuk egy csomag alprogramját, az
egész csomag betöltődik a memóriába Ezek után, ha késöbb bármely csomagbeli
alprogram hívása történik, az nem kerül IlO műveletbe. Másrészről azáltal, hogy az
implementáció függetlenítve van az interfésztöl, ezért egy implementáció
módosításnál sokat spórolunk, hiszen nem kell az összes alprogramot újra fordítani,
amik használják a csomagot, elég csak a csomag törzsét.

129
13 .PUSQL csomagok (packages) Iváncsy Renáta

13.1. A specifikáció
A csomag specifikációja nyilvános (public) deklarációkat tartalmaz. Ezeknek a
deklarációknak a láthatósága lokális az adatbázis séma számára, de globális az egész
csomagra nézve. A deklarált elemek elérhetőek a programjainkból és az egész csomagból.
A specifikáció felsorolja azokat az elemeket, amiket a programok használhatnak. A
programnak elég tudnia azokat a dolgokat, amik a specifikációban meg vannak adva. Például
ha adva van egy fiiggvény, annak elég tudni, hogy mi a bemenő paramétere és mivel tér
vissza. Az, hogy a filggvény konkrétan hogyan van megvalósítva, az a programot nem érdekli.
A törzs csak akkor szükséges, ha kurzorokat vagy alprogramokat tartalmaz egy csomag. Ezek
nélkül elég csak a specifikáció. Így olyan globális változókat tudunk definiálni, amik az egész
kapcsolat alatt létemek.
A csomag tartalmára a következő formában lehet hivatkomi:
csomagnev.elemnev
A csomag tartalmára hivatkozhatunk adatbázis triggerekből, tárolt eljárásokból, 3GL
programokból és néhány Oracle kliensbőL Megkötés, hogy távoli csomagra nem lehet
hivatkozni, illetve csomagon belül nem hivatkozhatunk környezeti változókra (host variable).

13.2. A csomag törzse


A csomag törzse a specifikációt implementálja, azaz az összes a specifikációban deklarált
Irurzor és alprogram implementációját tartalmazza. A specifikációban megjelenő alprogram és
kurzor fejrészének (header) szó szerint meg kell egyeznie a törzsben található fejrésszel,
egyébként hibaüzenetet kapunk.
A törzs tartalmazhat saját deklarációkat, amik az implementációhoz szükségesek, de nem
kell, hogy nyilvánosak legyenek. Ezen deklarációk láthatósága lokális a törzsön belül. A
specifikációs résztől eltéröen a törzs deklarációs része tartalmazhat alprogram törzseket. A
csomag törzsében a deklarációs részt az inicializáló rész követi, ami opcionális. Ez általában
olyan utasításokat tartalmaz, amik a deklarációs részben deklarált változókat inicializálnak. A
csomag nem kaphat vagy adhat tovább paramétereket, igy az inicializáló résmek nincs túl
nagy szerepe. A csomag inicializációs része csak egyszer fut le, akkor, amikor először

hivalkozunk a csomagra. A csomagban lehetőség van az alprogram túlterbelésre.


Csomag hasmálata igen előnyös lehet olyan információk tárolásához, amik egy kapcsolat
(session) során végig fennállnak. Az alábbi csomag deklarációban erre láthatunk egy példát.
A feladat, hogy egy adott felhasználó csak akkor tudjon bármilyen tárolt eljárást futtatni az
adatbázisban, ha előtte explicit, egy eljárás futtatásának a segítségével belépett. Ezt tipikusan

130
13.PUSQL csomagok (packages) lváncsy Renáta

olyankor szokták alkalmazni, amikor sok felhasználó jogosultságait akaijuk kezelni, de nem
akarunk minden egyes felhasználónak külön adatbázis felhasználót és sémát létrehozni.
llyenkor egy felhasználót hozunk létre mindenkinek, és egy saját lábiában tároljuk el a
felhasználói neveket és jelszavakat. A csomag ehhez tartalmaz eljárásokat és filggvényeket.
create table jelszavak

userid int primary key,


pwd varchar2(30) not null

-- csomag specifikaeia
create or replace package userlogin is
procedure login (id int, passwd varchar2);
function is logged_in(dobhibat boolean) return boolean;
end userlogin;

-- csomag torzs
create or replace package body userlogin is
loggedin boolean;

procedure login (id int, passwd varchar2) is


jelsza varchar2(30);
hibasjelszo exception;
begin
select pwd into jelsza from jelszavak where userid id;
if (passwd != jelszo) then
loggedin := FALSE;
raise hibasjelszo;
else
loggedin ·= TRUE;
end i f ;
exception
when no_data found OR hibasjelszo then
raise_application_error(-20101, 'Invalid user name or
password! ') ;

131
13.PUSQL csomagok (pack.ages) lváncsy Renáta

end;

function is logged_in(dobhibat boolean) return boolean is


begin
i f dobhibat then
if (loggedin!= true) then
raise_application_error(-20102, 'Not logged in');
end if;
else
return loggedin;
end if;
end;
begin
loggedin := FALSE;
end userlogin;

A tábla létrehozása után létrehozzuk a csomagot. A csomag specifikációjában


speciftkálunk egy belépést megvalósító eljárást (login), és egy ftlggvényt, aminek boolean
visszatérési értékével le tudjuk kérdezni, hogy az adott felhasználó be van-e lépve vagy sem
(is_logged_in). A csomag törzsében megvalósí~uk a specifikációban specifikált eljárást
és ftlggvényt, valamint deklaráljuk a lokális változót, ami a belépés tényét tartalmazza. A
csomag törzsének van egy inicializációs része. Ez pontosan egyszer fut le a kapcsolat alatt. Itt
állí~uk be a lokális változó értékét hamisra. Amennyiben a felhasználó futtatja a login
ftlggvényt, és az sikeres, a lokális változó értéke igaz lesz, egyébként pedig hamis. Az
is _logged _in ftlggvény visszatérési értéke a lokális változó értéke, amennyiben FALSE
értékkel hívtuk meg. Ha igaz érték a ftlggvény bemenete, akkor maga az is _logged _in
függvény hibát dob. Ez azért előnyös, mert így nem kell minden egyes tárolt eljárásban
kezelni azt a problémát, ha a felhasználó nincsen belépve, hiszen már a lekérdezö ftlggvény
hibát generál erre az esetre.
A csomag megírása után minden egyes tárolt eljárást vagy triggert úgy kell kezdeni, hogy
lefuttatja az is _logged_in ftlggvényt, és csak abban az esetben folyatódik, ha az igazzal
tért vissza.

132
13.PUSQL csomagok (packages) Jváncsy Renáta

13.3. PL/SQL elöre definiált csomagok


Az Oracle számos eljárást és függvényt csomagokba foglalt. ezzel is segítve a
programozók munkáját. Az alábbiakban a leggyakrabban hasmált csomagokat tekintjük át.

13.3.1. A ST ANDARD csomag

A STANDARD csomag definiálja a PUSQL környezetet. A csomag specifikációja


globális deklarációkat tartalmaz (tipusok, kivételek, alprogramok), melyek automatikusan
elérhetők a PUSQL programok számára. Dyen függvények például az ABS, SIN stb.
függvények, vagy a NO_DATA_FOUND, TOO_MANY_ROWS stb. kivételek.
A STANDARD csomag tartalma direkt elérhető a programokbó l, nem kell a csomag
nevével hivatkozni rá. Abban az esetben kell a SATNDARD. elj á rásnév módon hivatkozni
a tartalmára, ha saját programunkban az eljárást vagy kivételt felüldefiniáljuk.

13.3.2. A DBMS_OUTPUT csomag

A DBMS_OUTPUT csomag segítségével lehetőség van PUSQL alprogramokból vagy


triggerekböl adatok megjelenítésére. Ennek segítségével könnyebben lehet tesztelni és
debuggolni a programokat. A PUT és a PUT_LINE eljárások információt tesznek egy
bufferbe, amit egy másik eljárás, trigger vagy csomag olvashat. Az információt a GET_ LINE
és a GET_LINES eljárásokkallehet kivenni.
GET_LINE(line, status);
A status érétke O, ha volt üzenet a bufferben, amennyiben nincs több sor, az értéke l.
A SQL*PLUS környezetben vagy a PUSQL Developer Command Window-jában a
kimenetet akkor jeleniti meg, ha a következő utasítást kiadtuic
SET SERVEROOTPUT ON;

13.3.3. A DBMS_PIPE csomag

A DBMS_PIPE csomag lehetőséget ad arra, hogy k:ülönbözö kapcsolatok (session) névvel


ellátott pipe-okon keresztül kommunikáljanak egymással. A pipe egy memória terület. amin
keresztül az egyik folyamat információt adhat át egy másiknak.
A pipe a pack_message eljárással tesz be adatot a pipe-ba, a send_message függvénnyel
küldi át egy másik folyamatnak. A fogadó folyamat a receive_message fiiggvénnyel kapja
meg az üzenetet. és az unpack_message eljárással olvassa ki az adatokat. Kétfajta pipe létezik,
a nyilvános és a nem nyilvános pipe.

133
13.PUSQL csomagok (paclr.ages) Iváncsy Renáta

A nyilvános pipe
A nyilvános pipe implicit vagy explicit létrehozható. Az implicit létrehozás azt jelenti,
hogy automatikusan létrejön, ha hivalkozunk rá, és megszüník, ha nem tartalmaz adatokat. Az
explicit pipe a CREATE_PIPE filggvénnyel hozható létre.
CREATE_ PIPE(
Pipename VARCHAR2,
Maxpipes i ze INT DEFAULT 8192,
Private BOOLEAN DEFAULT TRUE) RETURN INT;
A pipename paraméter lesz a pipe neve. Ennek segítségévellehet hivatkozni a pipe-ra,
ennek segítségével lehet üzenetet küldeni és fogadni. A névnek egyedinek kell lennie az
Oracle példányon belül. A maxpipesize határozza meg az üzenet maximális méretét. A
p r i v a t e paraméter azt határozza meg, hogy nyilvános pi pe lesz-e (ba értéke FALSE) vagy
nem nyilvános (ez az alapértelmezett). A visszatérési érték O, ha a sikeres a pipe létrehozása,
vagy már létezik. és a felhasználó használhatja. Egyébként az ORA-23322 hiba generálódik.
Az explicit létrehozott pipe-t megszűntetni a REMOVE_PIPE fiiggvénnyellehet:
REMOVE_PIPE(pipename VARCHAR2) RETURN INT;
A pipe akkor is megszűnik, ha a példányt lekapcsolják.
Minden nyilvános pipe aszinkron módon müködik. Azok írhatnak egy pipe-ba, akiknek
futtatási joguk van a DBMS_PIPE csomagra, és ismerik a pi pe nevét. Amennyiben egy adatot
kiolvastak a pipe-ból, akkor az eltünik onnan.
A küldö a PACK_MESSAGE eljárással a lokális üzenet butferébe teszi az adatokat. Ezt
egymás után többször is meghívhatja, az üzenetek a lokális butferben gyűlnek. Elküldeni a
pipe-ba a SEND_MESSAGE filggvénnyel lehet. A PACK_MESSAGE háromszorosan
túlterhelt eljárás, bemenete lehet VARCHAR2, NUMBER és DA TE tipusú. Az üzenetre
plussz 4 byte overbead kerül, l byte a típus jelzésére, 2 byte a hossz jelzésére és l byte az
üzenet vége jelzésére. A SEND _ MESSAGE filggvény szintaktikája:
SEND MESSAGE(
Pipename VARCHAR2,
Timeout INT DEFAULT MAXWAIT,
Maxpipesize INT DEFAULT 8192) RETURN INT;
A pipename paraméter a pipe neve, a timeout másodpercben értelmezve azt adja meg,
hogy sikertelen üzenetküldéskor mennyit váJj on. Az alapértelmezett érték l OOO másodperc. A
filggvény visszatérési értéke O, ha siker volt, l, ha timeout volt, vagy nem tudott zárat rakni,
és ORA-23322 máskor.
Üzenetet megkapni a RECEIVE_MESSAGE filggvénnyel lehet. Az üzenetet a lokális
bufferbe teszi, és eltávolítja azt a pipe-ból. Ha a pipe nem létezett, az Oracle implicit
létrehozza, és egy üzenetre vár.

134
13.PUSQL csomagok (packages) Iváncsy Renáta

RECEIVE_MESSAGE(
Pipename VARCHAR2,
Timeout INT DEFAULT MAXWAIT) RETURN INT;
A lokális butferből az UNPACK_MESSAGE eljárással lehet kivenni az üzenetet Ez
szintén háromszorosan túlterbelt eljárás, kimenő paramétereinek tipusa lehet VARCHAR2,
NUMBER vagy DATE.
Nem nyilvános pipe
A nem nyilvános pipe-t a CREATE_PIPE függvénnyellehet létrehozni. A hozzáféréséhez
az alábbi korlátozások vannak:
• Azok a folyamatok férbetnek hozzá, amik azonos felhasználói név alatt futnak,
mint a pipe létrehozója.
• Azok a tárolt alprogramok férhetnek hozzá, amik olyan felhasználói jogok
tartományában futnak, mint a pipe létrehozója.
• A SYSDBA felhasználők használhatják.
Amennyiben mások próbálnak hozzáférni a nem nyilvános pipe-hoz, hiba generálódik.

13.3.4. A DBMS_LOB csomag


A DBMS_LOB csomag a nagy objektumok kezelését támogató csomag. Olvassa és
módosítja a BLOB, CLOB és NCLOB adatokat, és csak olvasható müveletet biztosít a BFILE
adatokra
A LOB-oknak két nagy csoportja van: a belsö és a külsö LOB. A belső LOB-okat
(BLOB, CLOB, NCLOB) az adatbázison belül, külsö LOB-okat (BFILE) az adatbázison
kivül táro lj uk. Mind a két esetben csak egy un. LOB lokátort tárolunk el az adatbázisban, ez a
lokátor mutatja meg, hogy ténylegesen hol van az adat. Az adatbázis táblákban csak ez a
lokátor kerül eltárolásra.
Az alábbi példában egy táblát bozunk létre, ami különbözö nagy tipusú objektumok
tárolására is képes lesz:
CREATE TABLE haz

haz_id INT PRIMARY KEY,


haz_cim VARCHAR2(50),
haz_kep BLOB EMPTY_BLOB(),
haz hirdetesCLOB EMPTY_CLOB(),
haz_tervrajz BFILE

135
\3 .PUSQL csomagok (packages) lváncsy Renáta

Mivel az UPDATE és az INSERT utasíts előtt a LOB oszlop értéke nem lehet NULL, így
már a tábla létrehozásakor használjuk az inicializáló filggvényt, ami egy üres LOB lokátort
tesz be az adott oszlopba. A három használható filggvény az EMPTY _ BLOB (), az
EMPTY CLOB és az EMPTY NCLOB.
A LOB típusú adatok kezeléséhez először ki kell választani egy LOB lokátort:
DECLARE
Kep BLOB;
BEGIN
SELECT haz kep INTO kep FROM haz WHERE haz id l;
END;
Másolni WB értéket az alábbi módon tudunk:
INSERT INTO haz (haz_id, haz _ kep) (SELECT haz id + l, haz_kep
FROM haz WHERE haz id= 20);
Ebben az esetben a LOB lokátor és a LOB értéke is átmásolásra kerül. Az UPDATE
hasonlóan müködik.
A BFILE típusú LOB adatot a következő módon lehet beszúrni:
CREATE OR REPLACE DIRECTORY tempdir AS '\oracle\rdbms'
GRANT READ ON DIRECTORY tempdir TO valaki

INSERT INTO haz (haz_id, haz _ tervrajz) VALUES


(123, BFILENAME ( 'TEMPDIR', 'raj z .bmp');
Első lépésként létrehozunk egy könyvtár objektumot, és jogot adunk a valaki nevü
felhasználónak a könyvtár olvasására. A könyvtárnak az operációs rendszerben már léteznie
kell. Ezek után be tudjuk szúrni a fájlt a táblába a BFILENAME (könyvtár, fájlnév)
használatávaL

13.3.5. Az UTL_FILE csomag

Az UTL_FILE csomag filggvényei segitségével az operációs rendszer szöveges fájljait


lehet olvasni és irni. Az FOPEN filggvény megnyit egy fájlt. A függvény specifikációja a
következő:

FOPEN (
Location VARCHAR2,
Filename VARCHAR2,
Open_mode VARCHAR2) RETURN UTL_ FILE . FILE_ TPE

136
13.PUSQL csomagok (packages) lváncsy Renáta

A location adja meg a fájl elhelyezkedését a könyvtár rendszerben. A filename


adja meg a fájl nevét. Az open_mode azt határozza meg, hogy milyen módban kerüljön
megnyitásra a fájl, r esetén olvasásra, w esetén írásra, a esetén hozzáfüzésre. A fájl
visszatérési értéke egy fájlkezelö. A fájlkezelő típusát az UTL_FILE csomag deklarálja a
specifikációs részben.
A fájlba írni a PUT_LINE eljárással lehet. mig olvasni belöle a GET_LINE eljárássaL
PUT __ LINE (
File FILE_TYPE,
Butfer VARCHAR2)

GET _LINE (
File FILE_TYPE,
Suffer OUT VARCHAR2)
A fájlt bezárni az FCLOSE utasítással lehet:
FCLOSE(file FILE_TYPE)

13.3.6. A DBMS_ALERT csomag

Ennek a csomagnak a segítségével adatbázis triggereket használhatunk fel arra, hogy


figyelmeztesse a programunkat. ha valamilyen adatbázis érték megváltozott. A
figyelmeztetések (alert) tranzakció alapúak és aszinkronok.

137
14.A PUSQL objektum tipusok Iváncsy Renáta

14. A PUSQL objektum típusok


Az objektum orientált programozás igen kedvelt módja lett a programozásnak, hiszen
általa időt és fáradságot takaríthatunk meg a komplexebb programok készítésekor. A
PUSQL-ben az objektum orientált programozás az objektum tipusra épül.
Jelenleg PUSQL programból nem lehet objektum tipusokat definiálni. Az objektum
típusokat az Oracle adatbázisban kell létrehozni és tárolni, ahol több program megoszthatja
egymás közt öket. A programot, ami objektummal dolgozik, kliens programnak hívják.
Deklarálhatja és kezelheti az objektumot anélkül, hogy tudná. hogy az objektum típusok
hogyan reprezentálják az adatokat, és hogyan implementálják a müveleteket. Így lehetőség
van arra, hogy elkülönítve újunk programokat és objektum tipusokat, illetve úgy meg lehet
változtatni egy objektum i.mplementációját, hogy az nem érinti a programot. Az objektumok
mind a procedurális-, mind az adat ahsztrakciót támogatják.

Az objektum típus

Az objektum típus egy felhasználó által definiált összeten adattipus, ami magában
foglalja az adatstruktúrát és az adatok kezeléséhez szükséges filggvényeket és eljárásokat. A
változókat, amik az adatstruktúrát alkotják. attribútumoknak nevezzük. A ftlggvényeket és
eljárásokat, amik meghatározzák az objektum viselkedését, metódusoknak nevezzük. Egy
objektum tehát attribútumokból és metódusokból áll. Egy objektum általában a valós világ
egy részének egy absztrakciója. Ha például veszünk egy k:utyát leíró objektumot, akkor ennek
az attribútumai a következök lehetnek: név, fajta, kor, míg a metódusai: eszik, iszik, gazdát
cserél és beoltják. Természetesen egy k:utyával nagyon sok minden egyéb is történhet, az
objektumunk csak azokat az attribútumokat és metódusokat tartalmazza, ami az adon feladat
elvégzéséhez feltétlen szükséges.
Futás időben, amikor az adatstruktúrákat értékekkel töltjük fel, az absztrakt objektum egy
példányát (instance) hozzuk létre. Annyi példányt lehet létrehozni, amennyire szükségünk
van.

!38
14.A PUSQL objektum tipusok lváncsy Renáta

14.1. Az objektum tipus struktúrája

Az objektum tipusnak, hasonlóan a csomagokhoz, két része van: a specifikáció és a törzs.


A specifikáció az interface az objektum és a programok között. Az adatstruktúrát deklarálja és
a metódusokat. A törzs definiálja a metódusokat, azaz implementálja a specifikációt.
Minden információ, amire egy kliens programnak szüksége van, megtalálható a
specifikációban. A specifikációban az attribútumokat a metódusok előtt kell deklarálni. Csak
a metódusoknak van implementációja, ezért ha egy objektum csak attribútumokat tartalmaz,
akkor a törzs része el is maradhat. Az objektum specifikációs részében szereplö attribútumok
nyilvánosak (public). Az alábbi példában megnézhetünk egy objektumot, ami egy komplex
számot ad meg. Egy komplex szám két részből áll a valós (real) és a képzetes
(imaginare) részbőL Az objektumnak ez a két attribútuma van. Emellett találhatóak még a
komplex számok kezeléséhez szükséges metódusok, mint például az összeadás (p l us),
kivonás (le ss) stb.
CREATE TYPE Complex AS OBJECT
rpart REAL, -- attribute
ipart REAL,
MEMBER FUNCTION plus (x Complex) RETURN Complex, -- method
ME MB ER FUNCTION l ess (x Complex) RETURN Complex,
ME MB ER FUNCTION times (x Complex) RETURN Complex,
ME MB ER FUNCTION divby (x Complex) RETURN Complex
) ;

CREATE TYPE BODY Complex AS


MEMBER FUNCTION plus (x Complex) RETURN Complex IS
BEGIN
RETURN Complex(rpart + x.rpart, ipart+ x.ipart);
END plus;

MEMBER FUNCTION less (x Complex) RETURN Complex IS


BEGIN
RETURN Complex(rpart- x.rpart, ipart- x.ipart);
END less;

MEMBER FUNCTION times (x Complex) RETURN Complex IS

139
14.A PUSQL objektum típusok lváncsy Renáta

BE GIN
RETURN Complex(rpart * x.rpart - ipart * x.ipart,
rpart * x.ipart +ipart* x.rpart);
END times;

MEMBER FUNCTION divby (x Complex) RETURN Complex IS


z REAL .- x.rpart**2 + x.ipart**2;
BE GIN
RETURN Complex((rpart * x.rpart +ipart* x.ipart) l z,
(ipart* x.rpart- rpart * x.ipart) l z);
END divby;
END;

14.2. Az objektum tipus komponensei


Egy objektumnak attribútumai és metódusai vannak. Az objektum specifikációjában
deklarálhatunk attribútumokat és metódusokat, de konstansokat. kivételeket, kurzorokat és
tipusokat nem. Egy objektumnak minimum l attribútuma kell, hogy legyen, maximum l OOO
lehet. Metódust nem kötelező megadni.

14.2.1. Attribútumok

Az attribútumok., hasonlóan a változókhoz, nevükkel és típusukkal vannak deklarálva.


Egy tipuson belül a névnek egyedinek kell lennie, de előfordulhat. hogy két azonos nevü
attribútuma van egy objektumnak feltéve, hogy különbözö típusúak. Az attribútumok típusa
bármilyen Oracle tipus lehet, kivéve a következöket
• LONG és LONG RAW
• NCHAR,NCLOB,éSNVARCHAR2
• ROWI Dés UROWI D
• PUSQL-specifilrus tipusok BINARY INTEGER (és ezek altípusai), BOOLEAN,
PLS_INTEGER, RECORD, REF CURSOR, %TYPE és %ROWTYPE
• PUSQL csomagban definiált típusok
Egy attribútumot nem lehet inicializálni a deklarációs részben, így nem kaphat
DEFAULT értéket és nem köthetjük ki rá, hogy nem veheti fel a NULL értéket.

!40
14.A PUSQL objektum tipusok lváncsy Renáta

14.2.2. Metódusok

A metódus egy ftlggvény vagy eljárás, amit az objektum típusban deklarálnak a MEMBER
vagy STATIC kulcsszó hasmáJatávaL Egy metódusnak nem lehet azonos a neve, mint az
objektum tipusnak, vagy bármely attribútumának.
A MEMBER metódusok példányra hivatkomak:

l instance_expression.method()
A STATIC metódusok objektumra hivatkoznak, nem annak pédányára:
object_type_name.method()
A metódusok két részböJ állnak a specifikációból és a törzsből. A specifikáció a metódus
nevét és az opcionális paraméter listáját tartalmazza, ftlggvények esetén pedig még a
visszatérési értéket. A törzsben található a kód, ami elvégzi a metódus feladatát. Minden
metódusnak, ami szerepel a specifikációs részben, meg kell lennie a megvalósilásnak a
törzsben, vagy pedig NOT INSTANTIABLE-ként kell deklarálni, ami megadja, hogy ez a
metódus csak ennek a típusnak az altípusaiban van jelen. A formális paraméterek nevükkel és
típusukkal vannak megadva, azzal a kikötéssel, hogy egy típusra nem lehetnek méret
megszorítások. Az adattípus bármilyen Oracle adattípus lehet, kivéve azokat, amiket az
attribútumoknál is felsoroltunk.
Oracle-ban objektumokat létre lehet homi PUSQL nyelven, Javaban és C-ben. A
metódusok lehetnek túlterheltek is.

14.2.3. Konstruktor metódus

Minden objektumnak van egy konstruktora, ami egy rendszer által definiált metódus. A
konstruktor metódus neve megegyezik az objektum típus nevével. A konstruktort az objektum
típus inicializálására és példányosítására használjuk. Az Oracle automatikusan elkészíti
minden objektum típusnak a konstruktorát. A konstruktor formális paraméterei az objektum
típus attribútumai. Az attribútumok és a formális paraméterek azonos sorrendben, azonos
névvel és azonos típussal szerepelnek. A PUSQL soha nem hívja meg implicit a
konstruktorokat, azt mindig nekünk kell explicit meghívni. A komplex példára a konstruktor:
DECLARE
K complex;
C complex;
D complex;
BEGIN
K := complex(5,2); - - a k objektum letrehozasa

141
14.A PUSQL objektum típWIOk Iváncsy Renáta

C:= complex(6,3); - a c objektum letrehozasa


D:= k . plus(c); --a d ak es a c osszege
DBMS _OUTPUT.PUT LINE(d.rpart ll + ll d.ipart ll 'I');
- az eredmeny kiiratasa a kimenetre
END;

14.2.4. Objektum tipus definiálása

Objektum tipust az alábbi szintaktikávallehet definiálni:


CREATE [OR REPLACE] TYPE típus név
[AUTHID {CURRENT USER l DEFINER}]
{ {IS l AS} OBJECT l UNDER supertype name

attribútum_név adattipus[, attribútum_név adattipus] ...


[{MAP l ORDER} MEMBER függvény_ specifikáció,)
[{FINAL! NOT FINAL} MEMBER fűggvény_ specifikáció,]
[{INSTANTIABLEI NOT INSTANTIABLE} MEMBER függvény spec,]
[ {MEMBER l STATIC} {subprogram__ spec l call_spec}
[, {MEMBER l STATIC} {subprog ram_spec l call_ spec} l ... l
[{FINAL! NOT FINAL}] [ {INSTANTIABLEI NOT INSTANTIABLE}];

[CREATE [OR REPLACE] TYPE BODY tipus_név {IS l AS}


{ {MAP l ORDER} MEMBER fűggvény_törzs;
l {MEMBER l STATIC} {alprogram __ törzs l call __spec};}
[{MEMBER l STATIC} {alprogram törzs l call _spec};) ...
END; l

14.2.5. Objektum tipus módosftása

Az ALTER TYPE utasítással új attribútumot lehet adni egy objektum tlpushoz, egy létező

attribútumot lehet módosítani vagy törölni. Ezzel az utasítássallehet egy új metódust felvenni,
vagy egy létezőt törölni.
CREATE TYPE Person_typ AS OBJECT
( name CHAR (20),
ssn CHAR(l2),
address VARCHAR2(100));
CREATE TYPE Person nt IS TABLE OF Person_typ;
CREATE TYPE dept_typ AS OBJECT
( mgr Person_typ,
emps Person_ nt);
CREATE TABLE dept OF dept_typ;

-- Add new attributes to Person typ and propagate the change

142
14.A PUSQL objektum típusok Iváncsy Renáta

-- to Person_nt and dept_typ


ALTER TYPE Person typ ADD ATTRIBUTE (picture BLOB, dob DATE)
CASCADE NOT INCLUDING TABLE DATA;

CREATE TYPE mytype AS OBJECT (attrl NUMBER, attr2 NUMBER);


ALTER TYPE mytype ADD ATTRIBUTE (attr3 NUMBER),
DROP ATTRIBUTE attr2,
ADD ATTRIBUTE attr4 NUMBER CASCADE;
Ha egy eljárás le lett fordítva. minidig az objektum tipus aktuális verzióját használja. A
már létező eljárások a szerveren, ami egy olyan objektum típusra hivatkoznak, ami meg lett
változtatva. a legközelebbi híváskor újra fordítódnak. A kliens oldali eljárásokat a
programozónak kell újra fordítania. ha olyan objektum típusra hivatkozik, ami meg lett
változtatva. Ha egy olyan típusnak töröljük egy metódusát, aminek vannak altípusai, akkor
lehet, hogy változásokat kell végezni az altípuson, ha az felülírta ezt a metódust.

14.2.6. Öröklés

Lehetőség van öröklés megadására az objektum típusok között. Egy objektum típus
altípusaként definiálhatunk egy típust, ami örökli a szülö összes attribútumát és metódusát, de
ezen kívül még újabb attribútumokkal és metódusokkal rendelkezhet. Lehetőség van arra is,
hogy a szülö metódusát felülúja a gyerek metódus.

14.2.7. Objektumok deklarálása és inicializálása

Egy objektum típus specifikációja:


CREATE TYPE Rational AS OBJECT (
num INTEGER,
den INTEGER,
MAP MEMBER FUNCTION convert RETURN REAL,
MEMBER PROCEDURE normalize,
MEMBER FUNCTION reciprocal RETURN Rational,
MEMBER FUNCTION plus (x Rational) RETURN Rational,
MEMBER FUNCTION less (x Rational) RETURN Rational,
MEMBER FUNCTION times (x Rational) RETURN Rational,
MEMBER FUNCTION divby (x Rational) RETURN Rational,
PRAGMA RESTRICT REFERENCES (DEFAULT, RNDS,WNDS,RNPS,WNPS)
)i

143
14.A PUSQL objektum típusok Iváncsy Renáta

Ha létrehoztunk egy objektum típust, utána a PUSQL blokkból úgy deklaráhatjuk. mint
bármely más beépített típust. Az alábbi példában deklarálunk egy Ra tional objektum
típusú változót, majd meghívjuk rá a konsttuktort. A konsttuktorban a két szám a racionális
szám számlálója és nevezője.
DECLARE
r Rational;
BEGIN
r := Rational(6, 8);
dbms output.put line(r.num); -- prints 6
Az r értéke deklaráláskor NULL, a konsttuktor meghivása után kap inicializált érétket.
Egy NULL objektum sosem lesz egyenlő egy másik objektummal, ha tehát összehasonlítanánk
öket, az eredmény NULL lenne.
Az attribútumokra a nevük alapján hivatkozhatunk, ahogy azt a fentebbi példában is
láttuk. a képemyöre csak a számlálót írattuk ki az r. num hivatkozással. Az attribútum
hivatkozásokat láncolni is lehet. Ha például egy objektumnak egy attribútuma rekord tipusú,
akkor a rekord egy mezöjére a következő szintaktikával hivatkozhatunk:
példánynév.attribútumnév.mez6név.
Metódusokat is a pont hivatkozással hivhatunk meg: egyednev. metodus formában.

144
15.PUSQL dinamikus SQL Iváncsy Renáta

15. PL/SQL dinamikus SQL


Az eddig tárgyalt esetekben, a blokkokban és alprogramokban használt SQL utasítások
statikusak volta](. Már a program megirásakor pontosan tudtuk. hogy hogyan fog kinézni az
SQL utasítás, amit használni akarunk. Előfordul azonban, hogy a program futása során derül
ki, hogy milyen SQL utasítást kell hasmálni. Oyenkor igen jó szalgálatot tesz a dinamikus
SQL használatának lehetősége. Dinamikus SQL használatára tipikus példa, amikor a
felhasználó állithatja össze a nézetének oszlopait vagy akár tábláit. így futási időben más- és
más SELECT utasítást kell végrehajtani a megfelelő eredmény érdekében. A dinamikus SQL
utasítások sztringekben tárolt SQL utasítások, amely sztringet futási időben rak össze a
program. Ezt a sztringet van lehetőségünk futtatni a megfelelő helyen. A legtöbb SQL utasítás
futtatására az EXECUTE IMMEDIATE utasítás szolgál. A több sorral visszatérő SQL
utasításokat azonban az OPEN-FOR, FETCH és a CLOSE utasítások használatával
futtathatjuk. Az Oracle az EXECUTE IMMEDIATE utasításan kívül a DBMS_SQL előre

definiált csomaggal támogatja a dinamikus SQL kezelését.


A dinamikus SQL használatának előnyei:
• Rugalmasabb alkalmazások. hiszen futási időben lehet összerakni különböző

feltételeknek megfelelő lekérdezéseket


• Lehetőséget ad DDL és DCL utasítások futtatására tárolt eljárásokban.
• Lehetőség van a WHERE feltételt dinamikusan összerakni.
A dinamikus SQL használatának hátrányai:
Mivel a dinamikus SQL esetén az utasítás futási időben alakul ki, a hátrányok ebből

adódnak:
• Az utasítások nincsenek elöoptimalizálva
• A végrehajtási terv a futtatáskor alakul ki
• Csak futtatáskor van szintaktikai és jogosultság ellenőrzés
Az EXECUTE IMMEDIATE utasítás szintaktikája:
EXECUTE IMMEDIATE dinamikus sztring
[INTO valtozol, valtozo2,_]
[USING [INIOUTIIN OUT] kotesl,
[IN l OUT l IN OUT] kotes2, ...
[{RETURNING l RETURN} INTO kotesl,kotes2]
A dinamikus sztring tartalmazza a lefuttatandó SQL utasítást. Az opcionális INTO
kulcsszó utáni változókba kerülnek be az adatok, ba az SQL utasítás visszatér valamilyen
egysoros eredménnyel. Az opcionális USING kulcsszó után bemenő paramétereket lehet

145
15.PUSQL dinamikus SQL lváncsy Renáta

megadni, amiket a lekérdezésen belül ott lehet hasmálni, ahol kifejezést lehet hasmálni. A
kimenő paraméterek visszatérési értékeket kaphatnak.
A dinamikus sztring bármilyen SQL utasítást tartalmazhat, ami után nem kell a
pontosvesszőt kitenni. Amennyiben azonban PUSQL blokkot tartalmaz, a pontosvesszöket ki
kell tenni.
Az alábbi példában egy tárolt eljárás segítségével adjuk fel az anyagra a rendelést a
cukrász adatbázisban. Amennyiben még nem létezik a rendelés tábla, azt is létrehozzuk. Ezt a
Data Dictionary us e r_ tables nevü táblájából kérdezhetjük Ie. Ezek után beszWjuk a
kivánt értékeket hasmálva a dinamikus SQL-t paraméterkötésseL A paraméterek neve
irreleváns a dinamikus SQL utasításban, csak a sorrendjük számí t.
CREATE PROCEDURE rendeles sp (anyagid INT, mennyiseg FLOAT)
AS
Tabladb INT;
Sqlstm VARCHAR2(500);
BEGIN
SELECT COUNT(*) INTO tabladb FROM user_tables
WHERE UPPER(table_name) = 'RENDELES';
IF tabladb = 0 THEN
EXECUTE IMMEDIATE ' CREATE TABLE rendeles

rendeles id INT PRIMARY KEY,


rendeles_datum DATE,
rendeles_anyagid INT NOT NULL,
rendeles_mennyiseg FLOAT,
rendeles rendezve DATE
) ,;
END IF;
Sqlstm := 'INSERT INTO rendeles VALUES (rend_seq.NEXTVAL,
Sysdate, :1, :2, NULL)';
EXECUTE IMMEDIATE sqlstm USING anyagid, mennyiseg;
END;

146
IS.PUSQL dinamikus SQL lváncsy Renáta

A következő példában egy dinamikusan összeállított DELETE utasítást valósítunk meg:


CREATE PROCEDURE delete rows
(table_name VARCHAR2, condition VARCHAR2 DEFAULT NULL)
AS
Where cond VARCHAR2(100) := 'WHERE ' l l condition;
BEGIN
IF condition IS NULL THEN
Where cond .- NULL;
END IF;
EXECUTE IMMEDIATE 'DELETE FROM ' l l table name l l
where_cond;
END;
Ebben az eljárásban a tábla nevét nem adhatjuk át paraméterként a lekérdezésbe, mert a
tábla neve helyén a statikus SQL-ben sem szerepelhet kifejezés.

147
16.A Transact-SQL alapjai Iváncsy Renáta

16. A Transact-SQL alapjai


Az SOL (Structured Query Language) a relációs adatbázisokban tárolt adatok elérésére
szolgáló, az ANSI által szabványoshon nyelv. Tartalmaz mind adatdefiniciós (data definition
language - DDL), mind adatmanipulációs (data manipulation language- DML) utasításokat.
Az SOL nyelv nagy előnye, hogy szabványos, hátránya azonban, hogy nem elégít ki minden
programozói igényt. Ennek megfelelöen a legtöbb, az adatbázis kezeléssei foglalkozó cég az
SOL szabványt kibövítve kialakította a saját egyéni adatbázis-kezelő nyelvét. Dyen nyelv a
Sybase majd a Microsoft SOL Serveresetén a Transact-SOL (rövidítése a T-SOL), az Oracle
esetén, pedig a PUSOL.
A Transact-SOL nyelvnek központi szerepe van a Microsoft SOL Server (továbbiakban
SOL Server) müködésében, minden alkalmazás, ami az SOL Serverrel kommunikál, Transact-
SOL (T-SOL) utasításokat küld a szerver felé. A T-SOL segítségével kibővültek a szabványos
SOL utasítások. Példa erre a tábla módosítására szolgáló ALTER T ABLE utasítás, ami a
szabványban csak az oszlop típusának a módosítását illetve új oszlop hozzáadását
engedélyezi, mig a T -SOL-ben a tábla bármilyen tulajdonságát lehetőségünk van
megváltoztatni. A T-SOL azon túl, hogy az utasításokat kibővítette, új utasításokat és
lehetöségeket hozott a nyelvbe. Segítségével lehetőség van változók definiálására, feltételes
utasítások, ciklusok irására valamint tárolt eljárások, triggerek, filggvények, indexek
készítésére.
A T-SOL-ben, ellentétben a PUSOL-Iel nem szükséges az egyes sorokat pontosvesszövei
lezárni.

16.1. Kommentek
A Transact-SOL kétfajta megjegyzést támogat. A dupla minusz, (--) jellel egysoros
megjegyzést tehetünk, míg a , .. l jelek között több sorban is elhelyezhetünk megjegyzést,
amelyek akár egymásba ágyazhatóak.

16.2. Azonosftók
Az SOL szerveren minden adatbázis objektum kaphat azonosítót, mínt például az
adatbázisok, táblák, tárolt eljárások, indexek, oszlopok, megkötések és így tovább. A legtöbb
esetben kötelező azonosítóval ellátni az objektumot, de vannak olyan objektumok, amelyek
esetében az azonosító megadása opcionális (ilyenek pl. a megkötések). Az objektum
azonosítója akkor kerül létrehozásra, amikor az objektumot definiáltuk. Ezek után az

!48
16.A Transact-SQL alapjai lváncsy Renáta

objektumra az azonosítójával hivatkozhatunk. Az azonosítóknak két osztálya létezile a


szabályos azonosilók és az elválasztó karakterrel határolt azonosítók (delimited).
A szabályos azonosítókra különböző megkötések vannak, amelyek a következők :
• Az els6 karakternek az Unicode Standard 2.0 által definiált betűnek (a.. z, A .. Z),
aláhúzásnak U. (@) vagy kettős keresztnek (#) kell lennie. A különbözö azonosító
kezdetek különbözö jelentéssei bírnak.
Jel az azonositó elején Jelentés
@ Lokális változó vagy paraméter
@@ Rendszer változók
# Átmeneti tábla vagy eljárás
1#1 Globális átmeneti objektum
• Az azonosítók további karakterei vagy betük, számok, kukac (@), aláhúzás U és
doJiárjel ($) lehetnek.
• Egy azonosító nem lehet semmilyen a Transact-SQL által foglalt szó (ezeknek a
szavaknak mind a k.isbetűs, mind a nagybetűs verziója foglalt).
• Az azonosítón belül nem lehet szóköz vagy egyéb, fent fel nem sorolt speciális
karakter.
Az elválasztó karakterrel eJiátott azonosítókat [] jelek vagy " "jelek között keJI megadni.
Ebben az esetben az azonosítónak nem keJI megfelelnie a szabályos azonositóknál leírt
szabályoknak.

16.3. Konstansok
A konstans (más néven literál) egy szimbólum, ami megadott értéket reprezentál. A
konstans formátuma fiigg az általa reprezentált értéktőL

Karakter sorozat (sztring) konstans


A karakter sorozat konstansok egyszeres aposztrófok között található alfanumerikus
karakterek és számok lehetnek, valamint a felkiáltójel(!), a kukac (@),és a kettős kereszt(#).
Példálc sztring Iconstans ra: 'Budapest', 'Hello World!'
Bináris konstans (Hexadecimális konstans)
A bináris konstans a Ox-szel kezdődik, és hexadecimális számokat tartalmaz. A számok
nincsenek aposztrófok között.
Példa bináris konstansra: OxA3F
Bit konstans
A bit konstans a O vagy az l számmal van reprezentálva, és nincsen aposztrófok között.
Ha l-nél nagyobb számot használunk, akkor az l-re lesz konvertál va.

149
16.A Transact-SQL alapjai Iváncsy Renáta

Dátum konstans
A dátum kanstansok megadott formátumú, aposztrófok közötti kifejezések.
Például: '021ll 12002 ', vagy '15 April, 2002 'stb.
Integer konstans
Az integer konstans számok, amik nincsenek aposztrófok között, valamint nem
tartalmaznak tizedes pontot.
Például: 23, 45 stb.
Decimális konstans
A decimális konstans számok sorozata, ami tartalmazhat tizedespontot is.
Például: 1234.56, 0.23 stb.
Float és real konstans
A float és real konstans megadott formátumúak lehetnek.
Példálc real és float lconstansolcra: 123.5E5, 0. 5E-2 stb.

16.4. Lokális változók


(A globális változó a rendszer által támogatott, elöre definiált változó, ami @@-al
kezdődik.)

A Transact-SQL-ben a változók olyan objektumok. melyek meghatározott értékeket


tartalmazhatnak. A változók deklarálását a DECLARE kulcsszóval kell kezdeni, majd
megadni a változó nevét. A változó nevének mindenképp a @ karakterrel kell kezdödnie. A
név megadása után meg kell határozni, hogy a változó m.ilyen tipusú és m.ilyen hosszú legyen.
Több változó deklarálása esetén az egyes változó deklarálásokat vesszövei kell elválasztani.
DECLARE @v ál tozónévl típus l, @v ál toz6név2 tipus 2, ...
Az alábbi példában három változót deklaráltam egy integer, egy 20 hosszú
karaktersorozat és egy numeric típusút.
DECLARE @szamlalo INT, @nev varchar(20), @ertek numeric(3,2)

16.4.1. Változók hatásköre

A változó hatásköre a Transact-SQL utasftások halmaza, amelyek hivatkozhatnak egy


változóra. Egy változó hatásköre a definiálástól számítva a batch vagy a tárolt eljárás végéig
tart.

ISO
16.A Transact-SQL alapjai Iváncsy Renáta

16.5. Értékadás változónak


A változó deklarálásakor az értéke NULL lesz. A változónak a SET utasítás segítségével
adhatunk értéket, vagy a SELECT utasitásoD keresztül. Egy változónak nem tudunk
alapértelmezett értéket adni.
Változó értékadásának szintaktikája a SET utasítással:
SET @változ6=érték
Változó értékadásának szintaktikája a SELECT utasitáson belül:
SELECT @változól=oszlopl, @változ62=oszlop2,._ FROM tábla WHERE

Abban az esetben, ha a változónak a SELECT utasításon keresztül adunk értéket, figyelni


kell arra, hogy a lekérdezés pontosan egy sort adjon vissza. Abban az esetben, ha a
lekérdezés több sorral tér vissza, és a változó egy skal'r kifejezésre mutat. akkor a
v'ltozó értéke az utolsó sor megfelelő értéke lesz. (ORACLE esetén ilyenkor hibaüzenetet
kaptunk!)

16.6. Operátorok

16.6.1. Aritmetikai máiveletek


Az arittnetikai müveletek matematikai műveletet végeznek el két numerikus adattípuson.
A következő táblázat az arittnetikai operátorokat tartalmazza, és azok jelentését
Oper,tor Jelentés
+ Összeadás. Eredményének típusa a magasabb precedenciájú operandus
adattípusa. A bit típusra nem használható.
- K.ivonás. Eredményének típusa a magasabb precedenciájú operandus adattípusa
A bit típusra nem használható.
• Szorzás. Eredményének típusa a magasabb precedenciájú operandus adattípusa. A
datetime és a smalldatetime típusokra nem használható.
l Osztás. Eredményének típusa a magasabb precedenciájú operandus adattípusa. A
datetime és a smalldateti.me típusokra nem használható.
% Modulo osztás. Eredményének értéke INT tipusú.
A típusok közt Js van defimálva precedencia, erről bövebben az adattípusok feJezetben
lesz szó.

16.6.2. trtékadó müvelet


A T-SQL-ben az egyetlen értékadó operátor az egyenlőségjel(=).

151
16.A Transact-SQL alapjai Iváncsy Renáta

16.6.3. Bitmáiveletek

Bibnűveletek minden INTEGER típusú adattípus között értelmezhetőek.

Jelentés
Bit szintü S kapcsolatot hajtja végre. Kimenetének típusa megegyezik
a bemenetének ti usával.
Bit szintü VAGY kapcsolat. Kimenetének típusa megegyezik a
bemenetének ti usával.
Kizáró VAGY kapcsolat. Kimenetének típusa megegyezik a
bemenetének ti usával.

16.6.4. ÖSszebasonHtó máiveletek

Az összehasonlító müveletek segitségével határozhatjuk meg, hogy két kifejezés


megegyezik-e vagy sem. Összehasonlitó operátort minden kifejezés között lehet használni,
kivéve a text, ntext és az image típusok között.
Operátor Jelentés
= Egyenlő
> Nagyobb
< Kisebb
>= Nagyobb vagy egyenlő
<= Kisebb vagy egyenlő
<> Nem egyenlő
!= Nem egyenlő (Nem SQL-92 standard)
!< Nem kisebb (Nem SQL-92 standard)
!> Nem nagyobb (Nem 8_QL-92 standard)
Az összehasonlitó operátor eredménye BOOLEAN típusú (TRUE, FALSE vagy
UNKNOWN (ismeretlen). BOOLEAN tipus, eDentétben a többi tipussal, nem lehet tábla
oszlopának vagy változónak típusa, és nem térbet vissza eredménybalmazként.

16.6.5. Logikai máiveletek

A logikai müveletek bizonyos feltételek igazságát vizsgálják. Eredményük, hasonlóan a


logikai operátorokhoz BOOLEAN típusú, TRUE vagy FALSE értékkel.
Qp_erátor Jelentés
ALL IGAZ, ha az összehasonlítás halmazában minden IGAZ.
AND IGAZ, hamindkét BOOLEAN kifejezés IGAZ.
ANY IGAZ, ha legalább egy IGAZ a halmazbóL
BETWEEN IGAZ, ha az operandus a megadott határok közé esik.
EXISTS IGAZ, ha az allekérdezés eredménye legalább egy sor.
IN IGAZ, ha az operandus megegyezik eggyel a felsoroltak közül.
LIKE IGAZ, ha az operandus illeszkedik egy mintára.
NOT Negálás.
OR IGAZ, ha az egyik BOOLEAN kifejezés igaz.
SOME IGAZ, ha néhány az összehasonlító halmazból igaz, több, mint egy.

152
16.A Transact-SQL alapjai Iváncsy Renáta

16.6.6. Sztring összefűző művelet

Sztringeket a + operátorrallehet összefiízni. Például:


J SELECT vezeteknev + ' ' + keresztnev as nev FROM tanulo;

16.6.7. Egyoperandusú roliveletek


Az egyoperandusú müveletek egy operanduson végeznek el valamilyen müveletet. Az
operandusnak numerikusnak kell lennie.

Operátor Jelentés
+ Pozitiv előjel
- Negatív előjel
- Bit szerinti negálás (Csak INTEGER típuson lehet használni.)

16.6.8. Operátor precedencia

Az operátor precedencia határozza meg, hogy melyik müvelet kerüljön hamarabb


kiértékelésre. Az egyértelműség kedvéért érdemes használni a zárójelezést, mert ebben az
esetben biztos olyan sorrendben kerülnek elvégzésre a müveletek. ahogyan azt mí szeretnénk.
Az azonos szinten található müveletek balról jobbra kerülnek kiértékelésre.
+(pozitiv előjel),- (negativ előjel), -(bit negálás)
*(szorzás), l (osztás),% (moduló osztás)
+(összeadás), + (összefiizés), -{kivonás)
Összehasonlító operátorok(=,<,>,<=, >=, !=. <>,stb.)
",&, l (Bit müveletek)
NOT
AND
ALL, ANY, BElWEEN, IN, LIKE, OR, SOME
Értékadás (=

153
17 .T-SQL programvezérl ö utasítások Iváncsy Renáta

17. T-SQL programvezérlő utasftások


A T-SQL számos olyan programvezérlő utasítás tartalmaz, aminek a segítségével a T-
SQL utasítások. blokkok vagy tárolt eljárások végrehajtását vezérelhetjük. Ezek a szavak
használhatóak mind egyszerű lekérdezésekben, batch utasításokban vagy tárolt eljárásokban
is. Programvezérlő utasítások nélkül a T-SQL utasítások megjelenésük sorrendjében,
szekvenciálisan kerülnek végrehajtásra.

17.1. Blokkok definiálása, a BEGIN ••• END


A BEGIN és az END k:ulcsszavak segítségével van lehetőség arra, hogy T-SQL
utasításokat egy logíkai blokkba foglaljuk. A BEGIN és az END utasításoknak mindig párban
kell állniuk. nem szerepelhet BEGIN END nélkül, és fordítva, nem szerepelhet END BEGIN
nélkül. Akkor szokás használni, ha az IF ... ELSE utasításban vagy a WHILE ciklusban több
mint egy sort kell végrehajtani vagy a CASE függvény egy eleme utasitások egy blokkját
tartalmazza.

17.2. Az IF••. ELSE utasítás


A feltételes utasitás segítségével van lehetőségünk a T-SQL utasitások sorozataközt egy
feltételnek megfelelöen választani. Ha a feltételben megadott kifejezés értéke IGAZ, a feltétel
mögöttí utasitások futnak le. Opcionálisan megadható ELSE k:ulcsszó is, amivel az
utasításoknak egy altematíváját adhatjuk meg.
IF boolean kifejezés
Utasitás blokk
[ELSE
Utasítás_blokk)
A boolean_kifejezés egy olyan kifejezés, aminek eredménye IGAZ vagy HAMIS. Ha a
kifejezés egy SQL utasítás, akkor az utasítást zárójelek között kell megadni.
Az utasítások sorozata blokkba foglalt utasítások. Abban az esetben, ha az utasítások nem
kerülnek blokkba, csak egyetlen utasítás kerül végrehajtásra. A blokkot a BEGIN és az END
kulcsszavakkal kell megadni. Ha egy IF... ELSE kapcsolat m.indkét ágában használunk
CREATE T ABLE vagy SELECT INTO utasitást, akkor ezeknek az utasilásoknak
ugyanarra a táblanévre kell hivatkozniuk.
Az IF ... ELSE kifejezés használható mind batch-ekben (SQL utasítások egy összefogott
csoportja), mind tárolt eljárásokban, de akár egyszerű lekérdezés megfogalmazásakor is. A

154
17.T-SQL programvezérlő utasítások Iváncsy Renáta

feltételes kifejezések egymásba is ágyazhatóak, az egymásba ágyazások számának nincsen


korlátja.
Példa:
IF (SELECT anyag_egysegar FROM anyag WHERE anyag_nev='cukor')
< 100
BEGIN
PRINT 'A cukor ara tul alacsony!'
UPDATE anyag SET anyag_egysegar=anyag egysegar+50 WHERE
anyag_nev= 'cukor'
END
ELSE
PRINT 'A cukor ara megfelelo'

17.3. A WHILE ciklus


Az utasítások sorozata mindaddig végrehajtódik, amig a BOOLEAN kifejezés IGAZ
értékkel tér vissza. A ciklust a cikluson belülről a BREAK és a CONTINUE utasításokkal
lehet kontrollálni.
WHILE boolean __kifejezés
Utasítások sorozata
[BREAK]
Utasítások sorozata
[CONTINUE]
A boolean kifejezés egy olyan kifejezés, aminek eredménye IGAZ vagy HAMIS lehet.
Amennyíben a kifejezés egy SQL utasítást tartalmaz, az SQL utasításnak zárójelek között kell
szerepelnie. Az utasítások sorozata T-SQL utasítások, amikaBEGIN és az END kulcsszavak
közön blokkba lehetnek foglalva.
A BREAK utasítás segítségével lehet a legbelső WHILE ciklusból kiugrani. A
CONTINUE utasítás hatására a WHILE ciklus újraindul, figyelmen kívül hagyva a
CONTINUE után álló utasításokat.
Példa:
WHILE (SELECT AVG(price) FROM titles) < $30
BEG IN
UPDATE titles
SET price = price * 2
SELECT MAX(price) FROM titles
IF (SELECT MAX(price) FROM titles) > $50
BREAK

155
17 .T -SQL programvezérlő utasfiások lváncsy Renáta

ELSE
CONTINUE
END
PRINT 'Too much for the market to bear'

17.4. A GOTO
A GOTO utasítás segítségével egy címkére lehet ugrani. A GOTO utasítás és a címke
között egyetlen egy utasítás sem lesz végrehajtva. A GOTO gyakori használata nehezen
követhetövé teszi a kódot, ezért érdemes egyéb programvezérlő utasítás segítségével
megoldani a feladatokat. GOTO utasítást akkor érdemes használni, ha mélyen beágyazott
programvezérlő utasításokban járunk. és onnan szeretnénk ki ugrani_
A címke definiálása:
Cimke név:
A GOTO utasítás:
GOTO cimke nev
Példa:
DECLARE @tablename sysname
SET @tablename = N'authors'
table_loop:
IF (@@FETCH STATUS <> -2)
BE GIN
SELECT @tablename RTRIM(UPPER(@tablename))
EXEC ("SELECT """ t @tablename + """ = COUNT(*) FROM "
t @tablename
PRINT " "
END
FETCH NEXT FROM tnames cursor INTO @tablename
IF (@@FETCH STATUS <> -1) GOTO table loop

17.5. A RETURN
A RETURN utasítás feltétel nélkül megszakítja a lekérdezést, a tárolt eljárást vagy a
batchet. A RETURN utasítás után álló utasítások nem kerülnek végrehajtásra. Tárolt
eljárásban a RETURN értékéül egy INTEGER szám adható. Amennyiben nem adunk meg
visszatérési értéket, a tárolt eljárás O-val tér vissza. Általános szokás, hogy a RETURN kóddal
adjuk meg, hogy a tárolt eljárás sikeres volt-e. Siker esetén a visszatérési érték nulla, minden
nem nulla visszatérési érték hibát jelent.

156
17.T -SQL programvezér ló utasfiások Iváncsy Renáta

17.6. RETURN integer_kifejezés


Példa:
CREATE PROCEDDRE checkstate @param varchar(ll)
AS
IF (SELECT state FROM authors WHERE au id @par am) 'CA'
RETURN l
ELSE
RETURN 2

17.7. A WAITFOR
A WAITFOR utasítás megad egy időpontot vagy egy idö intervallumot ameddig az
utasítások végrehajtása felfüggesztödig.

17.8. W AITFOR {DELAYidő l TIME idő}


A DELA Y után álló idö megadja, hogy mennyi ideig legyen felfüggesztve az utasítások
futása (max. 24 óra). A DELA Y után megadott idő azt adja meg, hogy mennyi ideig kell
várni. Az idő paramétert DATETIME típusban kell megadni. Dátumot nem lehet megadni,
ezért a DA TETIME típus dátum részének használata itt nem megengedett (csak az óra, perc,
másodperc stb.). A TIME kulcsszó után egy abszolút időt kell megadni, a Serveraddig vár,
mig el nem éri az adott időt.

Példa:
BEGIN
WAITFOR TIME '22:20'
EXECUTE update_all_stats
END

17.9. A CASE függvény


A CASE filggvény kiértékel egy feltételt, és ennek megfelelően több lehetőség közül
visszaad egy értéket. Nagyon fontos megjegyezni, bogy a CASE függvény a Transact-SQL
esetén nem programvezérlő utuftás.
A CASE filggvény egy speciális T-SQL függvény, aminek segítségévellehetőség van az
oszlop értékének filggvényében más és más eredményt megjeleníteni. Ez a változtatás csak
átmeneti, tehát az adatban nem történik változás. Ezzel a módszerrellehetöség van arra, hogy
egy lekérdezésben a rövidítés helyett a teljes szót újuk ki, ha a táblában csak a rövidítés van
eltárolva. A CASE fiiggvény a következő elemekből áll:

157
17.T -SQL programvezérlő utasítások Iváncsy Renáta

• a CASE kulcsszóból,
• annak az oszlopnak a nevébő!, amit át akarunk alakítani,
• a WHEN és a THEN kulcsszavakból,
• az END kulcsszóból,
• és az opcionális ELSE kulcsszóból.
A CASE utasításnak két formája van, az egyszerű CASE és a SEARCHED CASE
utasítás. Az egyszerű CASE utasítás esetén a bemeneli változóra teszünk különböző

feltételeket. Amennyiben az egyik feltétel teljesül, a feltétel mögött álló kifejezéssel tér
vissza.
CASE bemeneti_ kifejezés
WHEN feltétell THEN visszatérési_ kifejezés l
WHEN feltétel2 THEN visszatérési __ kifejezés 2

WHEN feltételN THEN visszatérési_ kifejezés N


ELSE visszatérési_ kifejezésN+l

END
A bemeneli kifejezés akkor lesz végrehajtva, ha az egyszerű CASE utasítást használjuk.
Bármilyen érvényes SQL Server kifejezés lehet. A feltétel bármilyen érvényes kifejezés,
amivel a bemeneli kifejezés össze lesz hasonlítva. A bemeneli kifejezés tipusának és az
összehasonlító kifejezés tipusának meg kell egyeznie vagy implicit adatkonverziónak kell
életbe lépnie ahhoz, hogy az utasítás helyes legyen. A kimenet az a kifejezés, ami visszatérési
értéke lesz a CASE kifejezésnek, ha a feltétel és a bemeneti kifejezés megegyeztek. Az ELSE
után található visszatérési érték abban az esetben lesz az eredmény, ha egyetlen feltétel sem
lett igaz. Ha ez a rész hiányzik, és a bemeneli kifejezés nem illeszkedett egyetlen feltételre
sem, a CASE visszatérési értéke NULL lesz. A visszatérési értékek tipusának meg kell
egyezniOle vagy implicit konverzióval átkonvertálhatónak kell lenniük.
Az utasítás müködése:
• Kiértékeli a bemeneli kifejezést.
• A megadott sorrendben kiértékeli a bemeneti_kifejezés=feltétel egyenlőséget, minden
egyes WHEN kulcsszóra.
• Azzal a visszatérési kifejezéssel tér vissza, amelyik legelőször IGAZ értéket adott.
• Ha egy feltétel sem volt igaz, az SQL Server az ELSE ágban megadott kifejezéssel tér
vissza, ha volt megadva, egyébként pedig NULL értékkel.
A CASE utasítás lekérdezésen belül is használható.

!58
17.T-SQL programvezérlő utasítások lváncsy Renáta

Példa:
SELECT Category
CASE type
WHEN 'popular comp' THEN 'Popular Computing'
WHEN 'mod cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
END,
CAST(title AS varchar(25)) AS 'Shortened Title',
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY type, price

17.9.1. A SEARCHED CASE függvény

A SEARCHED CASE utasítás esetén nincsen bemeneti kifejezés, minden egyes


feltételnél egy BOOLEAN kifejezést kell megadni, és egy visszatérési kifejezést. Abban az
esetben, ha az adott BOOLEAN kifejezés IGAZ-at ad, a neki megfelelő visszatérési
kifejezéssel tér vissza.
CASE
WHEN BOOLEAN kifejezésl THEN visszatérési_ kifejezésl
WHEN BOOLEAN_ kifejezés2 THEN visszatérési kifejezés 2

WHEN BOOLEAN_kifejezésN THEN visszatérési_ kifejezés N


[ ELSE visszatérési _ kifejezés N+l
]
END
A filggvény müködése:
• A megadott sorrendben minden egyes WHEN kulcsszóra kiértékeli a BOOLEAN
kifejezést.
• Azzal a visszatérési kifejezéssel tér vissza, amelyikhez tartozó feltétel a legelőször

IGAZ-at adott.
• Ha egyetlen BOOLEAN kifejezés értéke sem lett IGAZ, akkor az ELSE ágban
megadott visszatérési kifejezéssel tér vissza, ha volt ELSE ág, egyébként pedig NULL
értékkel.

159
17.T-SQL programvezérlő utasilásolt lváncsy Renáta

Példa:
SELECT 'Price Category'
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table
Title'
ELSE 'Expensive book!'
END,
CAST(title AS varchar(20)) AS 'Shortened Title'
FROM titles
ORDER BY price
Az eredmény:
Price Category Shortened Title

Not yet priced Net Etiquette


Not yet priced The Psychelegy of Co
Very Reasonab1e Title The Gourmet Microwav
Very Reasonable Title You Can Combat Compu
Very Reasonable Title Life Without Fear
Very Reasonable Title Emotional Security:
Coffee Table Title Is Anger the Enemy?
Coffee Table Title Cooking with Compute

160
18.T-SQL adattípusok lváncsy Renáta

18. T-SQL adattípusok


A Microsoft SQL Server 2000-ben m.inden oszlopnak, lokális változónak, kifejezésnek és
paraméternek megvan a maga típusa. Az SQL Server számos rendszer által definiált adattípust
ad meg. Lehetőség van felhasználó által definiált adattípusok megadására is, ami nem más,
mint a rendszer által definiált adattipus elnevezése (ezt az sp_addtype utasítással lehet
megtenni.). A rendszer által definiált adattípusok a következők:
INTEGERS
63 63
• bigint (Egész szám, értéktartománya: -2 .•• 2 -1)
31 31
• int (Egész szám, értéktartománya: -2 ••• 2 -1)
5 15
• smallint (Egész szám, értéktartománya: -i .•• 2 -l)
• tinyint (Egész szám, értéktartománya: 0 .. . 255)
BIT (Integer szám Ovagy l értékkel.)
DEC~és~RlC
38 8
• decimal (Fix pontos szám, értéktartománya -10 + l...lol -l)
• numeric (megegyezik a decimal adattipussal)
MONEYésSMALLMONEY
• money
• smallmoney
Lebegőpontos számok
• float (Lebegőpontos szám, értéktartománya: -1.79E+308 ... 1.79E+308)
• real (Lebegőpontos szám, értéktartománya: -3.40E+38 ... 3.40E+38)
Dátumok
• datetime (1753. Jan. 1...9999 Dec 31-ig tartó dárum és idő)
• smalldatetime (1900.Jan 1...2079. Jun 6-ig tartó dátum és idő)
Karakter típusok
• char (Fix hosszú nem unicode karakter, maximális hossz 8000 karakter lehet)
• varchar (Változó hosszúságú, nem unicode karakter, maximális hossz 8000 karakter
lehet)
31
• varchar(max) (Változó hosszúságú, nem unicode karakter, maximálisan 2 karaktert
tartalmazhat)
31
• text (Változó hosszúságú nem unicode karakter, melynek maximum hossza 2 -1
lehet)

161
18.T-SQL adattípusok lváncsy Renáta

Unicode karakter típusok


• nchar (Fix hosszú unicode karakter, maximálisan 4000 karakter hosszú lehet.)
• nvarchar (Változó hosszú unicode karakter, maximálisan 4000 karakter hosszú lehet.)
• nvarchar(max) (Változó hosszúságú, unicode karakter, maximálisan 2 30 karaktert
tartalmazhat)
• ntext (VáltozÓ hosszúságú unicode karakter, melynek maximum hossza 2 30-l lehet)
Bináris sztringek
• binary (Maximálisan 8000 byte méretü, fix hosszú bináris adat.)
• varbinary (Maximálisan 8000 byte hosszú, változó méretü bináris adat.)
• varbinary(max) (Maximálisan 2 31 byte hosszú, változó méretü bináris adat)
• image (Maximálisan 231 -1 byte méretü, változó méretü bináris adat.)
Egyéb tipusok:
• cursor (Referencia egy k:urzorra.)
• sql_ variant (Adattípus, ami lcülönbözö SQL Server adattípust tartalmaz, kivéve a text,
ntext, timestamp és az sql_ variant típusokat.)
• table (Speciális adattípus, hogy egy eredmény halmazt későbbi feldolgozásig
tároljunk.)
• timestamp (Az egész adatbázisra nézve egyedi szám, ami akkor kerül módosításra,
amikor egy sor módosításra került. )
• uniqueidentifier (Globálisan egyedi azonosító.)
• xm1 (XML adatot tárol, melyet változóban vagy tábla oszlopban lehet használni)

18.1. Adattípus precedencia (datatype precedence)


Ha két lcülönbözö típusú adat vagy kifejezés egy operátor segitségével egymással
kapcsolatba kerül, az adattípus precedencia az, ami meghatározza az eredmény típusát. Az
eredmény típusa a magasabb precedenciával rendelkező adattípus lesz. Ez a precedencia a
következő :

162
IS.T-SQL adattípusok lváncsy Renáta

sql_variant (legmagasabb) bit


datetime ntext
smalldatetime text
float image
real timestamp
decimal uniqueidentifier
money nvarchar
smallmoney nchar
bigint varchar
int char
smallint varbinary
tinyint binary (legalacsonyabb)

163
19.T-SQL lrurzorok Iváncsy Renáta

19. T-SQL kurzorok


A legtöbb esetben egy lekérdezés eredménye több, m.int egy sor. Dyenkor az eredmény
egy adathalmaz, ami a lekérdezésben visszatérö rekordokat tartalmazza. A kurzorok
segítségével lehetőségünk van ezen az adathalmazon navigálni, így az egyes rekordokat
egyenként elérni. A kurzorok kezelése 5 to lépésböJ áll.
• A kurzor deklarálása a DECLARE kulcsszó segítségéveL Ebben a lépésben kell
megadni azt a lekérdezést, amire a kurzort létrehozzuk.
• A kurzor megnyitása, ebben a fázisban kerül a lekérdezés végrehajtásra.
• Navigálás a sorok között, valamint az egyes sorok értékének felhasználása.
• A kurzor bezárása.
• A kurzor deallokálása.
Az egyes lépéseket részletesen a fejezet további részében tárgyaljuic
Az SQL Server 2000-ben is lehetőség van kurzor változók használatára. A kurzor
változókról egy külön alfejezet szól.

19.1. A kurzorok működése


Az SQL Server 2000-ben, ellentétben az ORACLE9i-vel a kurzorok nem csak egy
irányba mozoghatnak, hanem lehetőségünk van minden fajta navigációra az adathalmazon
belül. Egy másik k:ülönbség, hogy míg az ORACLE esetén a lekérdezés adathalmaza a kurzor
megnyitása után (azaz a lekérdezés végrehajtása után) állandó, addig az SQL Serveren az
adathalmaz sorain lehetőség van módosításra, esetleg törlésre is, így a kurzor használata
teljesen eltér az ORACLE esetében megismerttőL

19.2. A kurzor deklarálása


Az SQL Server 2000-ben a kurzorokat kétféleképpen lehet deklarálni. Az egyik az SQL-
92 szabvány szintaktikája, a másik a T-SQL szintaktikája. Mindkét deklaráció használata
helyes, de egy deklaráláskor a két szintaktika nem keverhetö.
Az SQL-92 szabvány szerinti deklaráció:
DECLARE kurzornév [INSENSITIVE] [SCROLL] CURSOR
FOR lekérdezés
[FOR {READ ONLY' l UPDATE [OF oszlopnév [, ... n]]} J
A kurzornév bármilyen, az azonosítók:nálleírt szabályoknak megfelelő azonosító lehet.
Az INSENSITIVE kulcsszó segítségével az adható meg, hogy a kurzor által használt adat
átmeneti másolata az eredeti adatnak. Ez az átmeneti tábla a tempdb adatbázisban van, és

164
19.T-SQL kurzorok lváncsy Renáta

minden kurzor müveletre ebből a táblából kapjuk a választ, így ezzel a lrurzorral nem tudjuk
módosítani az adatokat. Ha nem adjuk meg ezt a kulcsszót, akkor komnúttáJt törlések és
módosítások megtehetőek a ,,kurzor alatti" táblákon.
A SCROLL kulcsszó segítségével az adható meg, hogy a Irurzoron minden típusú FETCH
utasítás (FIRST, LAST, PRIOR. NEXT, RELATIVE, ABSOLUTE ld, később) érvényes. Ha
a SCROLL nincs megadva, akkor az egyetlen támogatott FETCH utasítás a NEXT.
A lekérdezés az a lekérdezés, ami meghatározza a Imrzor adathalmazát. A COMPUTE,
COMPUTE BY, FOR BROWSE és az INTO Irulesszavak használata nem megengedett a
lekérdezésben.
A READ ONLY kulcsszó megadása esetén a k:urzoron nem adhatóak meg módosítások.
Az UPDATE OF oszlopnév kulcsszó segítségével meg lehet adni azokat az oszlopokat,
amik módosíthatóak a lrurzoron keresztül. Ha nincsen megadva oszlop lista, az összes oszlop
módosítható.
A Transact-SQL deklaráció:
DECLARE kurzornév CURSOR
[ LOCAL l GLOBAL l
[ FORWARD_ ONLY l SCROLL l
[ STATIC l KEYSET l DYNAMIC l FAST_ FORWARD
[ READ_ONLY l SCROLL_ LOCKS l OPTIMISTIC J
[ TYPE_WARNING J
FOR lekérdezés
[FOR UPDATE [OF oszlopnév [ , ... n J J J
A LOCAL kulcsszóval megadható, hogy a lrurzor lokális legyen a triggerben, tárolt
eljárásban vagy batch-ben, ahol deklaráltuk. Ha a batch, tárolt eljárás vagy a trigger
befejeződik. a lokális kurzor implicit deallokálásra kerül. Amennyiben egy tárolt eljárás
ki.menö paramétere volt, úgy csak akkor kerül deallokálásra, ha az utolsó referencia is
megszünt rá.
A GLOBAL kulcsszóval megadható, hogy a lrurzor a kapcsolatra nézve globális, a kurzor
bármely tárolt eljárásból, triggerböl vagy batch-böl elérhető. Csak disconnect esetén
deallokálódi.k implicit a lrurzor.
A FORWARD ONLY kulcsszó azt adja meg, hogy a kurzor csak az első sorától az
utolsóig érhető el, így csak a FETCH NEXT utasítást támogatja.
A STATIC kulcsszó segitségével az adható meg, hogy a lrurzor által használt adat
átmeneti másolata az eredeti adatnak. Ez az átmeneti tábla a tempdb adatbázisban van, és
minden lrurzor müveletre ebböl a táblából kapjuk a választ, így ezzel a kurzorral nem tudjuk

165
19.T-SQL lrurzorok lváncsy Renáta

módosítani az adatokat. Ha nem adjuk meg ezt a lrulcsszót. akkor kommittált törlések és
módosítások megtehetőek a ,,kurzor alatti" táblákon.
A KEYSET lrulcsszó segitségével az adható meg, hogy a kurzoron belüli sorok tagsága és
sorrendje meghatározott, ha a kurzort kinyitottuk. A sorokat egyértelmüen azonosító lrulcsok
halmaza a tempdb adatbázis egy táblájában kerülnek eltárolásra, ezeket nevezik keyset-nek.
A nem Irules oszlopok módositása láthatóvá válik a kurzorban való mozgás során.
A DYNAMIC kulcsszó megadása esetén a kurzoron tett minden módosítás azonnal
látszódik, ahogy a kurzoron haladunk végig. Az adat értékek. sorok sorrendje és tagsága
minden egyes FETCH esetén változhat.
A FAST FORWARD lrulcsszó egy csak előre haladó (FORWARD ONLY), csak
olvasható (READ ONLY) kurzort deklarál.
A READ ONLY kulcsszó egy csak olvasható kurzort deklarál.
A SCROLL LOCKS lrulcsszó garantálja. hogy a pozicionált módositások vagy törlések
biztosan sikeresek lesznek a kurzorban. Az SQL Server zárolja a sorokat. amint azok be lettek
olvasva a kurzorba. hogy biztosítsa az elérhetőségüket

Az OPTIMISTIC kulcsszóval az adható meg, hogy a pozicionált módosító vagy törlő

utasítás ne hajlódjon végre, ha az adott sor az utolsó beolvasás óta módosftásra került. Az
SQL Server ilyenkor nem zárolja a sorokat, amikor beolvassa azokat a kurzorba. helyette
időbélyegeket használ.
A TYPE W ARNING lrulcsszó megadásával megadható az az opció, hogy a kliens oldalra
egy figyelmeztető üzenet kerüljön elküldésre, ha a kurzor implicit adatkonverzión esett át.

19.3. A kurzor megnyitása


A kurzor megnyitásának szintaktikája a következő:
OPEN {{[GLOBAL] kurzornév} l kurzor_változó_név}
Az OPEN utasítás megnyitja az argumentumaként megadott kurzort vagy kurzor változót,
és lefuttatja a deklarációs részben megadott lekérdezést. Ha a kurzort INSENSITIVE vagy
STATIC opciókkal deklaráltuk, akkor a megnyitáskor létrejön egy átmeneti tábla. ami az
eredményhalmazt tartalmazza. Az OPEN utasítás nem hajtódik végre, ha az eredményhalmaz
sorainak a száma meghaladja a Microsoft SQL Server táblájának maximum sor méretét. A
@@CURSOR_ ROWS adja meg a sikeresen visszakapott sorok számát.

166
19.T-SQL kurzorok lváncsy Renáta

19.4. A korzor kezelése


A kunorból a FETCH utasítás segítségével kaphatjuk meg az általunk kiválasztott sor
értékét Az SQL Serveren nem csak egy irányban lehet mozogni a kunorral, lehetőség van a
legelső, legutolsó vagy akár tetszőleges sor elérésére is. A FETCH utasítás szintaktikája a
következő :

FE TCH
[ [ NEXT l PRIOR l FIRST l LAST
l ABSOLUTE { n l @nvar }
l RELATIVE { n l @nvar }
l
FROM

{ { [ GLOBAL l cursor name } l @cursor variable name }


[ INTO @variable_name- [ , .. . n ] ] - -
A NEXT (következő), PRIOR (előző), FIRST (első) és LAST (utolsó) Irulesszavak adják
meg, hogy melyik irányba mozogjunk az adathalmazon belül, illetve, hogy a legelső vagy a
legutolsó sorra ugorjunk. A NEXT megadása esetén az aktuális sort követő sorral tér vissza,
és az aktuális sor értékét növeli eggyel. A PRIOR megadása esetén az aktuális sor elötti sorral
tér vissza, és az aktuális sor értékét csökkenti eggyel. A FIRST megadása eselén a legelső

sorral tér vissza, és az aktuális sor értékét az elsö sorra állítja. A LAST kulcsszó megadása
esetén a legutolsó sorral tér vissza, és azt teszi meg az aktuális sornak.
Az ABSOLUTE lrulcsszó megadása esetén az adathalmaz elejétől vagy végétöl számított
adott sorszámú sorát kapjuk meg. Ha a szám az ABSOLUTE lrulcsszó után pozitív, az
abszolút sorszámot a kunor elejétől számítja, ha negatív, akkor a végétől. Ha a paraméter
értéke nulla, az aktuális sorral tér vissza.
Ha a REALTIVE lrulcsszó után megadott n szám pozitiv, az aktuális sor utáni n-dik sort
adja vissza, ha negatív, akkor az aktuális sor előtti n-dik sort. Ha n értéke nulla, az aktuális
sorral tér vissza.
Az INTO kulcsszó segítségével adhatók meg azok a változók. amikbe az adott sor kerülni
fog. Balról jobbra a megfelelő változókba a kunor oszlopai kerülnek a megfelelő sorrendben.
A változók és az oszlopok típusának vagy meg kell egyeznie, vagy implicit adattípus
konverziónak kell müködni rájuk. A változók számának meg kell egyeznie a kurzorban
kiválasztott oszlopok számávaL

!67
19.T-SQL lrurzorok Iváncsy Renáta

19.5. A korzor bezárása


A CLOSE utasítás segítségével lehetőségünk van egy lrurzort bezárni. Ilyenkor az
eredményhalmaz elengedésre kerül, és m.inden lrurzor zár is felszabadul, ami az aktuális soron
volt. A CLOSE az adatstruktúrát megtartja újranyitás céljából, de amíg nem kerül újra
megnyitásra, nem lehet belöle sorokat lekérdezni, vagy pozícionálni benne. A CLOSE
utasítást csak megnyitott lrurzorokra lehet hasmálni.
CLOSE {{[GLOBAL] kurzornév) l kurzor változó név

19.6. A korzor "elengedése"


A DEALLOCATE utasítás segítségével lehet megszüntetni egy referenciát egy
adatstruktúráróL Ha az összes referencia megszünt egy eredményhalmazról, az SQL Server
megszünteti az adatstruktúrát
DEALLOCATE {{[GLOBAL] kurzornév} kurzor változó név

19.7. Korzorváltozók
A lrurzorváltozókat a batch vagy eljárás DECLARE utasításában lehet deklarálni.
Deklarálás után az alapértelmezett értékük a NULL. Értéket a SELECT vagy a SET utasításon
belül kaphatnak.
DECLARE kurzor változó név CURSOR

19.8. Információk korzorokról


A következö skalár ftlggvények a lrurzorokról adnak meg információkal:
@@CURSOR _ROWS, @@CURSOR_ST ATIJS, @@FETCH_ST ATIJS.
A @@FETCH _STATIJS a legutolsó FETCH utasítás státuszát adja vissza. Értéke O, ha a
FETCH sikeres volt, -l, ha a FETCH utasítást nem sikerül végrehajtani, vagy a sor kívül esett
az eredményhalmazon. -2 a visszatérési értéke, ha az adott sor hiányzik az eredmény
halmazból (ki lett törölve.). A filggvény értéke nem definiált, ha még egyetlen FETCH
müvelet sem került végrehajtásra.
Az alábbi példa az anyag tábla sorait sorra kiírja a kimenetre.
declare @id int, @nev varchar(20), @egyseg char(2), @ar float
declare cl CURSOR FOR select * from anyag;

open cl
fetch cl into @id, @nev, @egyseg, @ar

168
19.T-SQL kurzorok Iváncsy Renáta

while @@FETCH STATUS o


begin
print convert(varchar,@id)+': '+@nev+'
'+convert(varchar,@ar)+'Ft/'+@egyseg
fetch cl into @id, @nev, @egyseg, @ar
end
close cl
deallocate cl
A következő tárolt eljárások különbözö információkat szolgáltatnak a kurzorokról :
sp_describe_cunor : Az eljárás paramétere egy kurzor vagy egy kurzor változó,
k.imenete pedig egy kurzor típusú változónak kelllennie (noha az eredmény egyetlen sor.). Az
eljárás lefuttatása után a FETCH utasítással nyerhetjük ki az információt a kimeneti
kurzorból. Az eljárás információt ad meg a kurzorról.
sp_cunor_list: Ugyanazt az eredményt adja, mint az sp_describe_cunor, csak az összes
kurzorra.
sp_describe_cunor_tables: A kurzorhoz rendelt táblákról ad információt.
sp_describe_cunor_columns: A kurzorhoz rendelt tábla oszlopairól ad információt.

19.9. Módosítások a korzorban


A módositható kurzorok k:ülönbözö adatmódositó utasításokat támogatnak. Ha egy sorra
pozicionáltunk egy k:urzorban, az adott soron UPDATE és DELETE utasítások hajthatók
végre. Ezen utasítások célpontja a kurzor alaptáblája lesz. Az UPDATE és DELETE
utasításokat a WHERE CURRENT OF kulcsszóval kell hasmálni. A Transact-SQL
kurzorokban nincs lehetőség új sor beszúrására.
Ha a kurzort úgy hoztuk létre, hogy a lekérdezés eredmény sorainak sorrendje nem egyezik
meg az eredeti sorrenddel, a kurzor csak olvasható lesz. Csak olvasható lesz a kurzor például,
ha ORDER BY, GROUP BY, DISTINCT stb. kulcsszavakat használjuk benne, hiszen ebben
az esetben a sorrend változik.
Ha egy kurzorból töröltünk egy sort, a kurzor a kitörölt sorra mutat. ami azonban már nem
létezik. Ha bármilyen müveletet szeretnénk ezek után elvégem.i, a kurzort léptetni kell
valamilyen irányba.

169
20.T-SQL tárolt eljárások Iváncsy Renáta

20. T-SQL tárolt eljárások


Amikor egy programot írunk az SQL Server 2000-re, az elsődleges programozási nyelv,
aminek a segítségével a szerverrel kommunikálhatunk a Transact-SQL. A Transact-SOL
utasítások halmazát kétféleképpen használhatjuk. Egyrészt eltárolhatjuk öket a kliens oldalon,
és az alkalmazás elküldi azokat a szervernek. és fogadja az eredményt, de lehetőség van arra
is (és egyben ajánlatos is), hogy ezeket az utasításokat egységekbe foglalva a szerveren
tároljuk, és futtassuk. llyen lehetőség a tárolt eljárások használata, ilyenkor a kliens oldal csak
futtatja az eljárásokat, magukat az utasításokat nem ö tárolja el. Az SQL Server tárolt
eljárások alapvető tulajdonságai hasonlít minden egyéb programozási nyelv alapvető

tulajdonságaihoz:
• Lehetnek ki és bemenő paraméterei egyaránt.
• Utasításokat tartalmazhat, amik az adatbázison hajtanak végre müveleteket, és
természetesen más tárolt eljárást is meghívhat A tárolt eljárások, ellentétben az
ORACLE-lel, tartalmazhatnak DDL és DCL utasításokat is.
• Státusz információval térhet vissza az öt hívó eljárás vagy batch felé, ezzel jelezve a
sikerességet vagy a hibát.
Az SQL Server öt csoportba sorolja a tárolt eljárásokat. [l]
• A rendszer tárol eljárások a master adatbázisban vannak eltárolva. Minden rendszer
tárolt eljárás az sp_ prefixszel kezdődik. Segítségükkel lehetőség nyilik a
rendszertáblák adatainak lekérdezésére, az adminisztrátoroknak a rendszertáblák
módosítására, noha nincs joguk a táblákat közvetlen módosítani. A rendszer tárolt
eljárásokat bármely adatbázisban futtathatjuk.
• A lokális tárolt eljárások az egyes felhasználói adatbázisokban vannak eltárolva.
• Az átmeneti tárolt eljárások lehetnek lokálisak, ekkor a nevük egy #-kal kezdődik.

vagy globálisak. ilyenkor a nevük prefixe a következő : ## .

• A távoli tárolt eljárás (remote) az SQL Server egy korábbi sajátossága volt, most az
elosztott lekérdezések támogatják ezt a funkcionalitást.
• A kO.lső tárol eljárások (extended) DLL-ként vannak implementálva, és az SQL
Server környezetén kívül futnak le. Ezek az eljárások az xp_ prefixszel rendelkeznek.
A tárolt eljárást az EXECUTE utasítás segitségével futtathatjuk. A tárolt eljárások abban
különböznek a filggvényektöl, hogy nevük helyén nem térnek vissza értékkel, és nem
használhatóak kifejezésekben sem.

170
20.T-SQL tárolt eljárások lváncsy Renáta

A tárolt eljárások használatának előnyei:

• Elősegíti a moduláris programozást Az eljárás kódja a kliens kódjától fiiggetlenül


módosítható. A tárolt eljárást a kliens oldalról akárhányszor meghivhatj uk.
• Gyorsabb futást eredményez. A tárolt eljárás optimalizálva lesz, amikor létrehozzuk
őket, és elsö használat után használható a memóriában található verziója.
• Csökkenti a hálózati forgaimat
• Biztonságí mechanizmusként is használható. A felhasználóknak adhatunk jogot
futtatni az eljárást, még akkor is, ha az eljárás egyes utasításainak futtatására nem
lenne jogosultsága.
A tárolt eljárást a CREATE PROCEDDRE utasítással hozhatjuk létre, és az ALTER
PROCEDDRE utasítással módosíthatjuk. Az eljárás két ffi részből áll, az eljárás nevének és
paramétereinek a specifikálásából, valamint a törzsből, ami a T-SQL utasításokat tartalmazza.
A tárolt eljárás négyféle módon ad vissza információt:
• .Kimeneti paraméterként, ami lehet egyrészről skalár érték vagy kurzor változó.
• Visszatérési értékkel, ami minden esetben egy integer szám.
• Eredmény halmazzal, ami a tárolt eljárásban szereplö lekérdezések eredménye.
• Globális kurzorral, amire a tárolt eljáráson kivül is hivatkozhatunk.

20.1. Tárolt eljárás létrebozása


Tárolt eljárást a CREATE PROCEDDRE utasítással hozhatunk létre. Szintaktikája a
következő :

CREATE PROC [ EDURE l eljárás_név ; number


[ { @paraméter adat típus }
[ VARYING l [ • default l OUTPUT l
1 • • ·n l

WITH
{ RECOMPILE ENCRYPTION l RECOMPILE 1 ENCRYPTION } l

FOR REPLICATION

AS sql_utasítások [ ... n l
A ;number opcionális paraméter segítségével lehetőségünk van azonos nevü eljárásokat
létrehozni más sorszámmal, majd egyszerre le tudjuk törölni az egészet, csak az eljárás nevére
kell hivatkozni, szám nélkül (külön-külön nem is lehet letörölni öket). A létrehozáskor a
sorszámokat egytől kezdve kell megadni . Ha futtatáskor nem adjuk meg az eljárás számát,
akkor az egyes számmal ellátott eljárás fog lefutni.

171
20.T-SQL tárolt eljárások Iváncsy Renáta

A bemeneli paraméter núndig @-al kezdődik, és meg kell adni mind a típusát, mind a
típus hosszát, ha van ilyen. Az eljárás meghívásakor núnden bemenő paraméternek értéket
kell kapnia.
A VARYING Irulcsszó csak Irurzor paraméter esetén használható, megadja a kimeneti
paraméterként támogatott eredményhalmazt.
Az = jel után adható meg, hogy mi legyen az adott paraméter alapértelmezett értéke.
Amennyiben van egy paraméternek alapértelmezett értéke, úgy híváskor nem kell feltétlen
értéket kapnia. Az alapértelmezett értéknek konstansnak kell lennie, vagy lehet NULL érték
is. Tartalmazhat "wildcard" karaktereket(%, _. stb.) is, ha a paramétert az eljáráson belül a
LIKE operátorban használják.
Az OUTPUT lrulcsszó azt adja meg, hogy az adott paraméter kimeneti paraméter.
RECOMPILE l ENCRYPTION l RECOMPILE , ENCRYPTION: A RECOMPLIE
lrulcsszóval adható meg, hogy a tárolt eljárás futási időben legyen újrafordítva, azaz ne
tárolódjon el a futási terve. Az ENCRYPTION lrulcsszó használata esetén a tárolt eljárás
kódja titkosítva lesz, hogy elosztott adatbázisok esetén a kód ne kerüljön nyilvánosságra.
Egy tárolt eljárás mérete maximálisan 128Mb lehet. A CREATE PROCEDURE utasítás
nem keveredhet egy hatch-en belül semmilyen más T-SQL utasítással. A paraméterek
alapértelmezés szerint felvehetik a NULL értéket.

20.2. Tárolt eljárás futtatása


Tárnit eljárást az EXECUTE utasítással futtathatunic
EXEC [ UTE l l
{
@return_ status • l
{ eljárás_név [ ;number 1 1 @procedure_ name_ var

@parameter =1 { érték l @változó [ OUTPUT l l [


DEFAULT J l
[ , ... n l
[ WITH RECOMPILE l
A @retum_status egy integer típusú változó, amibe a tárolt eljárás visszatérési
információja fog kerülni. A változót a tárolt eljárás futtatása előtt kell definiálni.
A @procedure_name_var egy lokálisan definiált változó, ami egy tárolt eljárás nevét
reprezentálja.
A paraméterek megadásának két módja van. Egyrészt lehetőség van a név szerinti
paraméter átadásra, ilyenkor a @paramétemév=érték szintaktikát kell használni. Lehetőség

van azonban a pozíció szerinti paraméter átadásra. llyenkor a hívó értékek sorrendjének meg

172
20.T-SQL tárolt eljárások lváncsy Renáta

kell egyeznie az eljárásban deklarált paraméter sorrendnek. A:z. eljárást meghívhatjuk


konstansokkal, mint paraméterek, de lehetöség van változóval is meghívni egy eljárást. A
kimeneti paramétereket mindenképpen egy változóha kell betenni, aminek a típusa
megegyezik a kimeneti paraméter típusával. Ha a paraméter helyén a DEFAULT kulcsszó áll,
akkor a tárolt eljárás definiálásakor megadott alapértelmezett érték lesz a paraméter értéke. A
WITH RECOMPll...E kulcsszó használata esetén a tárolt eljárást újra fordítja a rendszer.

20.3. Tárolt eljárások módosítása


Tárolt eljárást az ALTER PROCEDORE utasítással lehet módosítani, és meg kell adni az
egész új eljárást, mintha most hoznánk létre.

20.4. Tárolt eljárások törlése


Tárolt eljárást törölni a DROP PROCEDORE utasítással lehet.
DROP PROCEDURE eljárás_név

20.5. Információk tárolt eljárásról


A tárolt eljárás kódját az sp_helptext eljárás hívásával kaphatjuk meg, ha bemeneti
paraméterként megadjuk a látni kívánt eljárás nevét (ha az eljárás titkosítva lett, az
sp_helptext segítségével nem láthatjuk a kódját). A:z. sp_depends eljárás segítségével
kaphatjuk meg azon objektumok listáját, amikre a tárolt eljáráson belül hivatkoruniL A tárolt
eljárást az sp _rename eljárással nevezhetjük át.

173
21.T-SQL filggvények Iváncsy Renáta

21. T-SQL függvények

21.1. Beépített függvények


Az SQL Server 2000 háromféle beépített tipust támogat Ezek az eredményhalmaz
filggvények (rowset function), az oszlop filggvények (aggregate function) és a skalár
filggvények.

21.1.1. A rowset függvények

A rowset filggvények ott használhatóak, ahol az SQL utasításban táblára hivatkozhatunk.


llyen ftlggvények a következők : CONTAINSTABLE, FREETEXTTABLE,
OPENDATASOURCE, OPENQUERY, OPENROWSET és az OPENXML

21.1.2. Az oszlop fflggvények

Az oszlopftlggvények értékek egy halmazán hajt végre számításokat és egy értékkel tér
vissza. A COUNT ftlggvény kivételével az oszlopfiiggvények a NULL értékeket figyelmen
kívül hagyjálc Leggyakrabban egy SELECT lekérdezésben szoktá.k használni.
A T-SQL-nek a következő oszlopftlggvényei vannak:
FüEEVény Jelentés
AVG Átlagot számítja ki.
BINARY CHECKSUM Bináris ellenőrzö összeg számítása.
CHECKSUM Ellenőrzö összeg számítása
CHECKSUM AGG Csoportokra ellenőrzö összeg számítása.
CO UNT Elemek számát adja meg egy csoportban. Az eredményt int-ben
adja.
COUNT BIG Ugyanaz, mint a COUNT, csak az eredményt bigint-ben adja me_g.
GROUPING Megjelöli a sort, hogy a ROLLUP vagy a CUBE eredményeként
jött-e létre. (Csak olyan lekérdezésben használható, a hol a
GROUP BY a CUBE vagy a ROLLUP kulcsszóval szerepel.)
MAX A maximummal tér vissza.
MIN A minimummal tér vissza.
SUM Az összeggel tér vissza.
STDEV Az elemek szórását adja meg.
STDEVP Az elemek populációjának szórását adja meg.
VAR A statisztikai varianciát (szórásnégyzetet) adja meg a kifejezés
elemeire.
VARP Az elemek populációjának szórásnégyzetét adja meg.

21.1.3. A skalár fflggvények

A skalár ftlggvények egyetlen egy értékkel dolgoznak, és egy értékkel is térnek vissza. A
skalár fiiggvényeket a következő osztályokba sorolhatjuk:

174
21. T-SQL fiiggvények Iváncsy Renáta

• Konfigurációs fiiggvények
• Kurzor ftlggvények pl. @@FETCH_STATUS
• Dátum és idö függvények pl. GETDATE, DATEADD, DATEDIFF
• Matematikai ftlggvények pl. ABS, SIN, FLOOR
• Metaadat fiiggvények pl. COL_NAME, COL_LENGTH, DB_NAME
• Biztonsági ftlggvények pl. HAS_ DBACCESS, USER, USER_ ID
• Sztring ftlggvények pl. CHAR, LTRIM, LOWER, UPPER
• Rendszer ftlggvények pl. CAST, CONVERT, CURRENT_USER, ISNULL
• Rendszer statisztikai függvények pl. @@IDLE, @@TOTAL_WRITE
• Text és kép ftlggvények pl. PATIND EX, TEXTPTR, TEXTVALID

21.2. Felhasználó által definiált függvények


A felhasználó által definiált ftlggvényeket a felhasználó készíti el a CREATE
FUNCTION utasítás segitségével, ahol megadja a ftlggvény feladatát elvégzö Transact-SQL
utasításokat. A ftlggvényt módosítani az ALTER FUNCTION utasítással lehet, mig törlésre a
DROP FUNCTION utasítás szolgál. A felhasználói függvény nulla, egy vagy több bemeneli
paramétert kaphat, és vagy egy skalár vagy egy tábla a visszatérési értéke. A ftlggvénynek
nem lehet kimeneti paramétere.
Az SQL Server 2000 három típusú felhasználó által definiált fiiggvényt támogat, ezek a
következők:

• Skalár ftlggvények (scalar function)


• In-line tábla értékű fiiggvények (In-line Table-valued function)
• Több utasításból álló tábla értékű függvények (Multistatement Table-valued function)
A skalár fiiggvények visszatérési értéke egy skalár érték. Az In-line tábla értékű

függvények visszatérési értéke egy tábla. A ftlggvénynek ebben az esetben nincs törzse, a
visszatérési érték egyetlen SELECT utasítás eredménye. A több utasításból álló tábla értékű

függvények visszatérési értéke szintén egy tábla, de ezt több SELECT utasítás hozza létre.
Nagyon fontos megjegyezni, hogy SQL Serveren a ftlggvényeket csak úgy lehet
meghívni, ha legalább két tagból álló nevével hivalkozunk rá. Ez tipikusan a fiiggvény
tulajdonosa előtaggal való ellátást jelenti. Az alábbi feladatokban a ftlggvény tulajdonosa
minden esetben az ap60 felhasználó lesz.

!75
21.T -SQL filggvények Iváncsy Renáta

21.2.1. A ffiggvények létrehozása

A fiiggvényeket a CREATE FUNCfiON utasítással hozhatjuk létre. Ennek szintaktikája


a különbözö filggvény tipusokra eltérő.
Skalár filggvény létrehozása:
CREATE FUNCTION függvény név
( [ { @paraméter_név [ AS] skalár_ adattípus default J }
[ , •• . n ] ] )
RETURNS skalár visszatérési tipus
[ WITH < függvény_opc i ók> [- [,] ... n]
[ AS ]
BEGIN
függvény_ törzs
RETURN skalárkifejezés
END
Ahol a filggvény _opciók a következöképpen vannak definiálva:
< függvény_opció > : : =
{ ENCRYPTION l SCHEMABINDING }
A @paraméter_név a filggvény bemeneti paramétere. A nulla. egy vagy több paramétert
definiálhatunk a ftlggvény létrehozásakor, de a paraméterek maximális száma 1024. A
ftlggvény hivásakor a bemeneti paraméternek értéket kell adni, kivéve, ha alapértelmezett
értéket definiáltunk a paraméternek a filggvény létrehozásakor. Oyenkor azonban híváskor a
paraméter helyén a DEFAULT kulcsszót kell hasmálni, nem lehet a paramétert elhagyni,
ahogy azt a tárolt eljárásoknál tehettük (A tárolt eljárások esetén a paraméter elhagyása is az
alapértelmezett értéket jelentette.). A paraméter nevek a ftlggvényen belüllokálisak.
Paraméter adattípusként bármilyen skalár adattípust megadhatunk, kivéve a timestarop
adattípust és a felhasmáló által definiált adattipusokat
A visszatérési tipus is bármely skalár adattípus lehet, kivéve a következöket text, ntext,
image és timestamp.
Az ENCRYPTION kulcsszó megadása. hasonlóan a tárolt eljárásokhoz, azt jelenti, hogy
a filggvény törzse kódolva lesz.
A SCHEMABINDING kulcsszó megadása azt jelenti, hogy a filggvény hozzá van kötve
azokhoz az adatbázis objektumokhoz, amikre hivatkozik. Ebben az esetben a hivatkozott
objektumokat nem lehet módosítani vagy törölni. A kötés a következő esetekben szünik meg:
• A ftlggvényt kitöröljük.
• A ftlggvényt módosítjuk, és nem adjuk meg a SCHEMABINDING opciót.
Példa skalár fiiggvényre:

176
21.T-SQL fiiggvények Iváncsy Renáta

CREATE FUNCTION semesterconverter (@sem_name char(S))


RETURNS varchar(20)
AS
begin
return case
when substring(@sem_name,S,l) 2
1 1
then substring(@sem_name,l,4) + / +
convert (varchar, ( convert (int, substring (@sem_name, l, 4)) +l))
+ 1
I. felev 1
when substring(@sem_ name,S,l) = l
then
convert (varchar, ( convert (int, substring (@sem_ name, l, 4)) -l))
1
+ 1
/
1
+ substring(@sem_ name,l,4) + 1
II. felev
end
end
A filggvény használata:
SELECT cou_id, ap60.semesterconverter (cou_semestername) FROM
course
Tábla visszatérésü egysoros fiiggvény:
CREATE FUNCTION függvény_név
( [ { @paraméter_név [AS) skalár_adattipus default ] }
[ , ••• n ] ] )
RETURNS TABLE
[ WITH < függvény_opciók> [ [,) ... n] J
[ AS ]
RETURN lekérdezés
A TABLE kulcsszó azt jelzi, hogy a filggvény visszatérési tipusa egy tábla lesz. Ez az
érték a lekérdezés eredmény lesz. Egysoros tábla visszatérésü filggvények esetén nem kell a
visszatérési értéket egy visszatérési változóhoz rendelni.
Példa tábla visszatérésü egysoros filggvényre:
CREATE FUNCTION getCourses (@semname char(S))
RETURNS TABLE
AS
RETURN SELECT cou id, sub id FROM course, subject
WHERE cou semestername = @semname AND cou subjectid sub id
A filggvény hivásának módja:
l select * from ap60.getCourses( 20021 1 1
)

177
21.T-SQL fllggvények lváncsy Renáta

Tábla visszatérésü több soros fiiggvény létrehozása:


CREATE FUNCTION függvény név
( [ { @paraméter_név [AS] skalár_adattípus [ = default J
[ , ••• n ] ) )
RETURNS @visszatérési vváltozó TABLE < tábla típus definíció >
[ WITH < függvény_opciók > [ [,) ... n l l
[ AS l
BE GIN
függvény tt5rzs
RETURN
END
Ahol a tábla_típus_definíció a következöképpen van definiálva:
<tábla tipus definició > :: =
( ( "oszlop_definició l tabla_megkötések } [ , .. • n ] )
A tábla visszatérésü több soros függvények esetén a visszatérési változó egy tábla
változó, ami a lekérdezések eredményét gyüjti össze és tárolja. A függvény törzsében kell
megadni azokat az utasításokat, amivel a táblát feltöltjük. A táblára a RETURNS kulcsszó
mögött megadott nevével tudunk hivatkozni.
A következő lista megadja azokat az utasításokat., amiket használhatunk egy többsoros
függvényben. Azok az utasítások, amik itt nem kerülnek felsorolásra, nem használhatóak:
• Értékadó utasítások.
• Programvezérlő utasítások
• DECLARE utasítások, amik lokális változókat és kurzorokat deklarálnak.
• SELECT utasítások, amik tartalmaznak lokális változónak értékadást is.
• Kurzor kezelő utasítások (DECLARE, OPEN, FETCH, CLOSE, DEALLOCATE).
Csak olyan FETCH utasítás használható, ami az INTO kulcsszó segítségével
változóha teszi a kurzor értékeit.
• A függvényen belüli lokális tábla változók módosítására INSERT, UPDATE és
DELETE utasításokat.
• Kiterjesztett tárolt eljárások hívása. (A kiterjesztett tárolt eljárás DLL, amit az SQL
Server dinamikusan be tud tölteni és futtatni.)
Példa több soros tábla visszatérési értékü fiiggvényre. A függvény bemenete egy O és I 00
közötti szám, amit százalékként értelmez a függvény. A visszatérési tábla egy két oszlopot
tartalmazó tábla, ami azoknak a tanároknak a NEPTUN kódját és nevét tartalmazza, akiknek a
kurzusán a bemeneti százaléknál többen buktak meg. Ha több ilyen kurzus volt, akkor
többször is bekerül az eredmény listába.

178
21.T-SQL filggvények lváncsy Renáta

CREATE FUNCTION getTeachers (@szazalek INT)


RETURNS @selTeacher TABLE
(teaid char(6), tea name VARCHAR(lOO), couid int)
AS
BEGIN
DECLARE cl CURSOR FOR
SELECT tea id, tea lname + 1 1
+ tea fname, ct courseid
FROM teacher, course teacher
WHERE tea id = ct teacherid
AND ct masterteacher = l
DECLARE @teaid CHAR(6), @teaname VARCHAR(l00), @couid INT
OPEN cl
FETCH cl INTO @teaid, @teaname, @couid
WHILE @@FETCH STATUS = 0
BEGIN
DECLARE @hallgatodb FLOAT
DECLARE @egyesdb FLOAT
SELECT @hallgatodb = count(*)
FROM student course
WHERE sc courseid @couid

SELECT @egyesdb = count(*)


FROM student_exam, exam
WHERE sx examid ex id
AND ex courseid @couid
AND sx_grade = l

IF @hallgatodb != O
IF (@egyesdb/@hallgatodb)*lOO > @szazalek
BEGIN
INSERT INTO @selTeacher values
(@teaid,@teaname,@couid)
END
FETCH cl INTO @teaid, @teaname, @couid
END
CLOSE cl

179
21. T -SQL filggvények Iváncsy Renáta

lDe.LLOCATE cl
RETURN
END
A ftlggvény hivása:
l SELECT * FROM getTeachers(20)
21.2.2. A függvéayek módosftáaa

A létrehozott ftlggvényt az ALTER FUNCTION utasilással lehet módosftani. Dyenkor


meg kell adni a teljes filggvény definiciót, m.intha most hoznánk újra létre a filggvényt.

21.2.3. A függvéayek t6rlése

A filggvényt a DROP FUNCTION utasítással törölhetjük:


DROP FUNCTION függvény_ név

!80
22.T-SQL triggerek lváncsy Renáta

22. T-SQL triggerek


A triggerek az SQL Serveren hasonló müködésüek. mint az ORACLE szerveren,
felfoghatóak olyan speciális tárolt eljárásként, amiket a felhasmáló közvetlen nem tud
meghívni, de a definiált eseményre automatikusan lefutnak. A triggerek bizonyos
adatbázisban történö események hatására aktivizálódnak és futnak le. A T-SQL triggere
számos tulajdonságban eltér a PUSQL triggerétöl, így a T -SQL triggereit is részletesen kell
tárgyalni.

22.1. Trigger létrehozása


Az SQL Server 2000 T-SQLrjében triggert csak adatmódosító (DML) utasítás válthat ki.
Dyen szempontból nagyban különbözik az ORACLE triggereitöl, ahol adat definíciós és
egyéb adatbázis eseményre (pl. shutdown, startup stb.) is lehetett triggert definiálni. További
különbség, hogy a T -SQL-ben csak utasitás szin«i triggert lehet definiálni (m.inden utasítás
hatására pontosan egyszer fut le a trigger), sor szintüt nem. A trigger létrehozásának
szintaktikája a következö:
CREATE TRIGGER trigger_ név
ON { tábla l nézet }
[ WITH ENCRYPTION l
{{{FOR l AFTER l INSTEAD OF} { [ DELETE l [ , l [ INSERT l
[ , l [ UPDATE l }
[ NOT FOR REPLICATION l
AS
[ { IF UPDATE ( oszlop )
[ { AND l OR } UPDATE ( oszlop ) 1
[ .. . n l
l IF ( COLUMNS UPDATED ( ) { bitszintú operátor }
módosított_bitmaszk ) -
{ összehasonlitó_operátor } oszlop bitmaszk [ .. . n
} l
sql_utasítás [ ... n 1
} }
Az SQL Serveren a triggereket három szempont szerint lehet csoportosítani:
a) Atriggert kiváltó esemény milyen objektumra van definiálva
Triggert két fajta adatbázis objektumra definiálhatunk. ez a tábla és a nézet.
b) Milyen eseményre fut le a trigger
Az SQL Serveren táblára vagy nézetre három esemény van definiálva, amire
triggert lehet futtatni. Ezek az események az adat beszúrás (INSERT), az adat
módosítás (UPDATE) és a sor törlés (DELETE). Ezek az események mind táblára,

181
22.T-SQL triggerek Iváncsy Renáta

mind nézetre definiálva vannak. A trigger létrehozásakor legalább egy eseményt meg
kell adni.
c) Az eseményhez képest a trigger időben mikor fut le
A trigger lefuthat a triggert kiváltó esemény után (AFfER vagy FOR. a kettő

teljesen megegyezik) vagy helyette (INSTEAD OF). A T-SQL-ben nincsen BEFORE


trigger! AFfER triggert csak táblára lehet definiálni. (Tehát nézetre csak INSTEAD
OF triggert lehet definiálni.) INSTEAD OF triggert egy táblára vagy nézetre
beszúrásonként, törlésenként illetve módosításonként maximum egyet lehet definiálni .
Tehát nem lehet például definiálni egy táblára két INSTEAD OF INSERT, vagy két
INSTEAD OF DELETE vagy két INSTEAD OF UPDATE triggert, viszont akárhány
AFfER trigger definiálható azonos eseményre is.
Az AFfER trigger az esemény után fut le, miután minden fajta korlátozás és
integritási kérdés tisztázva lett. Az INSTEAD OF trigger az esemény helyett fut le,
még mielőtt bármifajta vizsgálat a korlátozásokra és integritásokra megtörtént volna.
A WITH ENCRYPTION opció azt jelenti, hogy a trigger scriptjét kódolva tárolja el a
szerver. A NOT FOR REPLICA TION kulcsszó megadása azt jelenti, hogy a triggemek nem
kelllefutnia, ha egy repli.kált folyamat módositja a tábla adatait
A triggerben az AS kulcsszó után lehet megadni azokat a T-SQL utasításokat, amiket a
definiált esemény hatására le szerelnénk futtatni .
A trigger törzsében több speciális eszköz áll a programozó rendelkezésére, amelyek
segitségével az eseményben résztvevő adatokról nyerhet információt. Az egyik ilyen
lehetőség az IF UPDATE (oszlop_név) szerkezet, ahol az UPDATEO filggvény TRUE-val tér
vissza, ha az adott oszlop módosult. Ezt a szerkezetet DELETE trigger esetén nem lehet
használni, INSERT trigger esetén pedig az összes oszlopra TRUE-val tér vissza, hiszen vagy
új értéket kapott az adott oszlop, vagy az új NULL értéket. Az oszlop megadásakor a tábla
nevét nem kell megadni, hiszen a trigger deklarációjában az ON kulcsszó után már megadtuk,
hogy melyik táblával dolgozunk. Ha több oszlopra szerelnénk az UPDTAEO filggvényt
használni, akkor minden egyes oszlopra külön meg kell hivni a fiiggvényt. Az UPDATEO
filggvényt a trigger törzsének bármely részén lehet használni.
A másik módja a módosított oszlopokról információt szerezni az INSERT és UPDATE
triggerek esetén az IF (COLUMNS_UPDATEDO) szerkezet használata. A
COLUMNS_UPDATEDO fiiggvény visszatérési értéke egy bitsorozat (varbinary), amely az
egyes oszlopokat reprezentálja, és értéke egy, annál az oszlopnál, ami módosítva lett. A
bitsorozat legfelső bitje tartozik a tábla első oszlopához, a második legmagasabb helyértéken

182
22.T-SQL triggerek lváncsy Renáta

található bit tartozik a táblázat második oszlopához, és így tovább. A ftlggvény eredménye
egy egész számként megadott bitmaszkkal (módosítonbit_maszlc) maszkolható egy bit szintü
operátor (bitszintű_operátor) segitségével, és a kapott eredményt egy összehasonlító
operátorral összehasonlíthatjuk egy kívánt bitmintával (egész számként megadott érték).
A harmadik módja az eseményben részt vevő adatokról információt nyerni a deleted és az
inserted táblák használata. Ezeket a táblákat a szerver automatikusan hozza létre, és a
memóriában tárolja, amig a trigger aktiv. Mindkét tábla struktúrája megegyezik annak a
táblának a struktúrájával, amire a triggert definiáltuk, tehát ugyanazok az oszlopok,
ugyanabban a sorrendben szerepeinek benne. Az inserted táblából az éppen beszúrt adatokat
lehet elérni, míg a deleted táblából az éppen kitörölt adatokat lehet kinyerni. Mivel az SQL
Server triggerek utasítás triggerek, így figyelni kell arra, hogy mind az inserted mind a
deleted tábla több sort is tartalmazhat, így pontosan úgy kell kezelni öket, mint egy táblát
(JOIN). Amennyiben egyesével szecetnénk ezeket az információkat feldolgozni, érdemes
kurzort definiálni a táblák bejárására.
Egy táblára több triggert definiálhatunk ugyanarra az eseményre. A triggerek futási
sorrendje véletlenszerű lesz, kivéve az elsőt és az utolsót, mert az sp_settriggerorder tárolt
eljárással be lehet állítani egy triggert, hogy az legyen az első, ami lefut, és egy triggert, hogy
az legyen az utolsó ami lefut.
Megkötések, korlátozások triggerekre:
• A CREATE TRI GG ER utasitásnak a hatchen belül az első utasításnak kell lennie, és a
batch összes utasítása hozzá tartozik.
• Egy triggert csak egyetlen táblára lehet definiálni.
• A trigger csak az aktuális adatbázisban kerül létrehozásra, de hivatkozhat más
adatbázisbeli objektumokra is.
• Egy triggert több eseményre is definiálhatunk ugyanabban a CREATE TRI GG ER
utasításban.
• INSTEAD OF DELETFJUPDATE trigger nem definiálható olyan táblákra, amire
olyan idegeokules lett definiál va, ami kaszkádosítva lett (ON UPDATE CASCADE,
ON DELETE CASCADE).
• A trigger futása során, hasonlóan a tárolt eljárásokboz, eredménnyel térhet vissza. Ez
általában ketillendö, ezért kerülni kell a lekérdezéseket a triggerben, ami eredménnyel
tér vissza a felhasználó felé.

183
22.T-SQL triggerek Iváncsy Renáta

22.2. Trigger módosítása


Triggert módosítani az ALTER TRI GG ER utasítással lehet, majd meg kell adni a
módosított trigger teljes definícióját.

22.3. Trigger törlése


Triggert törölni a DROP TRIGGER utasítással lehet.
DROP TRIGGER { trígger_név) [ ... n)
A trigger akkor is törlődik., ha töröljük azt a táblát, amire definiálva lett.

184
23.T-SQL tranzakciók Iváncsy Renáta

23. T-SQL tranzakciók


A jegyzet első felében, a PUSQL anyagrész tárgyalásakor megnéztük, hogy mi a
tranzakció, milyen tulajdonságokkal rendelkezik, és hogy milyen problémák merülhetnek fel,
ha konkurensen futó tranzakciók azonos táblában vagy sorban levő adatokat szeremének
módosítani (piszkos olvasás, nem megismételhető olvasás, fantom olvasás). Természetesen
ezeknek a problémáknak a kiküszöbölésére az SQL Serverben is figyelmet fordítottak. Az
alábbiakban azt tekintjük át, hogy milyen módon müködik az SQL Server a tranzakció
kezelés szempontjábóL Feltételezzük, hogy az olvasó már tisztában van a tranzakció kezelés
alapjaivaL

23.1. Tranzakciómódok
Az SQL Serveren három tranzakciómód létezik:
• Autokommit tranzakció: minden egyes utasítás egy tranzakció.
• Explicit tranzakció: minden egyes tranzakciót explicit el kell indítani a BEGIN
TRANSACTION utasítással, és be kell fejezni a COMMIT vagy a ROLLBACK
utasltásokkal.
• Implicit tranzakció: Egy új tranzakció indul, amint egy előző befejezödött, de
minden tranzakciót explicit be kell fejezni a COMMIT vagy a ROLLBACK
utasításokkal (ez hasonlít a leginkább az Oracle tranzakció módjára).
Az SQL Server alapértelmezésben az autokommit tranzakció módban müködik. Ebben az
esetben minden egyes utasítás egy különálló tranzakció. Explicit tranzakció módba úgy
válthatunk. ha kiadjuk a BEGIN TRANSACTION utasítást. Implicit tranzakciós módba a
SET IMPLICIT_TRANSACTIONS utasítással válthatunk. Ennek szintaktikája a következő :
SET IMPLICIT_TRANSACTIONS {ON l OFF}

23.2. Az explicit és az implicit tranzakciók


A tranzakciókat egymásba is lehet ágyazni. A @@TRANCOUNT a nyitott tranzakciók
számát jelöli.

23.2.1. A REGIN TRANSACTION


Explicit tranzakció esetén a tranzakciót a BEGIN TRANSACTION utasítás jelzi egy
tranzakció kezdetét. Ekkor a @@TRANCOUNT értéke egyel nö. A tranzakciónak nevet is
lehet adni.

185
23 .T-SQL tranzakciók Iváncsy Renáta

BEGIN TRAN [ SACTION J [ transaction name


@tran name variable
[ WITH MARK [ 'description' J ] ]
A WITH MARK.Irulcsszóval az adható meg, hogy a tranzakció bekerüljön a log-ba.

23.2.2. A COMMIT TRANSACTION

A COMMIT TRANSACTION utasítással véglegesíthetjük a tranzakcióban végrehajtott


utasításokat. Ekkor a @@TRANCOUNT értéke eggyel csökken.
COMMIT [ TRAN [ SACTION J [ transaction_ name
@tran_ name_variable J ]
Amennyiben a @@TRANCOUNT értéke O a COMMIT előtt. akkor hibaüzenetet
kapunk, miszerint nincsen tranzakció kezdete utasítás az adott COMMIT utasításhoz.

23.2.3. A SA VE TRANSACTION

Biztonsági pontot a tranzakción belül a SA VE TRANSACTION utasítással tehetünk.


SAVE TRAN [ SACTION ] { savepoint_name 1 @savepoint_variable
A savepoint_name a biztonsági pont neve. A név maximum 32 karakter hosszú lehet. A
@savepoint_variable egy felhasználó által definiált változó, ami a biztonsági pont nevét
tartalmazza.

23.2.4. A ROLLBACK TRANSACTION

Egy explicit vagy implicit tranzakciót fejt vissza a tranzakció kezdetéig vagy a
tranzakción belüli biztonsági pontig.
ROLLBACK [ TRAN [ SACTION
[ transaction_name l @tran name __ variable
l savepoint_name l @savepoint_variable J
A transaction_name a tranzakció nevét adja meg, amihez a BEGIN TRANSACTION
tartozik. Ha egymásba ágyazott tranzakciók vannak, akkor a legkülső tranzakció nevét kell
megadni. A savepoint_name annak a biztonsági pontnak a neve, ameddig a tranzakciót vissza
szeretnénk fejteni.
Ha nincsen megadva sem tranzakció név, sem biztonsági pont név, akkor a legkülső

tranzakció kezdetéig fejtődik vissza a tranzakció. Ha két azonos nevű biztonsági pont van egy
tranzakcióban, akkor a ROLLBACK a legutolsó biztonsági pontig fejtődik vissza.
Ha a visszafejtés egy biztonsági pontig történik, akkor a zárolások nem kerülnek
felszabadításra.

186
23.T-SQL tranzakciók Iváncsy Renáta

23.3. Izolációs szintek


Az SQL Server mind a négy standard izolációs szintet implementálta. A szinteket a SET
TRANSACTION ISOLATION LEVEL utasítássallehet állítani:
SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
l READ UNCOMMITTED
l REPEATABLE READ
l SERIALIZASLE
}
Ha az izolációs szintet átállítottuk, az a kapcsolat végéig fennáll, mindaddig, mig át nem
állítjuk ismét.

23.4. Zárolások
A különbözö zároJási típusok az SQL Server 2000 esetén:
Zárolási mód Leírás
Osztott (shared) Csak olvasható müveletek:re hasmálatos, mint pl. a SELECT.
Módosító (update) Olyan erőforrásokra használatos, ami módositható.
Kizárólagos Kizárólagos jog, INSERT, UPDATE és DELETE utasítások esetén.
(exclusive) Biztosítja, hogy többen nem módosithatják egyszerre ugyanazt az
adatot.
lnten t ZároJási hierarchia kialakítására hasmálatos. Különbözö módjai:
intent shared, intent exclusive, és shared intent exclusivval.
Séma (schema) Akkor hasmálatos, ha a müvelet a végrehajtandó tábla sémájától
függ.
Bulk Update Táblába tömeges adatmázolás esetén hasmálatos, ha a T AB LOCK
zárolás meg van adva.
.. .
A zárolást módok kompabbtiltást mátnxa:
Létez6w
Kért úr IS s u IX SIX x
IntentsharedOS) I I I I I N
Shared (S) I I I N N N
Update (U) I I N N N N
Intent Exclusive (IX) I N N I N N
Shared with lntent Exclusive (SIX) I N N N N N
Exclusiv@ N N N N N N
A táblazárolást ttppek (table lock hmts) segitségével felülírhatók az aktuáhs tzoláctós
szint szabályai az adott tábla esetén. A táblazároJási tippeket a SELECT, INSERT, UPDATE
vagy DELETE utasításokkal lehet kiadni. A következő táblázat összefoglalja a táblazároJási
tippeket:
Zárolás Le fr ás
HOLDLOCK A tranzakció végéig megosztott zárat tart fenn.
NO LOCK Nem ad ki osztott zárat és nem vesz figyelembe kizárólagos zárat.
Csak SELECT utasítás esetén hasmálható.

187
23 .T-SQL tranzakciók Iváncsy Renáta

PAG LOCK Lapot zárol, amikor alap esetben tábla lenne zárol va.
READCOMMmED A READ COMMilTED izolációs szintnek megfelelő zárolást
használ.
READPAST Kihagyja azokat a sorokat, amiket más tranzakció zárol, ahelyett,
hogy megvárná, míg a másik tranzakció elengedi. Csak SELECT
esetén használható.
READUNCOMMITfED Megegyezik a NOLOCK-kal.
REPEATABLEREAD A REPEATABLE READ izolációs szintnek megfelelő zárolázi
mechanizmust használja.
ROWLOCK A tábla vagy lap szintü zárolás helyett sor szintü zárat ad ki.
SERIALIZABLE Megegyezik a HOLDLOCK-kaL
TABLOCK Tábla szintü zárolást tart fenn a sor vagy a lap szintü zárolás
helyett. A zár az utasítás végéig marad fenn, de ha együtt
használják a HOLDLOCK-kal, akkor a tranzakció végéig.
TABLOCKX Kizárólagos zárat hasmái a táblára. Meggátolja, hogy más
tranzakció olvassa, vagy módosftsa a táblát, az utasítás vagy a
tranzakció végéig tart.
UPOLOCK Módosító zárat használ az osztott zár helyett. A zárat az utasítás
vagy a tranzakció végéig tartja fenn. Azért hasznos, mert úgy
olvashatjuk az adatot, hogy közben mások is olvashatják, hogy
aztán késöbb módosítsuk, és biztosak lehetünk benne, hogy
közben az adat nem módosult.
XLOCK Kizárólagos zárat tesz a tranzakció általhasznált összes adatra a
tranzakció végéig. PAOLOCK-kal vagy TABLOCK-kal
használható, ezzel állítva be, hogy m.ílyen szintü legyen a zárolás.
A zárolást az egyes utasításokban a tábla neve után kell megadni a WITH kulcsszó után
zárójelben. PL.
l SELECT oszlopnév FROM tábla WITH (TABLOCKX) WHERE ....

23.5. Holtpont kezelése


Holtpont akkor alakulhat ki, ha a tranzakciók zárolva tartanak adatbázis objektumokat,
miközben olyan objektum zárolására várnak, amit egy másik, szintén várakozó tranzakció tart
fogva. A tranzakciók körben várakoznak egymásra, patt helyzet alakul ki.
A holtpontot az SQL Server egy "lock monitor" nevü folyamat segítségével detektálja. A
folyamat periodikusan felébred, és az olyan tranzakciók esetén, amik már egy meghatározott
időnél tovább várakoznak, el kezdi keresni a holtpontot Mivel a holtpontok kialakulásának
gyakorisága kicsi egy rendszerben, így a periodikus holtpont kereséssel csökkenthető a
keresési overhead. A holtpont megtalálása után az SQL Server megszünteti a holtpontot egy
tranzakció megszakításávaL A tranzakciót visszafejti, a többi tranzakciót pedig hagyja tovább
futni . Tipikusan olyan tranzakciót választ, amínek a visszafejtésének a költsége a legkisebb. A
másik módszer, hogy a felhasználó a SET DEADLOCK_PRIORITY LOW utasítással a
kapcsolat prioritását alacsonyra állítja, így holtpont kialakulása esetén az adott kapcsolatban

188
23.T-SQL tranzakciók lváncsy Renáta

futó tranzakció kerül megszakításra. A prioritást a NORMAL kulcsszó használatával lehet


visszaállítani az eredeti szintjére.
SET DEADLOCK_ PRIORITY { LOW l NORMAL l @deadlock_var

23.6. A hatékony tranzakció készítés szabályai


Egy tranzakciónak a lehető legrövidebbnek kell lennie, annak érdekében, hogy a
zárolásokkal és egyéb foglalt erőforrásokkal az egyéb tranzakciókat minél kevésbé
hátráltassa.
A hatékony tranzakció készitésének szabályai:
• A tranzakció alatt nem szabad felhasználótól adatot bekémi. A felhasználó válasza,
még ha azonnal válaszol is, nagyságrendekkel lassabb a sebessége, mint a számítógép
sebessége. Abban az esetben, ha mégis szükség lenne a felhasználótól információra.
akkor a tranzakciót vissza kell fejteni, a hiányzó adatot be kell kémi, és a már
rendelkezésre álló adatokkal újra kell indítani a tranzakciót.
• Ne indítsunk tranzakciót, míg az adatok közt keresünk.
• Legyen a tranzakció a lehető legrövidebb
• Használjuk az alacsonyabb izolációs szinteket, ha az is elegendő, ezzel növelhető a
párhuzamosan futó tranzakciók száma.
• A tranzakció alatt a lehető legkevesebb adathozzáférés legyen. Minél kevesebb adattal
dolgozunk, annál kevesebb zárra van szükség.

189
24.T-SQL hibakezelés lváncsy Renáta

24. T-SQL hibakezelés

24.1. A hiba szerkezete


Az SQL Server által generált hibák a következö attribútumokkal rendelkeznek:
• Hibaszám: minden egyes hibának egyedi hibaszáma van.
• Hiba ilzenet: a hibaüzenet megadja a hiba keletkezésének okát. Minden hibaszám
egyedi hibaüzenettel rendelkezik.
• Hiba fontossága (severity): a hiba fontossága azt adja meg, hogy mennyire komoly
az adott hiba. Ha ez az érték alacsony, mint például l vagy 2, akkor a hiba
alacsonyszintü, figyelmezletö hiba, míg magas érték esetén olyan hiba, amit azonnal
kezelni kell.
• Állapot kód: egy hibát több helyen is generálhat az SQL Server. A különbözö
helyeken keletkezett hibák különbözö állapot kóddal rendelkeznek. Az állapot kód
segítségével könnyebben lehet lokalizálni a hibát.
• Eljárás név: ha a hiba egy tárolt eljárásban generálódott, akkor az eljárás neve is
elérbetö.
• Sonzám: a sor száma azt adja meg, hogy az eljárásban melyik utasítás okozta a hibát.
Az SQL Server hibák a master.dbo.sysmessages rendszerlábiában vannak eltárolva. A
felhasználó által definiált hibák is a sysmessages táblában kerülhetnek eltárolásra.

24.2. A sysmessages tábla


A sysmessages táblában minden rendszer hibához vagy figyelmeztetéshez egy sor
tartozik. A rendszer hibákon kívül tartalmazhat felhasználó által definiált hibákat is, amit az
sp_addmessage rendszer tárolt eljárással adhatunk hozzá, és az sp_dropmessage rendszer
tárolt eljárással távolíthatunk el.

24.3. Az sp_addmessage
Az sp_addmessage tárolt eljárást csak a sysadm.in vagy serveradm.in szerepekhez
tartozó felhasznáJók futtathatják le. Ennek segítségével adható egy hiba üzenet a sysmessages
táblához.
sp_addmessage ( @msgnum = l msg_ id ,
@severity = l severity ,
@msgtext = l 'msg'
, [ @lang = J 'language•

190
24.T-SQL hibakezelés lváncsy Renáta

[ , [ @with_log = l 'with_log' l
[ , [ @replace = l 'replace' l
A tárolt eljárás paraméterei a hiba azonosítója, aminek értéke 5000 1-töl kezdödhet. Ennek
alapértelmezett értéke NULL A második paraméter a hiba fontossága, aminek értéke l és 25
között lehet, alapértelmezett értéke NULL. A harmadik paraméter a hiba szöveges üzenete. A
negyedik paraméter a nyelv. Ha nem adunk meg nyelvet, a kapcsolat alapértelmezett nyelve
lesz a hiba nyelve. A hibának a nyelvének és az azonosítójának együtt egyedinek kell lennie.
A következő paraméter azt adja meg, hogy a hiba bekerüljön-e a log fájlba.
Alapértelmezésben FALSE az értéke. Dyenkor nem minidig kerül be a log fájlba, csak akkor,
ha a hiba úgy generálódott. TRUE érték esetén mindenképp bekerül a log fájlba. Ha a hatodik
paraméter a REPLACE kulcsszó, akkor a hiba felülúja a táblában ilyen azonosítóval
rendelkező hibát.

24.4. Az sp_altermessage
A sysmessages táblában található hiba állapotát változtathatjuk meg vele. Csak sysadmio
vagy serveradmin jogosultsággal hívható meg.
sp __al termessage [ @message_ id = l message _number
, [ @parameter = l 'write_ to_log'
, [ @parameter_value = l 'value'
A message_number a módosítandó hiba hibaszáma. A második paraméter mindig
WITH_LOG kell, hogy legyen. Ha a value értéke TRUE, a hibamindig bekerül a Windows
NT log-jába, ha FALSE, akkor a hiba generálásától filggöen kerül be a log-ba.

24.5. Az sp_dropmessage
Kitöröl egy megadott hibát a sysmessages táblából. Csak sysadmin vagy serveradmín
jogosultsággal hívható meg. Mivel a táblában egy hibát az hibaszáma és a nyelv együtt
határoz meg, igy törlésnél is ezt a két paramétert kell megadni:
sp dropDessaqe [ @. . gnWil • l message number
- [ , [ @lanq = l 'language' l -

24.6. A FORMATMESSAGE
A FORMATMESSAGE a sysmessages tábla üzenetét formázza meg. Funkcionalitása
megegyezik a RAISERROR használatával, annyi különbséggel, hogy míg a RAISERROR az
üzenetet azonnal ki úja, addig a FORMATMESSAGE visszatér a módosított üzenettel további
felhasználásra.
FORMATMESSAGE msg_ number, param_value [ , ... n l )

191
24.T-SQL hibakezelés Iváncsy Renáta

A fllggvénynek meg kell adni a formázandó hiba hibaszámát., majd a paramétereket, amik
a szimbólumok helyére kerülnek.

24.7. A @@ERROR függvény


A @@ERROR rendszer fllggvény visszatérési értéke O, ha a legutoljára végrehajtott
utasítás sikeres volt, ha az utasítás végrehajtása során hiba lépett fel, a @@ERROR a
hibaszámmal tér vissza. Mivel a @@ERROR minden egyes utasítás után új értéket kap, igy
minden egyes utasítás után meg kell vizsgálni az értékét., ha fel aka.Jjuk használni. Másik
lehetőség, hogy elmentjük egy változóha az értékét, és így a vizsgálatot késöbb is
elvégezhetjük.
A Microsoft SQL Server 2000-ben tárolt eljárásból, batch-böl és triggerböl csak a
@@ERROR fllggvény érhető el, a hiba többi része, mint az üzenet, a fontossága, az eljárás
neve stb., csak a k.liensalkalm.azásban, az API hibakezelő mechanizmusa segitségével érhető

el.
A @@ERROR csak hiba esetén generálódik. figyelmeztetések esetén nem.
A @@ERROR szokásos használata a tárolt eljárás sikerességének vagy hibájának jelzése.
A tárolt eljárás minden egyes utasitása után megvizsgáljuk a @@ERROR értékét, és amikor
az nem nulla, eltároljuk egy nullára inicializált változóban. Az eljárás a változóval tér vissza.
Ha a tárolt eljárás utasításaiban nem volt hiba, a változó értéke nulla marad, ha volt benne
hiba, az utolsó hiba számát tartalmazza.
A @@ERROR használatát kiegészítheti a @@ROWCOUNT függvény használata, ami
azt adja meg, hogy az utolsó utasítás hány sort érintett.

24.8. A RAISERROR
A RAISERROR segítségével kétféleképpen küldhetünk hibaüzenetet az alkalmazásnak:
• Egy felhasználó által definiált hibaüzenetet, amit korábban az sp_addmessage tárolt
eljárással a sysmessages táblához adtunk.
• A RAISERROR utasításban megadott hibaüzenetet.
A RAISERROR a hibaüzenelen kívül hibaszámot, fontosságot és állapotot is rendel a
hibához. Ezen kívül lehetőség van arra, hogy a RAISERROR által generált hiba a Microsoft
SQL Server log-ban ketilljön eltárolásra.

192
24.T-SQL hibakezelés lváncsy Renáta

A RAISERROR szintaktikája:
RAISERROR ( { msg_ id l msg_ str } { 1 severity , state }
[ , a rgumen t [ , . . . n l l )
[ WITH option [ , .. . n l l
Az msg_id a felhasználó által definiált hiba, ami a sysmessages táblában került
eltárolásra. A felhasználó által definiált hibának a hibaszáma nagyobb kell, hogy legyen, mint
50000. Az alkalmi hiba (amit a RAISERROR generál) hibaszáma 50000.
Az msg_str az alkalmi hiba üzenete. Ez az a hiba, amit nem a sysmessages táblából
nyerünk ki, hanem a RAISERROR segítségével a hiba keletkezésekor definiálunk, és küldünk
el az alkalmazás felé. A hiba üzenete 400 karakter hosszú lehet. Ha a hibaüzenet hosszabb,
mint 400, akkor csak az elsö 397 karakter kerül megjelenitésre, és utána egy ellipszis, ami azt
jelzi, hogy az üzenet csonkolva lett. Minden alkalmi üzenetnek az üzenet azonosítója 14000.
Az alkalmi üzenetet, hasonlóan a C nyelv printf filggvényéhez, formattáló karakterek
segítségével formázható. Ennek segítségével a konstans szöveg közé változókat is
befiízhetün.k. A következö formázó szintaktika használható:
% [ [ flagl [widthl [preci si on l [{h l l} ll type
Af/ag meghatározza, hogy a mezöben melyik oldalra legyen rendezve a szöveg, illetve,
hogy milyen módon legyenek benne a szóköz karakterek. A width adja meg a szöveg
minimális szélességét. A precision megadja, hogy mennyi a maximális karakterszám, illetve
hogy mennyi a minimális digitek száma, amit a kimenetre kür. A különbözö típusú adatok
kiírására a következő szimbólumok szolgálnak:
Karakter tipus Jelentés
d vagy I Elöjeles integer szám.
o Elöjel nélküli oktális szám.
p Mutató.
s Sztring.
u Elöjel nélküli integer szám.
X vagy x Elöjel nélküli hexadecimális szám.
A severity határozza meg a htba fontosságát. Mmden felhasználó O és 18 értékig
határozhatja meg a hibaüzenet fontosságát. 19 és 25 közötti értéket olyan felhasznáJók
adhatnak a hibáiknak, akik sysadmin szerver szerephez tartoznak. A 19.. 25 mértékhez a
WITH LOG opciót meg kell adni.
A state a hiba állapotát jelenti, 1.. 127 lehet az értéke.
Az argument azok a paraméterek. amik a hiba üzenet részében szimbolikusan, a formázó
karakterek segítségével lettek helyettesítve. Ez lehet akár az aktuális hibaüzenet (msg_str)
vagy az msg_id által meghatározott üzenet a sysmessages táblában. A paraméterek száma O és
20 között lehet.

193
24.T·SQL hibakezelés Iváncsy Renáta

Az option a hiba opcióját határozza meg. A következő opciók megadása lehetséges:


Opció Jelentés
LOG A hiba bekerül a szerver hiba log-ba és az alkalmazás log-ba.
NOWAIT A hibát azonnal elküldésre kerül a kliens felé.
SETERROR A @@ERROR értékét az msg_id-ra vagy 500000-re állítja, ftlggetlenül a hiba
fontosságától.
Ha egy h1ba keletkezik, a hiba száma bekerül a @@ERROR ftlggvénybe, amJ a
legutoljára generált hiba számát tartalmazza. A @@ERROR értéke O akkor, ha a hiba
fontossága Oés l Oközé esik.
Példa a RAISERROR használatára: aktuális hiba küldése
DECLARE @DBID INT
SET @DBID = DB_ID()
DECLARE @DBNAME NVARCHAR(l28)
SET @DBNAME DB NAME()
RAISERROR
(' Az aktuális adatbázis azonosító:%d, az adatbázis név:
%s. ',
16, l, @DBID, @DBNAME)
Egy a felhasználó által előre definiált hiba generálása:
sp_addmessage 50005, 16,
'Az aktuális adatbázis azonosító:%d,az adatbázis név: %s.'
GO
DECLARE @DBID INT
SET @DBID = DB_ID()
DECLARE @DBNAME NVARCHAR(l28)
SET @DBNAME = DB_NAME()
RAISERROR (50005, 16, l, @DBID, @DBNAME)
GO

194
2S.SQL Sc:rver 2005 újdonságok lváncsy Rc:náta

25. SQL Server 2005 újdonságok


A jegyzet eddigi részében az SQL Server 2000-el foglalkoztunk. ami egészen 2005 öszéig
a legeltetjedtebben használt Microsoft SQL Server volt. Ezen fejezetben a Microsoft SQL
Server legújabb változatáról, az SQL Server 2005-röl lesz szó, ami 2005 öszén jelent meg, és
számos újítást tartalmaz a korábbi verzióhoz képest. Ebben a fejezetben csak a szerver oldali
programozást érintő kérdéskörrel foglalkozunk, egyéb információk a [12] irodalomban
található.
Az SQL Server 2005 számos fontos helyen továbbfejlesztette a T-SQL nyelvet:
• Új adattipust vezetett be, mint az XML adattipust, illetve nagy objektumok
tárolására szolgáló adattipusokat.
• Új, továbbfejlesztett nyelvi elemeket vezetett be, ami többek között támogatja a
rekurzív lekérdezést is.
• Bevezette az adatdefinfciós (DDL) triggereket. Az SQL Server 2000-ben csak
DML triggerek léteztek.
• Különbözö katalógus nézeteket definiált, aminek segitségével a metaadatok
érhetőek el.

25.1. Új adattípusok
Az SQL Server 2005 bevezette az XML adattipust, és nagy értékek tárolására szolgáló
adattipusokat (large value data types).
Az XML adattípus XML dokumentumok és XML dokumentum darabokat képes tárolni
oszlopként, változóként, paraméterként vagy fiiggvény visszatérési értékeként Az XML
adattípussal össze lehet rendelni egy séma leírást, ami validálja az adott dokumentumot. Az
XML adattípusokat az XQuery nyelv segitségével és XML adatmódosító utasításokkal (XML
DML) kezelhetjü.k. Az XML DML az XQuery kitetjesztése insert, delete és repiace value of
utasításokkal.
A nagy adatok tárolására szolgáló új adattipusok a varchar(max), az nvarchar(max) és a
varbinary(max). Az SQL Server 2000-ben ezek helyett a varchar(n), nvarchar(n) és a
varbinary(n) volt használható, ahol n a maximális tárolási kapacitást defmiálta, aminek értéke
8000 byte lehetett varchar és varbinary típusok esetén és 4000 byte az nvarchar esetén. Ha
ennél nagyobb adatokat szerenünk volna tárolni, akkor LOB tipusú objektumokat kellett
használni, mint a text, ntext és image. Ezek azonban korlátozott kezelési lehetöségekkel
rendelkeznek. Az új adattípusok bevezetésével lehetőség van nagy szöveges és bináris

!95
25.SQL Server 2005 újdonságok lváncsy Renáta

adatokat tárolni és kezelni pontosan olyan módon, ahogy a kisebb verziójukat (például a
varchar(max)-ra és az nvarchar(max)-ra használhatóakasztring kezelő műveletek is).

25.2. T-SQL nyelvi fejlesztések


A T-SQL fejlesztések a következők, amelyek közül ebben a jegyzetben csak néhány
fontosat tárgyalunk részletesen:
• A TOP klauzula használható kifejezéssel is.
• A T ABLESAMPLE klauzula az eredményhalmaz egy véletlen részhalmazával tér
vissza.
• Az OUTPUT klauzula segítségével lehetőség van az INSERT, UPDATE és
DELETE utasítások által érintett sorokat eredményhalmazként visszanyerni.
• Az általános tábla kifejezések (Common Table Expression, CTE) segítségével
lehetőség van átmenetileg elnevezett eredményhalmazokat kezelni, ami igen
hasznos lehet például rekurzív lekérdezések megfogalmazásakor.
• Az új SOME, ANY és ALL operátorok segítségével lehetőség van egy oszlop
értékeit egy skalár értékkel összehasonlítani.
• Az APPL Y operátor segítségével lehetőség van egy eredményhalmaz minden
egyes sorára végrehajtani egy tábla értékű filggvényt.
• Az EXECUTE AS klauzula segítségével meghatározható, hogy a tárolt eljárás,
filggvény vagy trigger milyen jogosultságokkal fusson.

25.2.1. TOP

A TOP klauzula használatával lehetőség van egy lekérdezés első meghatározott sorát
megkapni. Az SQL Server 2000-ben a sorok számát csak konstansként lehetett megadni. Az
SQL Server 2005-ben már lehetőség van kifejezésként meghatározni a sorok számát. A TOP
klauzula szintaktikája a következő:
TOP (kifejezés) [PERCENT] [WITH TIES)
A kifejezés határozza meg, hogy hány sorral térjen vissza a lekérdezés, illetve a sorok
hány százalékával. Amennyiben a kifejezés nem konstans, a zárójeleket nem lehet elhagyni.
Százalékos értéket úgy lehet megadni, ha az opcionális PERCENT kulcsszót is kitesszük a
lekérdezés ben.
A WITH TIES opcióval a következő eset valósítható meg. Ha a lekérdezés tartalmaz
ORDER BY kifejezést. akkor lehetőség van arra, hogy a lekérdezés a TOP kifejezésében

1%
25.SQL Server 2005 újdonságok Iváncsy Renáta

meghatározott sorok számánál többel térjen vissza, ha ezek a többlet sorok azon oszlopa, ami
alapján rendeztünk, megegyezik az utolsó sor értékéveL

25.2.2. OUTPUT
Az OUTPUT ldauzula segítségével lehetőség van visszakapni azokat a sorokat, amiket az
INSERT, UPDATE vagy DELETE utasítások érintettek.
Az alábbiakban a három utasítás egyszerűsített szintakti.kája található, ahol a lényeg az
OUTPUT használatán van.
INSERT INTO táblanév (oszlopok_ listája) OUTPUT kifejezés
VALUES értékek

DELETE FROM táblanév OUTPUT kifejezés WHERE feltétel

UPDATE táblanév SET oszlop = érték OUTPUT kifejezés FROM


táblák WHERE feltétel

Az OUTPUT kulcsszó után meg kell határozni, hogy mely oszlopok értékeivel szeretnénk
visszatérni. Amennyiben ezen kívül mást nem határozunk meg, akkor az érintett sorok
eredményhalmazként kerülnek a kliens felé. Lehetőség van azonban ezeket a sorokat egy
tábla típusú változóha vagy egy átmeneti táblába tenni az INTO kulcsszó segitségével.
Az érintett sorok oszlopainak a kiválasztására a DELETED és az INSERTED prefix
használata szolgál. A DELETED prefixet DELETE vagy UPDATE esetén lehet használni, és
a kitörölt adatokat tartalmazza. Az INSERTED prefix INSERT és UPDATE utasítások esetén
használható, és az új adatokat tartalmazza.
Az alábbi példában definiálunk egy tábla típusú változót, majd egy módosító utasítással
csökkentjOk a l 00 forintnál olcsóbb termékek árát l 0%-kal. Az érintett sorokból az anyag
nevét, régi és új árát az átmeneti táblába töltjük. A szkript utolsó lekérdezésében pedig
felhasználjuk ezt a tábla változót, hogy a 30 forintnál olcsóbb anyagok régi és új árát
lekérdezzük.

197
25.SQL Server 2005 újdonságok Iváncsy Renáta

declare @tabla table(nev varchar(lOO),


regiar float,
ujar float)
update anyag set anyag egysegar anyag egysegar * 0.9
output inserted.anyag_nev,
deleted.anyag_egysegar,
inserted.anyag_egysegar
INTO @tabla
where anyag egysegar < 100

select * from @tabla where ujar < 30

25.2.3. EXECUTE AS

Az EXECUTE AS klauzula segítségével megadható, hogy milyen jogosultságokkal


fusson egy tárolt eljárás, egy tárolt függvény vagy egy trigger.
Az EXECUTE AS szintaktikája függvény, eljárás és DML trigger esetén:
EXECUTE AS {CALLER l SELF l OWNER l 'user name'}
Az EXECUTE AS szintaktikája adatbázis hatókörrel rendelkezö DDL trigger esetén:
EXECUTE AS {CALLER l SELF l 'user name'}
Az EXECUTE AS szintaktikája szerver hatókörrel rendelkező DDL trigger esetén:
EXECUTE AS {CALLER l SELF l 'login name'}
Ahol az egyes kulcsszavak a következőket jelentik:
CALLER
A modul belsejében található utasítások a modul hívójának jogosultságaival futnak. Ez az
opció az alapbeállftás minden emlitett modul esetén.
SELF
A modul belsejében található utasítások a modul létrehozójának vagy módosítójának
jogosultságaival futnak.
OWNER
A modul belsejében található utasítások a modul tulajdonosának jogosultságaival futnak.
'user_name'
A modul belsejében található utasítások az itt meghatározott felhasználó jogosultságaival
futnak.

!98
25.SQL Server 2005 újdonságok lváncsy Renáta

'login_name'
A modul belsejében található utasítások az itt meghatározott login jogosultságaival
futnak.

25.3. Hibakezelés
Az SQL Server 2000-ben a hibakezelés lényegében hiba dobásának lehetőségére

korlátozódik. ami egy programozási nyelv esetén nem kielégitő. Az SQL Server 2005-ben
ezért bővítették a rendszer hibakezelési lehetőségeit. Az alábbiakban ezt tekintjük át röviden.
Az SQL Server 2005-ben a hibakezelés megvalósításának módja hasonlít a már sokak
által megszokott programozási nyelvekben (C#, C++) megismert hibakezeléshez. Az SQL
utasítások egy csoportját egy TRY blokkba zárhatjuk. és az itt keletkezett hibákat a CATCH
blokkban tudjuk lekezelni. A TR Y-CATCH blokk szintaktikája a következő:
BEGIN TRY
{SQL utasítások sorozata}
END TRY
BEGIN CATCH
{SQL utasítások sorozata}
END CATCH
A TRY-CATCH blokk minden olyan hibát elkap, aminek hiba fontossági értéke
(severity) nagyobb, mint 10, és nem bontja a kapcsolatot. A BEGIN CATCH utasításnak
közvetlen az END TRY utasítást kell követnie, különben szintaktikus hiba keletkezik.
Egy TRY-CATCH blokkra az alábbi megkötések vannak:
• Nem tarthat több hatch-en keresztül.
• Nem tarthat több blokkon keresztül (nem lehet több BEGIN és END benne).
• Nem tarthat IF-ELSE programvezérlő utasításon keresztül sem.
• Nem használható felhasználó által definiált függvényben.
Amennyiben nem keletkezik hiba a TRY részben, akkor a vezérlés közvetlen az END
CATCH utasítás utáni első sorra kerül (ha ez az utolsó sor az eljárásban, akkor az eljárás
visszatér). Amennyiben keletkezett hiba, akkor aBEGIN CATCH blokk első sorára kerül a
vezérlés. A CATCH blokk utasításainak végrehajtása után a vezérlés közvetlen az END
CATCH utáni elsö sorra kerül. A CATCH blokkon belüli elkapott hibák nem térnek vissza a
hívó alkalmazáshoz. Ha mégis valamilyen módon értesíteni szeretnénk a hibáról a hívó
alkalmazást, akkor a RAISERROR vagy a PRINT utasítást kell használni, vagy egy SELECT
utasítással egy eredmény halmazt kell a hívó fél számára biztositani.
A TRY-CATCH blokkok egymásba is ágyazhatóak, vagy a TRY vagy a CATCH blokk
tartalmazhat további blokkokat A GOTO utasítással nem léphetünk be egy TRY-CATCH

199
25.SQL Server 2005 újdonságok Iváncsy Renáta

blokkba, de azon belül használható címkére ugrásra, vagy lehetőség van ennek az utasításnak
a segítségével kiugrani a blokkból.

2S.3.l.lnformáció kinyeréseabibáról
A CATCH blokkban számos rendszer függvény segítségével tudunk információt kinyerni
arról, hogy milyen hiba keletkezett. Ezek a következők:
Függvény neve Visszatérési érték
ERROR NUMBERO A hiba számával tér vissza.
ERROR SEVERITYQ A hiba fontossági számával tér vissza.
ERROR STA TE0 A hiba állapot számával tér vissza.
ERROR_PROCEDUREQ Annak a tárolt eljárásnak vagy triggernek a nevével tér vissza,
ahol a hiba keletkezett.
ERROR LINEO A rutinon belüli sorszámmal tér vissza, ami a hibát okozta.
ERROR MESSAGE() A hibaüzenet teljes szövegét tartalmazza.
Amennyiben a fenti függvényeket nem a CATCH blokkon belül híVJuk meg, visszatérési
értékük NULL.

25.4. DDL triggerek


Az SQL Server 2005-ös verziójában kibővítették a triggerek funkcionalitását. llyen
módon az új verzióban már nem csak DML utasftásokra, de DDL utasításokra is lehet triggert
definiálni. Az alábbiakban megnézzük, hogy milyen lehetőségek vannak SQL Server 2005-ön
DML és DDL triggereket írni.
A DML trigger nem sokban különbözik a korábbi verzióban megírt DML triggertől.
Szintaktikájába kerültek be új elemek.
CREATE TRIGGER trigger .név
ON { tábla l nézet }
[ WITH ENCRYPTION l {EXECUTE AS {CALLER l SELF l OWNER}}l
{{{ FOR l AFTER l INSTEAD OF) { [ DELETE l [ , l [ INSERT
[ , ] [ UPDATE J }
[ NOT FOR REPLICATION J
AS
[ { IF UPDATE ( oszlop )
[ { AND l OR } UPDATE ( oszlop ) l
[ .•. n l
l IF ( COLUMNS_UPDATED ( ) { bitszintú_operátor }
módositott_bitmaszk )
{ összehasonlitó operátor} oszlop bitmaszk [ ... n
} l
sqlu t asi tás [ ... n l
} }

200
25.SQL Server 2005 újdonságok Iváncsy Renáta

A DDL triggerek különböző adatdefiníciós utasítások hatására automatikusan lefutó tárolt


eljárások. llyen utasítások a CREATE, ALTER, DROP, GRANT, DENY, REVOKE és a
UPDATE STATISTICS utasítások. DDL utasításokat általában adminisztrativ műveletek

elvégzésére szaktak definiálni, mint mondjuk az auditálás. Az alábbi események DDL Irigger
készítését indokolják:
• Meg szeretnénk akadályomi, hogy bízonyos módositásokat hajtsanak végre az
adatbázis sémában.
• Szeretnénk, ha bizonyos műveletek végrehajtódDának abban az esetben, ha valami
megváltozik az adatbázis sémáhan.
• Naplómi szeretnénk eseményeket vagy módositásokat. amik az adatbázis
sémában történtek.
A DDL trigger létrehozásának szintaktikája a következő :
CREATE TRIGGER trigger ..név
ON { ALL SERVER l DATABASE }
[ WITH {ENCRYPTION l {EXECUTE AS (CALLER l SELF l
'felhasználói név'}}}
{{{FOR l AFTER} { esemény_tipus esemény_csoport} [, ... n)
AS
sql_utasítás [ ... n)
Mint látható, DDL trigger esetén is el kell nevezni a triggert, majd meghatározni, hogy mí
legyen a hatásköre. Ez lehet az adott adatbázis, amiben a trigger definiál va lett (DAT ABASE
kulcsszó használata) vagy az egész szerver (ALL SERVER). Az adatbázis hatókörrel
rendelkező DDL triggerek abban az adatbázisban kerülnek eltárolásra, ahol a létrehozó
utasítást kiadtuk., de létrehozhatjuk a MASTER adatbázisban is. A szerver hatókörrel
rendelkező DDL triggerek mindenképpen a MASTER adtabázisban kerülnek eltárolásra.
Az EXECUTE AS lrulcsszóval azt adhatjuk meg, hogy milyen jogosultságokkal fusson le
a trigger.
Mint ahogy az a szintaktikából is látható, a DDL trigger csak az esemény után lefutó
triggerként lehet definiálni. Ezek után kell definiálni az eseményt, amire az adott triggemek le
kell futnia. Az alábbi táblázatban azok az események láthatók, amikre adatbázis hatókörrel
rendelkező DDL trigger futtatható :
CREAlll_APPUCATION_ROU! ALlllR_APPUCATION_ROLE DROP_APPUCATION_ROLE

CREATE _ASSEMBLY ÁLTER _ASSEMBLY P ROP _ASSf!MBLY

ALTF.R_AUTHORIZATioN_DATABASE

CREÁTE_CERTIFICAlll ALTF.R-C ERTIFlCAlll DROP_CERTIFlCATE

CREAlll_ CON"mACT DROP_CONTRACT

201
25.SQL Server 2005 újdonságok Iváncsy Renáta

GRANT_DATABASE DENY_DATABASE .REVOKE_DATABASE

CRF.ATE_I!VI!IIIT_NOTIFICATION DROP_EVENT_NOTIFICATION

CRF.ATP._FUNCTION ALTER_fuNCTION DRDP_P'UNCilON

CltEATE_INDEX ALTER_INDEX DROP_INDEX

CREÁTE) O!SSAOE_TYPE ALTER).iESSAOE_TYPE - --·· - ·--· DROP_MI!SSAGE_)YPE

CRF.ATE_PARTITION_FUNCTION ALTER_PARTmON_FUNCTION . DROP_PARTITION_ FUNCTION

CltEATE_ PARTITION_SCHEME ALTER_PAR1TnON_SCHEME DROP_PARTITION_SCHEME

CREATE_PR.ÖCEDURE ALTER~PROCEDURE DROP_ PROCEDU'RB

Cllf!ATE_QUEUE ALlilR~QUÜ - DROP_QUEUE

CREATE~REMÓ'I'Ejii!RVJéE_BINDING ÁLTER~RI!MOTE_SERVICI!_BiNriÍNG DltOP_REMÓTE_SERvici!_BINDING

Cllf!ATE_RÓl i- . ALTER_ ROu! - - DROP_ROU! - ----- ~

C1tEATE_ROlTI1! ALTER_RoUTE DROP_ROUTI! .

Cllf!ATE_SCHI!MA ALTER_SCHI!MA pROP_SCHI!MA

Cllf!ATE_SERVICE Ai;riJt_SRRV!cF. DROP_SERVICE

Cllf!ATE_STAnSTICS i>RoP_SfATiST!cs uPDATE~STAnsnes--

CRF.ATE_SYNONYM DROP_SYNONYM

CltEATE_TABU! ALTRR_TABU! DRÖP_TABLB

CIÜ!.ATE_ntiOOI!R N:fu_TiuOOER ... ;DRöJö ~-Tiu<iaEii ..


CJti!ATE_1YPE DROP~-rfPE

CREAri:_UsER ALT'Ili_USER
CRRATE_VIEW ALTER_ VIEW

·cwii_XMi._jli:ímMÁ-:_r owcnoN ALTER-XML_SCHEMA_COLLECT10N DROP_XML_SCHI!MA-COlLECTION

Az alábbi táblázatban azok az események vannak felsorolva, amire szerver hatókörű DDL
triggert használhatunk.
ALTER_AI.TilfORIZATION_ SI!RVER

CREATE_DATABASE ALTER_ DATABASE -· DROP_DATABASE


. - .)
CREATE_ENDPOINT DROP_ ENDPOINT
i
CltEATE_LOOIN ]ALTP..R LOGIN DROP_LOOIN
l -
GRANr_SERVI!R ·p ÉNY_SI!RVER REVOKE_SERVER.

Az események meghatározása mellett lehetőség van esemény csoportok definiálására. Az


esemény csoportokat az SQL Server 2005 előre definiálta. Dyen esemény csoport például a
DDL_TABLE_EVENTS eseménycsoport, ami bármely, egy táblán végzett CREATE,
ALTER vagy DROP eseményt magában foglal. Hasonlóan van DDL_FUNCTION_EVENTS,
DDL_PROCEDURE_EVENTS stb. (Az eseménycsoportok teljes listája a Helpben
megtalálható ).

202
26.lrodalom jegyzék Iváncsy Renáta

26. Irodalom jegyzék


[l] Programming a Microsoft SQL Server 2000 Database, Microsoft Corporation, 1999
[2] David K. Rensin, Andrew M. Fedorebek and William C. Amo: Microsoft SQL
Server7 Sercrets, IDG Books W ori dwide, Inc. 1999
[3] SQL Server Books Online
[4] Gajdos Sándor: Adatbázisok, Müegyetem Kiadó, 2000
[5] David lseminger: T-SQL Language Reference, Microsoft Press, 2001
[6] David Iseminger: T-SQL Stored Procedures and Tables Reference, 2001
[7] Neena Kochnar, Eileen Lad: Introduction to Oracle: SQL and PUSQL
Oracle, 1998
[8] Tom Portfolio, John Russeii:PUSQL User's Guide and Reference Release 9.0.1
Oracle, 200 l
[9] D.K. Bradshaw: Oracle9i Supplied PUSQL Packages and Types Reference
Release 2 (9.2) Oracle, 2002
[l O] Rózsa Zsolt: Digitális könyvtárak a Weben, diplomamunka 2002
[ll] Nagy-György Attila: Vállalati információs rendszerek szoftverfejlesztési kérdései,
diplomamunka 2003
[12] Bill Hamilton, Programming SQL Server 2005, O'Reilly, ISBN: 0-596-00479-6, 2006
Feb.

203

You might also like