http://www.beregszaszi-debr.sulinet.hu/tantargy/info/anyagok/sqljegyzet.pdf
Középszint
Fealdatok
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_infoism_17maj_fl.pdf
Megoldás
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_infoism_17maj_ut.pdf
Emeltszint
Feladat
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/e_infoism_17maj_fl.pdf
Megoldás
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/e_infoism_17maj_ut.pdf
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_inf_17maj_fl.pdf
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_inf_17maj_ut.pdf
Az SQL (Structured Query Language)- Strukturált Lekérdező Nyelv.
Az SQL szabványos adatbázis-kezelő nyelv. A lekérdezési funkciók mellett a nyelv több olyan elemmel is rendelkezik, amelyek más adatkezelési funkciók végrehajtására is alkalmasak. A nyelv legújabb szabványos változatai, pedig már egészen kiterjedt adatbázis-kezelési műveletek megvalósítására is használhatók.
Az SQL lekérdező része megfelel a relációs algebrának, ezért alkalmas a relációs adatmodell kezelésére, és az SQL segítségével meg lehet fogalmazni a matematikailag megalapozott műveleteket. Lehetőség van az SQL parancsokba történő beépítésére, ami hatékony, gyors lekérdezési lehetőséget biztosít.
Az SQL-nek több verziója van. Általában a különböző ABKR implementációk a saját képükre formált SQL megvalósítással rendelkeznek.
Az SQL nyelv szabványai:
· az ANSI (American National Standards Institute = Amerikai Nemzeti Szabványügyi Intézet) által definiált SQL;
· SQL-92 vagy SQL2 - az 1992-ben elfogadott módosított szabvány. Később ezeket az ISO (International Standars Organization) Nemzetközi Szabványügyi Szerveze) is elfogadta;
· az SQL3.
Minden SQL parancs egy kulcsszóval kezdődik, amelyet paraméterek, esetleg további kulcsszavak követhetnek. A paraméterek általában azok az objektumok, melyekre a parancsok vonatkoznak. Ilyen lehet például egy tábla vagy attribútum neve, esetleg egy konstans, vagy valamilyen azonosító.
A parancsok lehetnek egyszerűek vagy összetettek, ami azt jelenti, hogy egy parancson belül egy másik parancs is előfordulhat.
Az SQL parancsokat két fő csoportra oszthatjuk:
· DDL (Data Defintion Language) és
· DML (Data Manipulátion Language)
parancsok. A DDL parancsok definiálják az AB objektumait, a DML parancsok, pedig végrehajtják azokkal a műveleteket. A DML egyik legfontosabb parancsaihoz tartozik a lekérdezési parancs.
(Bővebben – az Oracle fejezetben)
4.2 Táblák létrehozása, módosítása, törlése
A tábla definiálásának parancsában meg kell adni a tábla nevét, a tábla attribútumait, azok típusát és méretét. (Táblák létrehozása az Oracle-ben)
A legfontosabb adattípusok, amelyeket az SQL szabvány definiál:
· Egész számok. Ezek megadásánál a SHORTINT, INT vagy INTEGER kulcsszavakat használhatjuk;
· Valós számok, lebegőpontos tárolással. Ebben az esetben is különböző mérető számokat adhatunk meg. A FLOAT és a REAL a hagyományos programozás nyelvekből is ismert normál lebegőpontos számot jelenti. A DOUBLE PRECISION duplapontos számot jelent, míg speciálisan az SQL-ben használhatjuk a DECIMAL(<számjegy>,<tizedesjegy>) formát is, ahol explicit módon megadhatjuk, hogy a szám hány számjegyből állhat, illetve hány tizedes-jegyet tartalmazhat.
· Fix vagy változó hosszúságú karaktersorozatok. Megadásuk a CHAR(<hossz>), illetve a VARCHAR(<hossz>) paranccsal történik. A CHAR segítségével olyan attribútumot definiálhatunk, amely pontosan a megadott hosszúságú karaktersorozatként fogja tárolni az adatokat, míg a VARCHAR esetén a megadott attribútumoknál csak az aktuális számú karakter kerül tárolásra. Látszólag a VARCHAR szolgáltatja a jobb megoldást, azonban az SQL elég rugalmas ahhoz, hogy a CHAR típust is jól kezelje.
· Dátum és idő. Ezeket a DATE és TIME kulcsszavakkal lehet megadni.
A táblákat a következő paranccsal lehet létrehozni:
CREATE TABLE <táblanév> { <attribútumdefiníció> [,<attribútumdefiníció>]… }
Az <attribútumdefiníció> paraméterben adjuk meg az egyes attribútumok nevét és típusát, a következő módon:
<név> <típus> [DEFAULT <érték>]
A <név> jelenti az attribútum nevét, míg a <típus> adja meg a típust és a méretet, a fentiekben ismertetett módon. A DEFAULT paranccsal alapértelmezett értékeket adhatunk meg az egyes attribútumoknak. Ennek használata nem kötelező.
A létező táblát módosíthatjuk az ALTER TABLE paranccsal. Lehetőség van arra is, hogy új oszlopot adjunk. Ez a következőképpen történhet:
ALTER TABLE <táblanév> ADD <attribútumdefiníció>
Hasonlóan történhet egy oszlop eltávolítása a táblából. Ebben az esetben elegendő az attribútum a nevét megadni:
ALTER TABLE <táblanév> DROP <attribútumnév>
Lehetőségünk van az egész tábla törlésére is:
DROP <táblanév>
Egy tábla definiálásakor a tábla nevén és az attribútumokon kívül egyéb információt is lehet megadni. Ilyenek a
· kulcsok
· az attribútum értékekre vonatkozó megszorítások.
Először a kulcsok, és az egyedi értékekkel bíró attribútumok megadásának módját ismertetjük. Az SQL-ben alapvetően az elsődleges kulcs megadására van lehetőségünk, ahogy azt a legtöbb ABKR megköveteli. Ha az elsődleges kulcsot szeretnénk definiálni, akkor a tábla létrehozását kibővíthetjük megfelelő opciókkal (záradékokkal). Ez a következőképpen néz ki:
CREATE TABLE <táblanév> { <attribútumdefiníció> [UNIQUE] [,<attribútumdefiníció> [UNIQUE]]… [,PRIMARY KEY (<kulcsattribútum> [,<kulcsattribútum>]…)|UNIQUE (<kulcsattribútum>) ]}
A UNIQUE kulcsszó segítségével minden egyes attribútumnál megadhatjuk, hogy az adott attribútum csak egyedi értékeket vehet fel. A <kulcsattribútum> paraméterben kell megadni annak az attribútumnak a nevét, amely a kulcsot alkotja, vagy annak egy részét képezi. Amennyiben csak egy attribútum tartozik a kulcshoz, akkor használhatjuk mind a PRIMARY KEY, mind a UNIQUE parancsokat. Több attribútumból álló kulcsot csak a PRIMARY KEY kulcsszóval definiálhatunk.
4.3 Idegen kulcsok alkalmazása
Az SQL lehetőséget biztosít az idegen kulcsok definiálására is.
Ennek módja az alábbi:
CREATE TABLE <táblanév> { <attribútumdefiníció> [REFERENCES <táblanév> (<attribútumnév>)] [,<attribútumdefiníció> [REFERENCES <táblanév> (<attribútumnév>)]]… [,FOREIGN KEY (<kulcsattribútum> [,<kulcsattribútum>]…) <táblanév> (<kulcsattribútum>[,<kulcsattribútum>]…) ]}
Láthatjuk, hogy az idegen kulcs megadása hasonló az elsődleges kulcshoz. A különbség mindössze annyi, hogy az idegen kulcsnál mindig meg kell adni, hogy az attribútum melyik másik tábla kulcsmezőjéhez kapcsolódik.
Amennyiben az idegen kulcs egy attribútumból áll, használhatjuk a REFERENCES záradékot, ha azonban az idegen kulcs összetett, akkor a FOREIGN KEY záradékkal kell definiálnunk.
Az ABKR-nek gondoskodnia kell a hivatkozási épség fenntartásáról. Ez azt jelenti, hogy ha egy idegen kulcsban hivatkozunk egy másik táblának egy kulcsértékére, akkor a megadott értékű előfordulásnak létezni kell.
Amennyiben olyan módosító, vagy törlő művelet hajtódik végre, amely a hivatkozási épséget megsérti, akkor az ABKR-nek ezt kezelnie kell.
Az ABKR-nek következő lehetőségei vannak:
· a műveletet nem engedi végrehajtani
· a műveletet megengedi, de a hivatkozási épség fenntartása érdekében automatikusan korrigálja az adatbázist
Ez a korrigálás kétféleképpen történhet.
· Az egyik az, hogy ha egy hivatkozott sort törlünk, vagy módosítunk, akkor a rá hivatkozó előfordulások is törlődnek, vagy módosulnak a másik táblában
· A másik lehetőség az, hogy a helytelen hivatkozásokat az ABKR egy NULL (üres) értékkel korrigálja.
Ha azt akarjuk, hogy egy korrigáló eljárás aktiválódjon a hivatkozási épség megsérülésekor, akkor azt a tábla definiálásában kell megadni. Mivel a hivatkozási épség az idegen kulcsokra vonatkozik, ezért azt csak az idegen kulcsokkal kell alkalmazni. Ezeket a megszorításokat a REFERENCES záradékban lehet megadni:
REFERENCES <táblanév> (<attribútumnév>) [[ON DELETE SET NULL|CASCADE] [ON UPDATE SET NULL|CASCADE]]
Az ON DELETE részben azt adhatjuk meg, hogy a törlés során bekövetkezett hivatkozás épség sérülését hogyan kezelje a rendszer, míg az ON UPDATE részben a módosításkor bekövetkezőt.
Mindkét esetben a két lehetőség közül választhatunk:
· SET NULL – a NULL érték beállítása
· CASCADE – a hivatkozó táblában is korrigálást hajtunk végre.
4.4 Megszorítások definiálása
(Megszorítások az Oracle-ben)
A tábla definiálásakor más megszorítások is megadhatók Ennek legegyszerűbb esete az, amikor a megszorítás az egyes attribútumok értékeire vonatkozik. Ezt az attribútum leírásakor kell megadni, és ennek a formája a következő:
<attribútumdefiníció> NOT NULL|CHECK (<feltétel>)
A NOT NULL opció azt jelenti, hogy az adott attribútum nem vehet fel NULL (üres) értéket. A CHECK kulcsszó után tetszőleges feltételt adhatunk. Az erre vonatkozó szabályok megegyeznek a SELECT parancsban használt WHERE záradék lehetséges feltételével.
A feltétel ellenőrzése sor beszúrásakor, vagy az attribútum módosításakor történik.
Ennél általánosabb megszorítások is megfogalmazhatók. Lehetnek olyanok, amelyek sorokra vonatkoznak, és lehetnek olyan globális megszorítások, amelyek a teljes adatbázisra vonatkoznak. A sorokra vonatkozó megszorítások ellenőrzése a sorban történő bármilyen módosításkor megtörténik. A teljesen általános megszorítások ellenőrzése minden olyan módosításkor bekövetkezik, aminek az adott feltételre hatása lehet. A sorra vonatkozó feltételek megadása szintén a CHECK paranccsal történik, ezt a tábla definiálásának a végén kell megadni. Formája az alábbi:
CREATE TABLE <táblanév> { <attribútumdefiníció> [,<attribútumdefiníció>]… [CHECK <feltétel>]}
A globális megszorítások definiálása külön kulcsszóval történik, melynek formája a következő:
CREATE ASSERTION <név> CHECK <feltétel>
Példa
Adjuk meg azt az SQL parancsot, amely létrehozza a Dolgozó táblát!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
A létrehozott tábla az alábbi:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési helye
A dolgozó
születési ideje
A dolgozó
Fizetése
Példa
Adjuk meg azt az SQL parancsot, amely létrehozza a Dolgozó táblát, és az elsődleges kulcsnak az A_dolgozó_törzsszáma mezőt definiálja!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7) PRIMARY KEY, Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
Egy másik lehetséges megoldás:
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) PRIMARY KEY (A_dolgozó_törzsszáma)}
Példa
Tegyük fel, hogy a Kifizetés táblában található A_dolgozó_törzsszáma nevű mező idegen kulcs, amely a Dolgozó táblával való kapcsolatot valósítja meg. Adjuk meg azt az SQL parancsot, amely a fenti Kifizetés táblát létrehozza, úgy hogy a hivatkozási épség sérülésekor az ABKR azt automatikusan frissítéssel korrigálja!
CREATE TABLE Kifizetés {A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7) REFERENCES Dolgozó (A_dolgozó_törzsszáma) ON UPDATE CASCADE ON DELETE CASCADE}
Egy másik lehetséges megoldás:
CREATE TABLE Kifizetés {A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7), FOREIGN KEY (A_dolgozó_törzsszáma) Dolgozó (A_dolgozó_törzsszáma) ON UPDATE CASCADE ON DELETE CASCADE}
A létrehozott tábla a következő:
A kifizetés dátuma
A kifizetett
bér
A levont
Adóelőleg
A dolgozó törzsszáma
Példa
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblát úgy definiálja, hogy a Fizetés mező esetén mindig ellenőrzésre kerüljön, hogy az éppen megadott érték eléri-e egy minimális bér összegét, mondjuk 55000 Ft-ot!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30), Sz_Ideje DATE, Fizetés DECIMAL(7,0) CHECK A_dolgozó_fizetése >55000}
Példa
Adjuk meg azt az SQL parancsot, amely egy olyan globális megszorítást definiál, amely ellenőrzi, hogy a Dolgozó táblában az összes fizetés együttesen ne haladja meg a 10.000.000 Ft-ot!
CREATE ASSERTION Összefizetés CHECK (10000000 >= (SELECT SUM(Fizetés) FROM Dolgozó))
4.5 Táblák indexelése
Példa
CREATE INDEX Diak_NeveInd ON Students ( Diak_Neve)
A Student tábla Diak_Neve attribútum indexelve lesz, és az index neve Diak_NeveInd.
Egy másik lehetőség:
CREATE UNIQUE INDEX Diak_NeveInd ON Students ( Diak_Neve)
Az index törlése:
DROP INDEX Diak_NeveInd
4.6 Példák a CREATE parancs alkalmazására
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
PRIMARY KEY (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK (Jegy =<5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num)
CHECK (Jegy IN ( 4, 5) AND Datum> 15/06/2001)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5) DEFAULT = 5,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
FOREING KEY ( Stud_Num ) REFERENCES Students (Stud_Num))
Stud_Num – külső kulcs, kapcsolat a Students-el.
Vagy
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES Students (Stud_Num),
Tantargy_Num INTEGER NOT NULL )
Ha a Students-ben a Stud_Num attribútum PRIMARY KEY, akkor a szülő-táblában azt nem kell megadni:
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES Students,
Tantargy_Num INTEGER NOT NULL )
Adjuk meg azt az SQL parancsot, amely hozzáadja a Dolgozó táblához a dolgozó lakcímét!
ALTER TABLE Dolgozó ADD A_dolgozó_lakcíme VARCHAR(50)
A módosított Dolgozó tábla így fog kinézni:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési helye
A dolgozó
születési ideje
A dolgozó
fizetése
A dolgozó lakcíme
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblából törli Sz_ helye attribútumot!
ALTER TABLE Dolgozó DROP Sz_Helye
A módosítás után a Dolgozó tábla:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési ideje
A dolgozó
fizetése
A dolgozó lakcíme
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblát törli!
DROP Dolgozó
4.7 Példák az adatintegritásra
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num INTEGER NOT NULL,
UPDATE OF Students CASCADES,
DELETE OF Students RESTICTED)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num INTEGER NOT NULL,
DELETE OF Students NULLS)
Diakok tabla
Nev
|
Ido
|
Hely
|
Neme
|
suly
|
Kiss Ede
|
15
|
Pécs
|
1
|
87
|
Nagy Éva
|
16
|
Gyál
|
2
|
56
|
Soós Leó
|
15
|
Kék
|
1
|
88
|
Vak Era
|
16
|
Kék
|
2
|
45
|
Bak Pál
|
17
|
Tét
|
1
|
97
|
Vass Ida
|
17
|
Győr
|
2
|
66
|
Kérem a diákok nevét
kilistázni! SELECT nev FROM diakok;
Milyen korúak a
diákok? SELECT DISTINCT ido FROM
diakok;
Kérem a 2001-ben
született diákok nevét! SELECT nev
FROM diakok WHERE ido=17;
Kérem a diákok nevét
és sulyát! SELECT nev,súly FROM
diakok;
Kérem a 16 éven aluli
lá nyok nevének listáját! SELECT nev FROM diakok WHERE Ido< 16;
Mi a neve annak a
lánynak aki Kéken született? SELECT
nev FROM diakok WHERE hely=’Kek’;
Mi a neve azoknak
akik nem születtek Kéken? SELECT nev FROM diakok WHERE hely<>’Kek’;
Mi a neve azoknak
akik betöltötték már a 16 évet? SELECT nev FROM diakok WHERE ev>=16;
V betűvel kezdődik a
nevük? SELECT nev FROM diakok WHERE nev LIKE 'V%';
Akiknek a súlya 57 és
96 kg között van!SELECT nev FROM diakok WHERE suly BETWEEN 57 and 96;
Rakjuk ábc sorrrendbe
a nevek szerint! SELECT * FROM diakok ORDER BY nev;
Kérek egy teljes listát
azokról, akik 15 és 16 évesek abc sorrendben! SELECT * FROM diakok WHERE ev
BETWEEN 15 OR 16; AND ORDER BY nev;
Kérek egy listát
arról kik születtek Kéken és Téten! SELECT * FROM diakok WHERE hely IN
('Kék', 'Tét');
Érettségi feladatok
Középszint
Fealdatok
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_infoism_17maj_fl.pdf
Megoldás
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_infoism_17maj_ut.pdf
Emeltszint
Feladat
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/e_infoism_17maj_fl.pdf
Megoldás
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/e_infoism_17maj_ut.pdf
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_inf_17maj_fl.pdf
https://dari.oktatas.hu/kir/erettsegi/okev_doc/erettsegi_2017/k_inf_17maj_ut.pdf
Az SQL (Structured Query Language)- Strukturált Lekérdező Nyelv.
Az SQL szabványos adatbázis-kezelő nyelv. A lekérdezési funkciók mellett a nyelv több olyan elemmel is rendelkezik, amelyek más adatkezelési funkciók végrehajtására is alkalmasak. A nyelv legújabb szabványos változatai, pedig már egészen kiterjedt adatbázis-kezelési műveletek megvalósítására is használhatók.
Az SQL lekérdező része megfelel a relációs algebrának, ezért alkalmas a relációs adatmodell kezelésére, és az SQL segítségével meg lehet fogalmazni a matematikailag megalapozott műveleteket. Lehetőség van az SQL parancsokba történő beépítésére, ami hatékony, gyors lekérdezési lehetőséget biztosít.
Az SQL-nek több verziója van. Általában a különböző ABKR implementációk a saját képükre formált SQL megvalósítással rendelkeznek.
Az SQL nyelv szabványai:
· az ANSI (American National Standards Institute = Amerikai Nemzeti Szabványügyi Intézet) által definiált SQL;
· SQL-92 vagy SQL2 - az 1992-ben elfogadott módosított szabvány. Később ezeket az ISO (International Standars Organization) Nemzetközi Szabványügyi Szerveze) is elfogadta;
· az SQL3.
Minden SQL parancs egy kulcsszóval kezdődik, amelyet paraméterek, esetleg további kulcsszavak követhetnek. A paraméterek általában azok az objektumok, melyekre a parancsok vonatkoznak. Ilyen lehet például egy tábla vagy attribútum neve, esetleg egy konstans, vagy valamilyen azonosító.
A parancsok lehetnek egyszerűek vagy összetettek, ami azt jelenti, hogy egy parancson belül egy másik parancs is előfordulhat.
Az SQL parancsokat két fő csoportra oszthatjuk:
· DDL (Data Defintion Language) és
· DML (Data Manipulátion Language)
parancsok. A DDL parancsok definiálják az AB objektumait, a DML parancsok, pedig végrehajtják azokkal a műveleteket. A DML egyik legfontosabb parancsaihoz tartozik a lekérdezési parancs.
(Bővebben – az Oracle fejezetben)
4.2 Táblák létrehozása, módosítása, törlése
A tábla definiálásának parancsában meg kell adni a tábla nevét, a tábla attribútumait, azok típusát és méretét. (Táblák létrehozása az Oracle-ben)
A legfontosabb adattípusok, amelyeket az SQL szabvány definiál:
· Egész számok. Ezek megadásánál a SHORTINT, INT vagy INTEGER kulcsszavakat használhatjuk;
· Valós számok, lebegőpontos tárolással. Ebben az esetben is különböző mérető számokat adhatunk meg. A FLOAT és a REAL a hagyományos programozás nyelvekből is ismert normál lebegőpontos számot jelenti. A DOUBLE PRECISION duplapontos számot jelent, míg speciálisan az SQL-ben használhatjuk a DECIMAL(<számjegy>,<tizedesjegy>) formát is, ahol explicit módon megadhatjuk, hogy a szám hány számjegyből állhat, illetve hány tizedes-jegyet tartalmazhat.
· Fix vagy változó hosszúságú karaktersorozatok. Megadásuk a CHAR(<hossz>), illetve a VARCHAR(<hossz>) paranccsal történik. A CHAR segítségével olyan attribútumot definiálhatunk, amely pontosan a megadott hosszúságú karaktersorozatként fogja tárolni az adatokat, míg a VARCHAR esetén a megadott attribútumoknál csak az aktuális számú karakter kerül tárolásra. Látszólag a VARCHAR szolgáltatja a jobb megoldást, azonban az SQL elég rugalmas ahhoz, hogy a CHAR típust is jól kezelje.
· Dátum és idő. Ezeket a DATE és TIME kulcsszavakkal lehet megadni.
A táblákat a következő paranccsal lehet létrehozni:
CREATE TABLE <táblanév> { <attribútumdefiníció> [,<attribútumdefiníció>]… }
Az <attribútumdefiníció> paraméterben adjuk meg az egyes attribútumok nevét és típusát, a következő módon:
<név> <típus> [DEFAULT <érték>]
A <név> jelenti az attribútum nevét, míg a <típus> adja meg a típust és a méretet, a fentiekben ismertetett módon. A DEFAULT paranccsal alapértelmezett értékeket adhatunk meg az egyes attribútumoknak. Ennek használata nem kötelező.
A létező táblát módosíthatjuk az ALTER TABLE paranccsal. Lehetőség van arra is, hogy új oszlopot adjunk. Ez a következőképpen történhet:
ALTER TABLE <táblanév> ADD <attribútumdefiníció>
Hasonlóan történhet egy oszlop eltávolítása a táblából. Ebben az esetben elegendő az attribútum a nevét megadni:
ALTER TABLE <táblanév> DROP <attribútumnév>
Lehetőségünk van az egész tábla törlésére is:
DROP <táblanév>
Egy tábla definiálásakor a tábla nevén és az attribútumokon kívül egyéb információt is lehet megadni. Ilyenek a
· kulcsok
· az attribútum értékekre vonatkozó megszorítások.
Először a kulcsok, és az egyedi értékekkel bíró attribútumok megadásának módját ismertetjük. Az SQL-ben alapvetően az elsődleges kulcs megadására van lehetőségünk, ahogy azt a legtöbb ABKR megköveteli. Ha az elsődleges kulcsot szeretnénk definiálni, akkor a tábla létrehozását kibővíthetjük megfelelő opciókkal (záradékokkal). Ez a következőképpen néz ki:
CREATE TABLE <táblanév> { <attribútumdefiníció> [UNIQUE] [,<attribútumdefiníció> [UNIQUE]]… [,PRIMARY KEY (<kulcsattribútum> [,<kulcsattribútum>]…)|UNIQUE (<kulcsattribútum>) ]}
A UNIQUE kulcsszó segítségével minden egyes attribútumnál megadhatjuk, hogy az adott attribútum csak egyedi értékeket vehet fel. A <kulcsattribútum> paraméterben kell megadni annak az attribútumnak a nevét, amely a kulcsot alkotja, vagy annak egy részét képezi. Amennyiben csak egy attribútum tartozik a kulcshoz, akkor használhatjuk mind a PRIMARY KEY, mind a UNIQUE parancsokat. Több attribútumból álló kulcsot csak a PRIMARY KEY kulcsszóval definiálhatunk.
4.3 Idegen kulcsok alkalmazása
Az SQL lehetőséget biztosít az idegen kulcsok definiálására is.
Ennek módja az alábbi:
CREATE TABLE <táblanév> { <attribútumdefiníció> [REFERENCES <táblanév> (<attribútumnév>)] [,<attribútumdefiníció> [REFERENCES <táblanév> (<attribútumnév>)]]… [,FOREIGN KEY (<kulcsattribútum> [,<kulcsattribútum>]…) <táblanév> (<kulcsattribútum>[,<kulcsattribútum>]…) ]}
Láthatjuk, hogy az idegen kulcs megadása hasonló az elsődleges kulcshoz. A különbség mindössze annyi, hogy az idegen kulcsnál mindig meg kell adni, hogy az attribútum melyik másik tábla kulcsmezőjéhez kapcsolódik.
Amennyiben az idegen kulcs egy attribútumból áll, használhatjuk a REFERENCES záradékot, ha azonban az idegen kulcs összetett, akkor a FOREIGN KEY záradékkal kell definiálnunk.
Az ABKR-nek gondoskodnia kell a hivatkozási épség fenntartásáról. Ez azt jelenti, hogy ha egy idegen kulcsban hivatkozunk egy másik táblának egy kulcsértékére, akkor a megadott értékű előfordulásnak létezni kell.
Amennyiben olyan módosító, vagy törlő művelet hajtódik végre, amely a hivatkozási épséget megsérti, akkor az ABKR-nek ezt kezelnie kell.
Az ABKR-nek következő lehetőségei vannak:
· a műveletet nem engedi végrehajtani
· a műveletet megengedi, de a hivatkozási épség fenntartása érdekében automatikusan korrigálja az adatbázist
Ez a korrigálás kétféleképpen történhet.
· Az egyik az, hogy ha egy hivatkozott sort törlünk, vagy módosítunk, akkor a rá hivatkozó előfordulások is törlődnek, vagy módosulnak a másik táblában
· A másik lehetőség az, hogy a helytelen hivatkozásokat az ABKR egy NULL (üres) értékkel korrigálja.
Ha azt akarjuk, hogy egy korrigáló eljárás aktiválódjon a hivatkozási épség megsérülésekor, akkor azt a tábla definiálásában kell megadni. Mivel a hivatkozási épség az idegen kulcsokra vonatkozik, ezért azt csak az idegen kulcsokkal kell alkalmazni. Ezeket a megszorításokat a REFERENCES záradékban lehet megadni:
REFERENCES <táblanév> (<attribútumnév>) [[ON DELETE SET NULL|CASCADE] [ON UPDATE SET NULL|CASCADE]]
Az ON DELETE részben azt adhatjuk meg, hogy a törlés során bekövetkezett hivatkozás épség sérülését hogyan kezelje a rendszer, míg az ON UPDATE részben a módosításkor bekövetkezőt.
Mindkét esetben a két lehetőség közül választhatunk:
· SET NULL – a NULL érték beállítása
· CASCADE – a hivatkozó táblában is korrigálást hajtunk végre.
4.4 Megszorítások definiálása
(Megszorítások az Oracle-ben)
A tábla definiálásakor más megszorítások is megadhatók Ennek legegyszerűbb esete az, amikor a megszorítás az egyes attribútumok értékeire vonatkozik. Ezt az attribútum leírásakor kell megadni, és ennek a formája a következő:
<attribútumdefiníció> NOT NULL|CHECK (<feltétel>)
A NOT NULL opció azt jelenti, hogy az adott attribútum nem vehet fel NULL (üres) értéket. A CHECK kulcsszó után tetszőleges feltételt adhatunk. Az erre vonatkozó szabályok megegyeznek a SELECT parancsban használt WHERE záradék lehetséges feltételével.
A feltétel ellenőrzése sor beszúrásakor, vagy az attribútum módosításakor történik.
Ennél általánosabb megszorítások is megfogalmazhatók. Lehetnek olyanok, amelyek sorokra vonatkoznak, és lehetnek olyan globális megszorítások, amelyek a teljes adatbázisra vonatkoznak. A sorokra vonatkozó megszorítások ellenőrzése a sorban történő bármilyen módosításkor megtörténik. A teljesen általános megszorítások ellenőrzése minden olyan módosításkor bekövetkezik, aminek az adott feltételre hatása lehet. A sorra vonatkozó feltételek megadása szintén a CHECK paranccsal történik, ezt a tábla definiálásának a végén kell megadni. Formája az alábbi:
CREATE TABLE <táblanév> { <attribútumdefiníció> [,<attribútumdefiníció>]… [CHECK <feltétel>]}
A globális megszorítások definiálása külön kulcsszóval történik, melynek formája a következő:
CREATE ASSERTION <név> CHECK <feltétel>
Példa
Adjuk meg azt az SQL parancsot, amely létrehozza a Dolgozó táblát!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
A létrehozott tábla az alábbi:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési helye
A dolgozó
születési ideje
A dolgozó
Fizetése
Példa
Adjuk meg azt az SQL parancsot, amely létrehozza a Dolgozó táblát, és az elsődleges kulcsnak az A_dolgozó_törzsszáma mezőt definiálja!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7) PRIMARY KEY, Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
Egy másik lehetséges megoldás:
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) PRIMARY KEY (A_dolgozó_törzsszáma)}
Példa
Tegyük fel, hogy a Kifizetés táblában található A_dolgozó_törzsszáma nevű mező idegen kulcs, amely a Dolgozó táblával való kapcsolatot valósítja meg. Adjuk meg azt az SQL parancsot, amely a fenti Kifizetés táblát létrehozza, úgy hogy a hivatkozási épség sérülésekor az ABKR azt automatikusan frissítéssel korrigálja!
CREATE TABLE Kifizetés {A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7) REFERENCES Dolgozó (A_dolgozó_törzsszáma) ON UPDATE CASCADE ON DELETE CASCADE}
Egy másik lehetséges megoldás:
CREATE TABLE Kifizetés {A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7), FOREIGN KEY (A_dolgozó_törzsszáma) Dolgozó (A_dolgozó_törzsszáma) ON UPDATE CASCADE ON DELETE CASCADE}
A létrehozott tábla a következő:
A kifizetés dátuma
A kifizetett
bér
A levont
Adóelőleg
A dolgozó törzsszáma
Példa
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblát úgy definiálja, hogy a Fizetés mező esetén mindig ellenőrzésre kerüljön, hogy az éppen megadott érték eléri-e egy minimális bér összegét, mondjuk 55000 Ft-ot!
CREATE TABLE Dolgozó {A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30), Sz_Ideje DATE, Fizetés DECIMAL(7,0) CHECK A_dolgozó_fizetése >55000}
Példa
Adjuk meg azt az SQL parancsot, amely egy olyan globális megszorítást definiál, amely ellenőrzi, hogy a Dolgozó táblában az összes fizetés együttesen ne haladja meg a 10.000.000 Ft-ot!
CREATE ASSERTION Összefizetés CHECK (10000000 >= (SELECT SUM(Fizetés) FROM Dolgozó))
4.5 Táblák indexelése
Példa
CREATE INDEX Diak_NeveInd ON Students ( Diak_Neve)
A Student tábla Diak_Neve attribútum indexelve lesz, és az index neve Diak_NeveInd.
Egy másik lehetőség:
CREATE UNIQUE INDEX Diak_NeveInd ON Students ( Diak_Neve)
Az index törlése:
DROP INDEX Diak_NeveInd
4.6 Példák a CREATE parancs alkalmazására
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
PRIMARY KEY (Stud_Num, Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK (Jegy =<5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num)
CHECK (Jegy IN ( 4, 5) AND Datum> 15/06/2001)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5) DEFAULT = 5,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER NOT NULL,
FOREING KEY ( Stud_Num ) REFERENCES Students (Stud_Num))
Stud_Num – külső kulcs, kapcsolat a Students-el.
Vagy
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES Students (Stud_Num),
Tantargy_Num INTEGER NOT NULL )
Ha a Students-ben a Stud_Num attribútum PRIMARY KEY, akkor a szülő-táblában azt nem kell megadni:
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES Students,
Tantargy_Num INTEGER NOT NULL )
Adjuk meg azt az SQL parancsot, amely hozzáadja a Dolgozó táblához a dolgozó lakcímét!
ALTER TABLE Dolgozó ADD A_dolgozó_lakcíme VARCHAR(50)
A módosított Dolgozó tábla így fog kinézni:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési helye
A dolgozó
születési ideje
A dolgozó
fizetése
A dolgozó lakcíme
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblából törli Sz_ helye attribútumot!
ALTER TABLE Dolgozó DROP Sz_Helye
A módosítás után a Dolgozó tábla:
A dolgozó törzsszáma
A dolgozó
neve
A dolgozó
születési ideje
A dolgozó
fizetése
A dolgozó lakcíme
Adjuk meg azt az SQL parancsot, amely a Dolgozó táblát törli!
DROP Dolgozó
4.7 Példák az adatintegritásra
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num INTEGER NOT NULL,
UPDATE OF Students CASCADES,
DELETE OF Students RESTICTED)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num INTEGER NOT NULL,
DELETE OF Students NULLS)
Az SQL szabad alakú nyelv (Free-Form Language).
DDL (Data Definition Language)
ALTER PROCEDURE
ALTER TABLE
ANALYZE (a teljesítmény statisztikáját gyűjti)
ALTER TABLE ADD CONSTRAINT
CREATE TABLE
CREATE INDEX
DROP INDEX
DROP TABLE
GRANT
TRUNCATE
REVOKE
DML (Data Manipulation Language)
INSERT
DELETE
UPDATE
SELECT
COMMIT WORK
ROLLBACK
9.2 Táblák létrehozása
A táblákat a CREATE TABLE paranccsal lehet létrehozni. Egy táblában <=1000 oszlop lehet. Több adattípust is lehet alkalmazni, de gyakorlatilag csak néhányra van szükség.
NUMBER(h, t) – numerikus adatok, hossza<=38, h a szám hosszát tartalmazza, t – a tizedes-jegyek számát;
DATE – dátum és idő típus;
VARCHAR2(méret) – karakter típus, a hossza váltózó (max hossza<=4000);
CHAR(méret) – karakter típus, fix hosszúságú (max hossza<=2000);
NCHAR(méret) – azonos a CHAR típussal, de a max méret függ a karakterkészletétől,
LOB (large objects) – bináris v. szöveges formátum. Lehet kép-, hang-, vagy nagy méretű szöveges állomány.
A LOB típuson belül lehetnek:
· LONG – szöveges adatok, max hossza<=2 Gbyte;
· LONG RAW – bináris adatok, max hossza<=2 Gbyte;
A LONG és LONG RAW típusokat csak egyszerű adatfeldolgozásban alkalmazzák.
· CLOB, NCLOB, BLOB – belső LOB típusok, mivel az AB-ban tárolódnak, max hossza<=4 Gbyte;
· CLOB – az adatokat tárolja az AB karakter-készlete alapján;
· NCLOB – az adatokat tárolja a nemzeti karakter-készletben.
Az Oracle mindegyik táblába automatikusan helyez egy ROWID nevű pszeudooszlopot, amely a programozók ritkán szokták használni.
ROWID – pszeudooszlop, amely tartalmazza a sor logikai egyedi címét. A ROWID nem változható meg, de a SELECT parancsban lekérdezhető:
SELECT rowid FROM tabla_1;
A Sor sorszáma – olyan szám, amely akkor rendelődik a sorhoz, amikor az bekerül a táblába. Ez a szám része a ROWID-nek.
Csak az a felhasználó hozhat létre táblákat, aki CREATE TABLE vagy CREATE ANY TABLE privilégiummal rendelkezik.
A STORAGE paraméter alkalmazása a CREATE TABLE parancsban
Egy táblát a STORAGE memória-paraméterek nélkül is lehet létrehozni. Ebben az esetben a tábla az alapértelmezési értékeket kapja, ami nem mindig jó megoldás. A memória egységeket (szegmenseket), melyekben a táblák tárolódnak, extentnek nevezzük. Az első extent neve INITIAL, a többi extentek pedig másodlagos extentek.
CREATE TABLE testtab
(col1 VARCHAR2(10))
STORAGE (INITIAL 100K
NEXT 50K
MINEXTENTS 1
MAXEXTENTS 99
PCINCREASE 20);
Az első extent 100K memóriát kap, a második – 50K. A PCINCREASE 20 érték alapján mindegyik következő extent mérete 20% növekszik az előzőhez képest. MINEXTENTS 1 azt jelenti, hogy a tábla először 1extentent kap, a MAXEXTENTS 99 – a tábla maximálisan 99 extentet kaphat.
9.3 Táblák partíciónálása
A táblákat, mint az indextáblákat is, particionálhatjuk. A particionálás lehetőséget ad a nagyon nagy táblák és indextáblák kezelésére. A particionálás során a nagy táblát kisebb és könnyebben kezelhető részekre osztja a rendszer.
Partíciónált tábla – olyan tábla, amelynek sorai kisebb azonos szerkezetű táblákba, partíciókra, vannak szétosztva.
A partíciók fizikailag különböző helyeken tárolhatjuk.
A partíciónálás előnyei:
Az I/O-terhelés jobb eloszlása
Biztonsági mentés és visszaállítás egyszerűbb végrehajtása
Az adatsérülés lehetőségének minimalizálása
Az archiválási folyamat segítése.
Példa.
CREATE TABLE nagy_tabla
(col1 VARCHAR2(10),
(col2 VARCHAR2(10))
)
PARTITION BY RANGE (col1, col2)
(PARTITION p1 VALUES LESS THEN (…) TABLESPACE p1,
PARTITION p2 VALUES LESS THEN (…) TABLESPACE p2);
Hivatkozás egy partícióra:
ALTER TABLE nagy_tabla DROP PARTITION p1;
ALTER TABLE parancs
Az oszlop hosszát lehet növelni még akkor is, ha a tábla adatokat tartalmaz. Az oszlop hosszát pedig csak akkor lehet csökkenteni, ha a tábla üres.
ALTER TABLE testtab ADD col2 VARCHAR2(100);
ALTER TABLE testtab MODIFY col2 VARCHAR2(150);
ALTER TABLE testtab STORAGE ( NEXT 10K
MAXEXTENTS 50);
ALTER TABLE testtab DROP COLUMN col1;
A táblákat átnevezhetjük:
RENAME testtab TO testtab1;
és törölhetjük:
DROP TABLE testtab;
Példa.
CREATE TABLE students(
id NUMBER(5) PRIMARY KEY,
first_name VARCHAR2(20),
last_name VARCHAR2(20),
major VARCHAR2(30), -- szak
current_credits NUMBER(3) ); -- leadott vizsgák száma
Az ORACLE-rendszer tartalmazz egy bemutató sémát, amelynek Scott a tulajdonosa:
CREATE TABLE scott.dept
(deptno NUMBER(2) NOT NULL,
dname VARCHAR2(14),
loc VARCHAR2(13),
CONSTRAINT pk_dept PRIMARY KEY (deptno));
CREATE TABLE scott.emp
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
sal NUMBER(7,2),
deptno NUMBER(2),
CONSTRAINT pk_emp PRIMARY KEY (empno));
Amikor egy olyan táblára (vagy más Oracle-objektumra) hivatkozunk, melynek nem mi vagyunk a tulajdonosa, akkor a tábla nevén kívül meg kell adni a tulajdonos nevét is
tulajdonos.tábla_név
9.4 CONSTRAINT integritási megszorítás alkalmazása
Hivatkozási integritás biztosítja, hogy egy adott oszlop csak olyan értékeket vehessen fel, amelyek megjelennek egy másik oszlopban. Integritási megszorításként lehet előírni.
Megszorítás – egy szabály vagy korlátozás az adatok egy részén kerül ellenőrzésre.
Integritási megszorítás – olyan szabály, amely egy vagy több oszlop lehetséges értékeinek körét határolják be. A megszorítást a tábla létrehozásánál az oszlopokhoz lehet hozzárendelni.
A CONSTRAINT záradékot a CREATE TABLE vagy ALTER TABLE parancsokban használhatjuk. A legtöbb megszorítás a CONSTRAINT záradék nélkül is megadható.
Léteznek:
táblamegszorítások
oszlopmegszorítások
Táblamegszorítás – olyan integritási megszorítás, amelyet egy tábla több oszlopára alkalmazunk. Oszlopmegszorítás pedig egy olyan integritási megszorítás, amelyet egy tábla oszlopához rendelünk.
A táblamegszorítások listája:
UNIQUE
PRIMARY KEY
FOREIGN KEY
REFERENCES
ON DELETE CASCADE
CHECK
ENABLE VALIDATE
DISABLE
Az oszlopmegszorítások:
NULL
NOT NULL
…
A többi oszlopmegszorítások a táblamegszorításokkal azonosak.
A DISABLE opciót a integritási megszorítás vagy trigger kikapcsolására (nem törlésére) alkalmazhatjuk. Leggyakrabban az ALTER TABLE parancsban alkalmazzák.
ALTER TABLE tabla DISABLE UNIQUE oszlop, oszlop,..
ALTER TABLE tabla DISABLE PRIMARY KEY
ALTER TABLE tabla DISABLE CONSTRAINT megszorítás_név
DISABLE ALL TRIGGERS
9.5. Beépített függvények
Típusok konvertálása
TO_CHAR(<number>) vagy
TO_CHAR(<number>, <format>)
TO_CHAR(<date>) vagy
TO_CHAR(<date>, <format>)
TO_DATE(<string>) vagy
TO_DATE(<string>, <format>)
TO_NUMBER(<string>)
Naptári függvények
ADD_MONTHS(<date>, n), a dátumhoz hozzáad n hónapót
ROUND(<date>)
ROUND(<date>, <format>)
Numerikus függvények
ABS(n)
COS(n)
COSH(n)
SIN(n)
SINH(n)
TAN(n)
TANH(n)
LN(n)
LOG(<base>, n) <base> - a logaritmus alapja
MOD(m, n) - m/n az osztás maradéka (mod(7,5): 2)
POWER(x,y) hatványozás (power(3,2): 9)
ROUND(n [,decimal_degits])
SIGN(n) (értékek: -1, ha n<0; 0, ha n=0; 1, ha n>0;)
CEIL(n) (ceil(10.7) : 11)
FLOOR(n) (floor(10.7): 10)
SQRT(n) (sqtr(25) : 5)
Karakteres függvények
ASCII(charakter)
CHR(n)
INITCAP(string) (Initcap(’szabó józsef’): Szabó József)
INSTR(input_string, sub_string [,n, [,m]])
Az n-ik karaktertől kezdve keresi az m-ik sub_string előfordulását az input_string-ben. Ha talált, visszaadja annak a helyét, ha nem talált, akkor az eredmény 0 lesz.
LENGTH (string) (Length(’Oracle’): 6)
LOWER (string) (Lower(’ABC’): abc)
UPPER (string)
LPAD (string, n)
LPAD (string, n[,pad_chars])
RPAD (string, n)
RPAD (string, n[,pad_chars])
LTRIM (string)
LTRIM (string [,set_of_chars])
RTRIM (string)
RTRIM (string [,set_of_chars])
SUBSTR (string, start [,length])
(Substr(’abcdef’, 3, 2): cd)
TRANSLATE (string, search_set, replace_set)
A string-ben a search_set karaktereket becseréli a megfelelő replace_set karakterekre.
TRANSLATE (’eger’, ’e’ , ’a’)=’agar’
Univerzális függvények
NVL(kifejezés, replace_value) - ha a kifejezés nem üres, akkor annak az értékét adja vissza. Ha a kifejezés NULL értékű, akkor a replace_value értéket adja vissza.
DECODE(expression, val_1, trans_1, val_2, trans_2,... val_n, trans_n, default)
A expression adatokban (pl. a Tabla oszlopában egy SELECT parancsban) a val_k értékeket helyetesíti a trans_k értékekkel. (k= 1,2,...,n). default – a többi értékeket nem változtatja meg.
Példa.
SELECT DECODE(job, ’clerk’, ’Ügyintéző’, ’president’ ’Elnök’, job) FROM emp;
JOB
-----
Elnök
ANALIST
Ügyintéző
Ügyintéző
ANALIST
Az Analist értéke nem változott meg, mivel az nem volt megadva a DECODE paraméterei között.
9.6 Fa-struktúrák alkalmazása a SELECT parancsban
Példa.
SELECT emp_no, e_name, job, fonok_no FROM emp;
emp_no e_name job fonok_no
---------- ---------- ----------- ------------
7369 Szabó clerk 7902
7499 Kiss salesman 7698
7521 Nagy salesman 7698
7698 Rontó manager 7839
7902 Orosz analist 7839
7839 Klapka president
Feladat. Egy olyan eredmény-táblát akarunk szerkeszteni, mely tartalmazza minden dolgozó és főnöke nevét. Lehet látni, hogy az eredmény struktúrája fa-szerkezetű. A hagyományos megoldás
SELECT f1.e_name, job, fonok_no FROM emp f1, emp f2
WHERE f1.fonok_no=f2.emp_no;
Az ORACLE9i-ben fa-szerkezetű lekérdezéseket lehet létrehozni. Ebben az esetben a SELECT parancs a következő opciókat tartalmazhatja:
CONNECT BY – egy táblán belül megadja az oszlopok közti kapcsolatot;
START WITH –meghatározza azt a sort, amelytől kezdődik a fa építése
SELECT emp_no, e_name, job, fonok_no FROM emp
CONNECT BY fonok_no= PRIOR emp_no
START WITH fonok_no IS NULL;
Ez a parancs a tábla sorait így rendezi át
emp_no e_name job fonok_no
---------- ---------- ----------- ------------
7839 Klapka president
7698 Rontó manager 7839
7902 Orosz analist 7839
7369 Szabó clerk 7902
7499 Kiss salesman 7698
7521 Nagy salesman 7698
9.7 NULL értékek
A parancsokban a NULL értékeket csak az IS NULL vagy IS NOT NULL operátorokkal lehet alkalmazni:
SELECT emp_no, e_name FROM emp WHERE comm IS NULL;
Ezért a következő parancs hibát tartalmaz:
SELECT emp_no, e_name FROM emp WHERE comm=NULL;
Példa.
SELECT e_name, sal+comm FROM emp;
ha a comm értéke NULL, akkor a sal+comm kifejezés értéke is NULL lesz, még ha adott is a sal érétke. A helyes megoldás a NVL függvény alkalmazása
SELECT e_name, sal+NVL(comm, 0) FROM emp;
és ha a comm értéke üres (NULL), akkor a NVL(comm, 0) függvény 0 értéket ad vissza. Lehet látni, hogy ilyen esetekben nélkülözhetetlen a NVL függvény.
9.8 Külső összekapcsolás (Lásd még 4.8.5.1)
Összekapcsolás – két vagy több tábla adatainak együttes feldolgozása egy SELECT parancsban. Külső összekapcsolás – olyan összekapcsolás, amikor az eredményben azok a sorok is jelennek meg, amelyeknek nincs megfelelője a másik táblában. A jelölése: (+).
SELECT d.dept_no, d.d_name, e.e_name
FROM dept d, emp e
WHERE d.dept_no (+) = e.dept_no;
A (+) művelet alkalmazása azt eredményezi, hogy az eredménytáblába kerül az összes dolgozó neve (e_name), és a részleg neve (d_name), de azoknak a részlegeknek a nevei is ki lesznek írva, melyekben jelenleg nem dolgozik senki.
Azonos feladat esetén, egy SELECT parancs gyorsabban hajtódik végre, ha külső összekapcsolást tartalmaz, mint a NOT IN-t tartalmazó konstrukció.
Például:
SELECT e_name, dept_no FROM emp
WHERE dept_no NOT IN (SELECT dept_no FROM dept);
vagy
SELECT e_name, dept_no FROM emp e, dept d
WHERE e.dept_no = e.dept_no(+) AND d.dept_no IS NULL;
9.9 Halmaz műveletek
UNION (egyesítés) – két lekérdezés eredményeinek unióját képezi. Az eredmény-táblába olyan sorok kerülnek, melyeket legalább az egyik tábla tartalmaz, de ismétlődő sorokat nem tartalmaz az eredmény-tábla;
INTERSECT (metszet) – két lekérdezés eredményeinek metszetét képezi. Olyan sorokat kapunk, melyek mindkét táblában előfordulnak;
MINUS (kivonás) – két lekérdezés eredményeinek különbségét képezi. Azokat a sorokat kapjuk, melyeket az első tábla tartalmazza, a másik – pedig nem.
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
UNION
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
INTERSECT
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
MINUS
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
9.10 Táblák módosítása
INSERT – új sor beszúrása
UPDATE – adatok módosítása a már létező sorokban
DELETE – sorok törlése
TRUNCATE – az összes sorok gyors törlése
9.10.1 Sorok beszúrása a táblába (INSERT parancs)
Ha az adatokat a sor összes mezőjébe akarjuk beszúrni, akkor a mező-listát nem szükséges megadni. A mezők neveit akkor kell megadni, amikor csak egyes mezőkbe akarunk adatokat beszúrni. A NULL (üres értékeket) az adatok közt lehet megadni, de ha az adat-lista nem tartalmaz egy mezőt, akkor is az NULL értéket fog kapni.
Példa.
Először az SQL*Plus-ban ellenőrizzük a testtab tábla struktúráját:
DESCRIBE testtab;
NAME NULL ? TYPE
--------- ---------- --------
COL1 VARCHAR2(10)
COL2 NUMBER(38)
INSERT INTO testtab(col1, col2) VALUES(’szöveg’, 123);
Ugyan ezt az eredményt kapjuk, ha az
INSERT INTO testtab VALUES (’szöveg’, 123);
parancsot alkalmazzuk.
A NULL-értékeket beszúrása-
INSERT INTO testtab (col1, col2) VALUES (’szöveg’, NULL);
vagy
INSERT INTO testtab (col1) VALUES (’szöveg’);
Arra is van lehetőség, hogy a táblába az INSERT parancs egyszerre több sort szúrjon be (e célból alkalmazzuk a beágyazott SELECT parancsot)
INSERT INTO testtab (col1, col2)
SELECT e_name, emp_no FROM emp;
9.10.2 Tábla létrehozása egy másik tábla alapján
CREATE TABLE emp_copy AS
SELECT * FROM emp;
CREATE TABLE emp_copy2 AS
SELECT emp_no, e_name FROM emp
WHERE e_name LIKE ’%a%’;
SELECT * FROM emp_copy2;
EMP_NO E_NAME
-------------- -------------
7499 allen
7654 martin
9.10.3 Adatok módosítása (UPDATE parancs)
Az UPDATE parancs módosítja az összes olyan sorokat, amelyekre teljesül a WHERE-feltétel. Ha az UPDATE parancs WHERE- feltételt nem tartalmaz, akkor a módosítás minden sorban végrehajtódik. Ez nagyon ritkán fordul elő.
Példa.
UPDATE emp_copy2 SET e_name=’Kovács’
WHERE emp_no=7499;
UPDATE emp_copy2 ec SET (emp_no, e_name) =
(SELECT emp_no, e_name FROM emp e
WHERE e.emp_no=ec.emp_no)
WHERE e_name LIKE ’I%’;
Az utolsó parancsban ec és e a táblák másodlagos nevei. Az utolsó WHERE-feltétel az egész parancshoz tartozik (az UPDATE-hoz), és azokat a sorokat adja meg, amelyeket módosítani akarunk. A beágyazott SELECT parancs azokat az értékeket szerkeszti, melyek bekerülnek az emp_copy2 táblába. A SELECT-ben a WHERE-feltétel összekapcsolja a két tábla megfelelő sorait.
9.10.4 Sorok törlése (DELETE parancs)
DELETE FROM emp_copy2 WHERE emp_no=7876;
DELETE FROM emp_copy2 WHERE emp_no IN
(SELECT emp_no FROM emp_copy);
Mindegyik SQL parancsban függvényeket lehet alkalmazni.
Példa.
UPDATE emp_copy SET e_name=UPPER( SUBSTR(e_name, 1, 1)) || LOWER(SUBSTR(e_name, 2, LENGTH(e_name)-1));
Ugyan ezt az eredményt kapjuk, ha az INITCAP függvényt alkalmazzuk.
Adatok gyors törlése
A tábla összes sorait gyorsan lehet törölni a TRANCATE paranccsal:
TRANCATE TABLE emp_copy;
A parancs végrehajtása után a tábla struktúrája megmarad, de az egyetlen sort sem fog tartalmazni.
9.11 Tranzakciók
Tranzakció – SQL parancsoknak olyan sorozata, amelyet az Oracle egyetlen egységként kezel. A tranzakció által okozott változásokat az AB-ban a COMMIT parancs véglegesíti.
Véglegesítés – az adatok változásainak átvezetése az AB-ba. A változások érvénytelenítését a ROLLBACK parancs hajtja végre. Ez alapján az AB-ban történt változtatások vagy ténylegesen végrehajtódnak, vagy valami okból – nem.
Az elosztott tranzakció olyan adatokkal hajtódik végre, amelyek az elosztott AB-ban, hálózaton, több csomópontban tárolódnak.
Kétfázisú véglegesítés – az Oracle az elosztott tranzakciók kezelését a kétfázisú véglegesítéssel végzi. Ez biztosítja, hogy egy tranzakció a hálózat minden csomópontjában vagy véglegesítődik, vagy visszagörgetésre kerül.
Bankautomata működésének folyamata, mint egy tranzakció példája.
1. Lekérdezzük a számlaegyenlegünket
SELECT account_balance FROM bank_table WHERE account_number=1111111
AND account_type= ’SAVINGS’;
Az SQL-parancs az SGA-n keresztül a kiszolgáló-folyamathoz kerül, amely ellenőrzi, hogy a az SQL-terület tartalmazza-e parancs futtatható változatát. Ha a parancs nincs ott, akkor elemzi a parancsot, és azt a végrehajtható formában az SQL-területre helyezi és utána végrehajtja. A kliens gyorsító-tárból leolvassa az egyenleget és közli azt a felhasználóval. Például, legyen az 250000 Ft.
Utána kérünk 20000 forintot. A kliens-folyamat fogadja a kérésünket, és az alapján szerkeszt egy SQL-parancsot
UPDATE bank_table SET account_balance=230000 WHERE WHERE account_number=1111111 AND Account_type= ’SAVINGS’;
Ezt a folyamatot bővebben lépésenként így lehet leírni:
1. A kliens-folyamat a parancsot az SGA-n keresztül eljuttatja a kiszolgáló-folyamathoz.
2. A kiszolgáló-folyamat ellenőrzi, hogy rendelkezésére áll-e a parancs végrehajtható formája. Ha Igen, akkor a 4 lépésben, ha Nem – akkor a 3 lépésben folytatódik a feldolgozás.
3. Létrehozza a parancs végrehajtható formáját és az SQL-területre helyezi.
4. Végrehajtja a parancsot.
5. A manipulált adatok az adatgyorsítóban vannak? Ha Igen - 7, ha Nem – 6.
6. Az adatokat az Oracle beolvassa az adatállományból az adatgyorsítóba.
7. Oracle rögzíti az adat régi értékét a visszagörgető szegmensbe (25000).
8. Oracle másolatokat készít a tranzakcióról a változásnaplóban.
9. Az adatgyorsító-tárban lévő adatot megváltoztatja az új értékre (23000).
10. A bankautomata jelzi, hogy befejezte a tranzakciót.
11. Az az esemény, hogy befejeződött a tranzakció, rögzítésre kerül a változásnaplóban.
12. Az Oracle törli a visszagörgető szegmensben tárolt visszaállítási információt.
13. Az automata kiadja a pénzt.
Az első tranzakció akkor kezdődik, amikor a felhasználó belép a rendszerbe és elindít egy művelet sorozatot az AB-ban. A következő tranzakciók a COMMIT vagy a ROLLBACK paranccsal kezdődik.
A COMMIT parancs a tranzakció által végzett módosítások véglegesítésére használható. A COMMIT explicit használata nélkül a program egészének végrehajtása egyetlen tranzakcióként tekintendő és nem kerül véglegesítésre a program befejeződéséig. Ennek az a hátránya, hogy ez idő alatt a többi felhasználó hozzáférését gátolja. A COMMIT parancsot ajánlatos használni minél gyakrabban.
A tranzakció végét a COMMIT vagy a ROLLBACK parancsok jelzik. A tranzakció alatt végrehajtott módosítások véglegesen a táblákban a csak a COMMIT parancs által történnek. A ROLLBACK parancs esetén ezek a változtatások nem lesznek rögzítve a táblákban, ami azt jelenti, hogy a ROLLBACK parancs után a táblák tartalma a tranzakció kezdeti állapotában kerül.
Például, ha egy UPDATE parancs több mint egy sort módosít, és hiba csak az egyik sorban történt, akkor is a ROLLBACK parancs a tábla egyetlen sora sem kerül módosításra.
A tranzakció végrehajtása alatt az Oracle zárolhatja a tábla sorait. Az Oracle csak azokat a sorokat zárolja, amelyekkel az INSERT, UPDATE, DELETE parancsok hajtják végre a műveleteket. A zárolás automatikusan történik, és a felhasználónak nem kell azzal foglalkozni. Mivel a zárolás csak egyes sorokat érint (és nem az egész táblát), ez idő alatt a táblával a többi felhasználó párhuzamosan dolgozhat.
Az Oracle-ban lehetőség van a visszalépést a tranzakció bár-melyik pontjára végrehajtani. E célból a SAVEPOINT parancsot alkalmazhatjuk. Ha létrehoztunk egy SAVEPOINT pontot, akkor a visszalépést a ROLLBACK TO SAVEPOINT paranccsal lehet végrehajtani.
Példa.
SAVEPOINT MyPoimt;
Savepoint created.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7499 allen
7566 jones
7788 scott
7654 martin
5 rows selected.
DELETE FROM emp WHERE e_name LIKE ’%a%’;
2 rows deleted.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7566 jones
7788 scott
3 rows selected.
ROLLBACK TO SAVEPOINT MyPoint;
Rollback complete.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7499 allen
7566 jones
7788 scott
7654 martin
5 rows selected.
9.12 Privilégiumok
Privilégium (jogosultság) a felhasználó számára lehetővé teszi, hogy az AB-ban bizonyos műveleteket hajthasson végre.
A privilégium kéttípusú lehet:
· rendszer-privilégium;
· objektum-privilégium.
A rendszer-privilégiumok lehetővé teszik adatdefiníciós és adatvezérlő parancsok végrehajtását, és az AB-ba való belépést. Az objektum-privilégiumok az AB objektumokkal való műveletekhez adnak jogosultságot. A felhasználó a létrehozása után egyetlen privilégiummal sem rendelkezik, és a privilégiumokat az AB adminisztrátortól később kapja. Amikor a felhasználó kap egy privilégiumot, utána az engedélyezett műveteket végrehajtatja a felsorolt AB-objektumaival.
Egy AB-hoz általános esetben több felhasználó is kapcsolódhat. Az Oracle-ban minden objektumnak van felhasználó-tulajdonosa. A nem tulajdonos-felhasználó csak akkor végezhet bizonyos műveleteket az objektumokkal, ha megkapta a megfelelő privilégiumokat. Létezik több mint nyolcvan rendszer-privilégium:
ALTER
DELETE
EXECUTE
INDEX
INSERT
REFERENCES
SELECT
UPDATE
…
A következő táblázat tartalmazza egyes privilégiumok és AB-objektumok közti lehetséges kapcsolatokat.
Privilégium
Table
View
Sequence
Procedure
ALTER
+
+
DELETE
+
+
EXECUTE
+
INDEX
+
INSERT
+
+
REFERENCES
+
SELECT
+
+
+
UPDATE
+
+
A INSERT, UPDATE és REFERENCES privilégiumokat lehet a tábla egyes oszlopaihoz kötni. Ha megakarjuk tudni, hogy milyen rendszer privilégiumokat lehet alkalmazni, végre kell hajtani a következő parancsot:
SELECT UNIQUE privilege FROM dba_sys_priv;
9.12.1 Privilégiumok adományozása
Az AB adminisztrátor a privilégiumokat a GRANT paranccsal adhatja meg a felhasználóknak:
GRANT privilégium_lista ON objektum_lista TO felhasználó_lista
[WITH GRANT OPTION];
GRANT privilégium_lista ON objektum_lista TO szerepkör_lista
[WITH GRANT OPTION];
GRANT privilégium_lista ON objektum_lista TO PUBLIC
[WITH GRANT OPTION];
A WITH GRANT OPTION esetén a felhasználó az adott privilégiumot más felhasználónak is tovább adhatja.
Példa.
GRANT SELECT, UPDATE ON emp_copy TO test_user;
A test_user felhasználó az emp_copy táblával végrehajthatja a SELECT és UPDATE parancsokat. Ezekben a parancsokban nem elég a tábla nevét emp_copy megadni, mivel a tábla tulajdonosát is meg kell adni. Például, ha a scott felhasználó az emp_copy tábla tulajdonosa, akkor a helyes hivatkozás:
SELECT * FROM scott.emp_copy;
Bizonyos esetekben ez a követelmény problémát is okozhat. Például, ha a tábla tulajdonosa a program létrehozása és futtatási ideje között megváltozott, akkor ezt figyelembe kell venni az összes táblára való hivatkozásban. Ilyen esetekben célszerű alkalmazni a tábla szinonimáját:
CREATE SYNONIM test FOR scott.emp_copy;
A scott.emp_copy tábla megkapta a test szinonimát. Ha ezek után megváltozik a tábla tulajdonosa, akkor továbbra is a táblára lehet hivatkozni a szinonima segítségével
SELECT * FROM test;
A PUBLIC opció esetén az adott privilégiumokat az összes felhasználóra érvényes, ami azt jelenti, hogy az objektum nyilvános. A Nyilvános objektum elérhető, látható az összes felhasználó számára.
GRANT SELECT, UPDATE ON emp_copy TO PUBLIC;
Ha a privilégium tartalmazza az ANY opciót, akkor az az AB összes táblájára érvényes. A következő privilégiumok esetén:
DELETE ANY TABLE
UPDATE ANY TABLE
INSERT ANY TABLE,
a felhasználó az AB összes tábláit módosíthatja, még akkor is, ha nem tulajdonosa a táblának. Ezt a legnagyobb lehetséges jogosultság, és csak az adminisztrátor szintű felhasználó kaphatja azt.
A SESSION_PRIVS nézetben megtalálhatók az aktuális privilégiumok. Az ALL_TAB_PRIVS és ALL_COL_PRIVS nézetekből pedig megtudhatjuk, hogy milyen privilégiumokkal rendelkeznek a felhasználók.
9.12.2 Szerepkörök (ROLE)
Szerepkör – a privilégiumok együttese, és lehetőség a felhasználók csoportosítására. A felhasználókat egy csoportba lehet beosztani, és a csoporton belül mindegyik felhasználó azonos jogosultsággal rendelkezik. Például, létrehozunk egy szerepkört
CREATE ROLE kozos;
utána a szerepkörhöz privilégiumokat kapcsolunk
GRANT INSERT ON table_a TO kozos;
GRANT INSERT ON table_b TO kozos;
GRANT INSERT, DELETE ON table_c TO kozos;
GRANT UPDATE ON table_d TO kozos;
GRANT DELETE ON table_e TO kozos;
GRANT SELECT ON table_f TO kozos;
Ha a felh_1 és felh_2 felhasználók megkapják a kozos szerepkört
GRANT kozos TO x;
GRANT kozos TO y;
akkor rendelkezni fognak az összes kozos szerepkörhöz tartozó jogosultságokkal.
9.12.3 Beépített szerepkörök
Az Oracle-ban léteznek beépített szerepkörök is:
CONNECT-
· ALTER SESSION
· CREATE CLUSTER
· CREATE DATABASE LINK
· CREATE SEQUENCE
· CREATE SESSION
· CREATE SYNONIM
· CREATE TABLE
· CREATE VIEW
RESOURSE-
· CREATE CLUSTER
· CREATE PROCEDURE
· CREATE SEQUENCE
· CREATE TABLE
9.12.4 Jogosultság a programok végrehajtására
Az AB-ban tárolódhatók
· Eljárások (PROCEDURE)
· Csomagok (PACKAGE)
· Függvények (FUNCTION).
Ezek az objektumok csak akkor érhetők el, ha a felhasználó EXECUTE privilégiummal rendelkezik.
Példa.
GRANT EXECUTE ON my_package TO PUBLIC;
GRANT EXECUTE ON my_func TO felh_2;
GRANT EXECUTE ON my_proc TO felh_1;
9.12.5 Privilégiumok visszavonása
Az AB adminisztrátor a privilégiumot a felhasználótól a REVOKE parancs által visszavonhat:
REVOKE privilégium ON objektum FROM felhasználó
[CASCADE CONSTRAINTS];
A CASCADE CONSTRAINTS a REFERENCES privilégium megvonása esetén törli az összes hivatkozási integritási megszorítást, amelyet a felhasználó hozott létre (CASCADE – lépcsőzetes).
REVOKE UPDATE ON emp_copy FROM test_user;
Ez a parancs után a test_user felhasználó nem módosíthatja a emp_copy táblát, de a SELECT parancsot továbbra is alkalmazhatja.
REVOKE SELECT ON classes FROM user_1;
REVOKE ALTER TABLE, EXECUTE ANY PROCEDURE FROM user_2;
REVOKE kozos FROM felh_1;
9.13 Indexek
Indexeket azzal a céllal hozzák létre, hogy a tábla bizonyos oszlopainak értékei ne ismétlődjenek, vagy (és) hogy gyorsabban történjen az adatok keresése. Az index létrehozása után azok a parancsok, melyek módosítják a táblát (UPDATE, DELETE, INSERT), az indexek szerinti sorrendjét továbbra is aktuális állapotban tartják. Ez időt igényel, és ezért minél több indexe van egy táblának, annál lassabban hajtódnak végre az UPDATE, DELETE, INSERT parancsok. A SELECT parancs a WHERE része alapján határozza meg a szükséges és felhasználandó indexeket, és ez biztosítja a parancs leggyorsabb végrehajtását.
Az indexeket létre lehet hozni:
· direkt módon, a CREATE INDEX paranccsal,
· automatikusan, a CREATE TABLE parancsban,
· ALTER TABLE paranccsal.
Használhatók:
· egyedi (nem ismétlődő) indexek, az értékei különbözőek, amikor a CREATE TABLE parancs a PRIMARY KEY vagy UNIQUE megszorításokat tartalmazza;
· ismétlődő értékeket tartalmazó indexek.
Példa.
CREATE INDEX Test_ind ON Test(col1)
TABLESPACE users
STORAGE (INITIAL 20K
NEXT 20K
PCTINCREASE 75);
Példa.
CREATE TABLE sample_3
(col_a VARCHAR(30),
col_b VARCHAR(30),
col_c VARCHAR(30));
CREATE INDEX col_c_ind ON sample_3(col_c) ;
CREATE UNIQUE INDEX col_a_ind ON sample_3(col_a) ;
A cola_ind index nem tartalmazhat ismétlődő értékeket, a colc_ind index pedig tartalmazhat.
A táblák indexeit a user_indexes nézetből lehet lekérdezni.
Példa.
SELECT index_name FROM user_indexes
WHERE table_name=’SAMLE_3’;
INDEX_NAME
-------------------
COL_A_IND
COL_B_IND
Láthatjuk, hogy a sample_3 táblához két index tartozik COL_A_IND, COL_B_IND. A következő parancs megsemmisíti (DESABLE) a COL_A_IND indexet.
ALTER TABLE semple_3 DESABLE CONSTRAINT COL_A_IND;
SELECT index_name FROM user_indexes
WHERE table_name=’SAMPLE_3’;
INDEX_NAME
-------------------
COL_B_IND
Most a semple_3 táblához csak egy COL_B_IND index tartozik. A következő parancs visszaállítja (ENABLE) a COL_A_IND indexet:
ALTER TABLE semple_3 ENABLE CONSTRAINT COL_A_IND;
A CREATE, ALTER parancsokban meg lehet adni, hogy az Oracle az indexek tárolására menyi memóriát adjon:
ALTER TABLE emp ADD CONSTRAINT pk_emp PRIMARY KEY (emp_no)
USING INDEX
INITRANS 5
MAXTRANS 10
TABLESPACE user_date
STORAGE ( INITIAL 20K
NEXT 20K
MINEXTENTS 1
MAXEXTENTS 99
PCTINCREASE 0)
PCTFREE 10;
Ha egy táblában a FOREIGN KEY vagy REFERENCES megszorításokkal külső kulcsokat hozunk létre, akkor azokat is kell indexelni, hogy a táblák közti kapcsolatot létrehozása után gyorsabban lehessen végrehajtani az adatok keresését:
ALTER TABLE emp ADD CONSTRAINT fk_demt FOREIGN KEY (dept_no)
REFERENCES dept(dept_no);
CREATE INDEX fk_dept_ind ON emp(dept_no) ;
A fk_dept_ind index ismétlődő értékeket tartalmazhat. Ezek után a következő parancs
gyorsabban hajtódik végre:
SELECT e.e_name, d.name FROM emp e, dept d
WHERE e.dept_no=d.dept_no;
Nagy táblák esetén az indexek megsemmisítése és visszaállítása sok időt igényelhet. Az indexet ideiglenesen is kikapcsolhatjuk (KEEP opcióval), úgy hogy az index továbbra is létezzen. Például,
ALTER TABLE emp KEEP INDEX pk_emp;
A DROP INDEX parancs az indexet véglegesen megsemmisíti, ha az nem PRIMARY KEY vagy UNIQUE index.
DROP INDEX Test_ind;
Sok esetben a programok indexelés nélkül is alkalmazhatók, de a végrehajtásuk lassabb lesz (legalább is elméletileg). Ne felejtsük, hogy gyakorlati szempontból mindegyik táblában kell, hogy legyen legalább egy PRIMARY KEY vagy UNIQUE index. Az indexeket az indexszegmens tartalmazza.
9.14 Táblák integritása
A UNIQUE és PRIMARY KEY indexeket az Oracle automatikusan hoz létre, amikor a CREATE TABLE parancsot végrehajtja
CREATE TABLE test (test_no NUMBER(5), …,
PRIMARY KEY(test_no), …);
A már létező táblában is létrehozhatunk elsődleges kulcsot:
ALTER TABLE test ADD
PRIMARY KEY(test_no);
Figyelem! Ha a tábla már tartalmaz sorokat, és azoknak az adatai a létrehozandó indexel konfliktusban vannak, akkor az ALTER parancs hibát jelez.
Az indexeket lehet törölni, vagy kikapcsolni törlés nélkül. Ezeket a műveleteket nem lehet végrehajtani, ha egy másik tábla idegen kulcsa hivatkozik az adott kulcsra.
Az ENABLE opció által egy indexet bekapcsolhatunk, az index kikapcsolására a DISABLE opció szükséges. Az alapértelmezés alapján (ha nincs megadva sem az ENABLE sem a DISABLE opció) az Oracle az ENABLE opciót fogja értelmezni.
ALTER TABLE test DISABLE PRIMARY KEY;
Ha ki akarjuk kapcsolni egy kapcsolatban levő idegen kulcsot, akkor ezt így lehet megvalósítani
ALTER TABLE test DISABLE PRIMARY KEY CASCADE;
Az index törlését hasonló képen lehet végrehajtani:
ALTER TABLE test DROP PRIMARY KEY;
Ha az index az ENABLE állapotban van, akkor a táblák közti integritási kapcsolatok minden módosítási művelet után is érvényesek maradnak. A DISABLE állapotban az integritási kapcsolatok megsérülhetnek. Ha az integritási kapcsolat egyszer megsérül, akkor az Oracle az indexet az ENABLE állapotába már nem képes visszaállítani.
9.15 Szekvenciák (sorozatok)
Ha egy Oracle alkalmazásban szükség van egy numerikus adatsorozatra (például, elsődleges kulcsra), melynek az értékei egyediek legyenek, akkor szekvenciákat lehet alkalmazni.
Szekvencia – egy olyan Oracle objektum, amely képes számokat generálni, és elérhetővé téve őket a sorszámozott elsődleges kulcsok számára.
Szekvenciák létrehozása:
CREATE SEQUENCE sor START WITH n
A START WITH n – megadja szekvencia kezdő értékét.
A szekvencia aktuális értékét a
sor.CURRVAL
attribútum adja vissza.
A szekvencia következő értékét (elemét) a
sor. NEXTVAL
attribútummal lehet megkapni.
Példa.
Ha a student tábla id mezője elsődleges kulcs, akkor annak az értékeit a student_sequence szekvencia által kapjuk meg:
CREATE SEQUENCE student_sequence START WITH 10000;
INSERT INTO students (id, first_name, last_name, major, current_credits)
VALUES (student_sequence.NEXTVAL, 'Scott', 'Smith', 'Computer Science', 0);
INSERT INTO students (id, first_name, last_name, major, current_credits)
VALUES (student_sequence.NEXTVAL, 'Margaret', 'Mason', 'History', 0);
SELECT id FROM students;
ID
-------
10001
10002
A szekvenciát általánosabb formában is létre lehet hozni:
CREATE SEQUENCE test_seq
INCREMENT BY 4
START WITH 50
MAXVALUE 70
MINVALUE 50
CYCLE
CACHE 3;
A test_seq szekvencia a következő sorozatot fogja generálni
50, 54, 58, 62, 66, 70, 50, 54,...
Az INCREMENT BY 4 az jelenti, hogy a szekvencia értékei néggyel fognak növekedni, hanem néggyel,
a MAXVALUE értékének elérése után a CYRCLE újból visszaállítja a MINVALUE értéket. A CACHE 3 egyszerre három generált számot fog elhelyezni a SGA-kesbe.
Figyelembe kell venni, hogy a ROLLBACK parancs a szekvencia kezdő állapotát nem állítja vissza, mely a tranzakció elején volt aktuális.
A szekvencia módosítása:
ALTER SEQUENCE test_seq
INCREMENT BY 10
MAXVALUE 1000
MINVALUE 50
NOCYCLE
CACHE 20;
és törlése:
DROP SEQUENCE test_seq;
9.16 Klaszterek (Fürtök)
Klaszter – olyan táblák adatainak együttes tárolása, amelyek közös adatokat tartalmaznak, és egy időben kerülnek feldolgozásra.
Klaszterkulcs – a klaszterizált táblák közös oszlopai közül azok az oszlopok, amelyek a tárolás vagy elérés kulcsául szolgálnak.
Ha a lekérdezések gyakran hivatkoznak két táblából álló összekapcsolt tábla-együttesre, akkor az AB adminisztrátor úgy dönthet, hogy ezeket a táblákat közösen egy klaszterben tárolja. A klasztert a CREATE CLASTER paranccsal lehet létrehozni.
Példa.
CREATE CLASTER Diak_Tanar (tantargy NUMBER(3))
TABLESPACE users
STORAGE( INITIAL 200K
NEXT 300K
MINEXTENTS 2
MAXEXTENTS 20);
A tantargy oszlop a klaszter kulcsa, és általa valósul meg a két tábla közti kapcsolat.
A már létező klaszterben táblákat lehet létrehozni:
CREATE TABLE Diak(tantargy NUMBER(3) PRIMARY KEY, …)
CLUSTER Diak_Tanar (tantargy);
CREATE TABLE Tanar(nev VARCHAR2(15) NOT NULL, …
tantargy NUMBER(3) REFERENCES Diak)
CLUSTER Diak_Tanar (tantargy);
A klaszter indexét még akkor kell létrehozni, amikor a táblák üresek, egyetlen sort sem tartalmazhat.
CREATE INDEX Diak_Tanar_Index
ON CLUSTER Diak_Tanar
TABLESPACE users
STORAGE( INITIAL 50K
NEXT 50K
MINEXTENTS 2
MAXEXTENTS 20);
A klasztert és az indexét különböző táblaterületben lehet tárolni. Ha töröljük a klaszter indexét, akkor a klaszter tábláit már nem lehet használni.
A klaszter módosítása az ALTER CLUSTER paranccsal történik:
ALTER CLUSTER Diak_Tanar
PRTFREE 30;
9.17 Nézetek (VIEW)
A nézet tartalmazza egy SQL-lekérdezés eredményét. A programokban ugyanúgy alkalmazhatjuk a nézeteket, mint a táblákat. Mivel a nézetek az AB-ban nem tárolódnak, úgy is lehet rájuk tekinteni, mint virtuális táblákra. Egy nézetet úgy is értelmezhetjük, mint egy tárolt SELECT parancs eredménytábláját, mely a nézet mindegyik megnyitásakor újból létrejön.
A nézet létrehozása:
CREATE VIEW v_customer_sales_rgn AS
SELECT surname, sales_region FROM customer;
A nézeteket a parancsokban úgy alkalmazhatjuk, mint a táblákat:
SELECT * FROM v_customer_sales_rgn;
A nézetet akkor nevezzünk egyszerűnek, ha az nem tartalmaz:
agregáló függvényt;
felhasználó által létrehozott függvényt;
beágyazott lekérdezést;
lekérdezések unióját.
A nézet nem tartalmazhat
ORDER BY
FOR UPDATE
záradékokat.
Az egyszerű nézet INSERT, DELETE, UPDATE parancsokkal módosítható. A módosítások azokban az táblákban rögzítődnek, amelyek alapján a nézetet szerkesztették.
A nézeteket kényelmes alkalmazni az összetett lekérdezések helyet:
CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.emp_no, e.e_name, d.dept_no, d.d_name
FROM emp e, dept d
WHERE e.dept_no=d.dept_no;
és
SELECT * FROM emp_dept_view;
Előfordulhat, hogy a módosítások után a táblában olyan változások történnek, hogy a tábla egyes sorai már nem kerülnek be a következő VIEW-lekérdezésbe, mivel nem felelnek meg a WHERE-feltételnek. Ilyen módosításokat meg lehet akadályozni, ha a nézet létrehozásának parancsa a WITH CHECK OPTION megszorítást tartalmazza.
A nézetet az ALTER paranccsal nem lehet módosítani. A módosítást csak úgy lehet végrehajtani, hogy először töröljük a nézetet
DROP VIEW test;
és utána újból létrehozzuk a nézetet, de már a módosított változatában.
A nézeteket biztonsági okokból is szokták alkalmazni. Például, ha egy felhasználónak egy tábla csak bizonyos oszlopait vagy sorait engedélyezzük elérni, akkor egy olyan nézetet hozunk létre, mely csak a megengedett adatokat tartalmazza, a felhasználó, pedig megkapja a megfelelő privilégiumokat erre a nézetre.
9.18 Szinonimák
Szinonima – egy olyan név, melyet táblához vagy nézethez lehet hozzárendelni, és az eredeti név helyett használni.
A szinonima létrehozása után a parancsokban az objektum eredeti neve helyett a szinonimával lehet rá hivatkozni.
Léteznek személyes és nyilvános (PUBLIC) szinonimák. A személyes szinonimákat egy-egy felhasználó hozza létre, és a továbbiakban csak ő használhatja.
CONNECT test/test
CREATE SYNONIM emp FOR scott.emp
A Test nevű felhasználó az emp táblára, melynek a tulajdonosa scott, létrehozott emp nevű szinonimát.
A nyilvános szinonimákat csak az AB adminisztrátor hozhat létre, és az ilyen szinonimát mindegyik olyan felhasználó alkalmazhatja, aki megfelelő privilégiummal rendelkezik
CREATE PUBLIC SYNONIM emp FOR scott.emp
A szinonima törlése:
DROP SYNONIM emp;
A távoli AB objektumára is lehet szinonimát létrehozni
CREATE PUBLIC SYNONIM synon FOR felh.aru@AB_1
A synon nevű nyilvános szinonimát hoztunk létre a távoli AB_1 AB-ban a felh.aru táblára.
DDL (Data Definition Language)
ALTER PROCEDURE
ALTER TABLE
ANALYZE (a teljesítmény statisztikáját gyűjti)
ALTER TABLE ADD CONSTRAINT
CREATE TABLE
CREATE INDEX
DROP INDEX
DROP TABLE
GRANT
TRUNCATE
REVOKE
DML (Data Manipulation Language)
INSERT
DELETE
UPDATE
SELECT
COMMIT WORK
ROLLBACK
9.2 Táblák létrehozása
A táblákat a CREATE TABLE paranccsal lehet létrehozni. Egy táblában <=1000 oszlop lehet. Több adattípust is lehet alkalmazni, de gyakorlatilag csak néhányra van szükség.
NUMBER(h, t) – numerikus adatok, hossza<=38, h a szám hosszát tartalmazza, t – a tizedes-jegyek számát;
DATE – dátum és idő típus;
VARCHAR2(méret) – karakter típus, a hossza váltózó (max hossza<=4000);
CHAR(méret) – karakter típus, fix hosszúságú (max hossza<=2000);
NCHAR(méret) – azonos a CHAR típussal, de a max méret függ a karakterkészletétől,
LOB (large objects) – bináris v. szöveges formátum. Lehet kép-, hang-, vagy nagy méretű szöveges állomány.
A LOB típuson belül lehetnek:
· LONG – szöveges adatok, max hossza<=2 Gbyte;
· LONG RAW – bináris adatok, max hossza<=2 Gbyte;
A LONG és LONG RAW típusokat csak egyszerű adatfeldolgozásban alkalmazzák.
· CLOB, NCLOB, BLOB – belső LOB típusok, mivel az AB-ban tárolódnak, max hossza<=4 Gbyte;
· CLOB – az adatokat tárolja az AB karakter-készlete alapján;
· NCLOB – az adatokat tárolja a nemzeti karakter-készletben.
Az Oracle mindegyik táblába automatikusan helyez egy ROWID nevű pszeudooszlopot, amely a programozók ritkán szokták használni.
ROWID – pszeudooszlop, amely tartalmazza a sor logikai egyedi címét. A ROWID nem változható meg, de a SELECT parancsban lekérdezhető:
SELECT rowid FROM tabla_1;
A Sor sorszáma – olyan szám, amely akkor rendelődik a sorhoz, amikor az bekerül a táblába. Ez a szám része a ROWID-nek.
Csak az a felhasználó hozhat létre táblákat, aki CREATE TABLE vagy CREATE ANY TABLE privilégiummal rendelkezik.
A STORAGE paraméter alkalmazása a CREATE TABLE parancsban
Egy táblát a STORAGE memória-paraméterek nélkül is lehet létrehozni. Ebben az esetben a tábla az alapértelmezési értékeket kapja, ami nem mindig jó megoldás. A memória egységeket (szegmenseket), melyekben a táblák tárolódnak, extentnek nevezzük. Az első extent neve INITIAL, a többi extentek pedig másodlagos extentek.
CREATE TABLE testtab
(col1 VARCHAR2(10))
STORAGE (INITIAL 100K
NEXT 50K
MINEXTENTS 1
MAXEXTENTS 99
PCINCREASE 20);
Az első extent 100K memóriát kap, a második – 50K. A PCINCREASE 20 érték alapján mindegyik következő extent mérete 20% növekszik az előzőhez képest. MINEXTENTS 1 azt jelenti, hogy a tábla először 1extentent kap, a MAXEXTENTS 99 – a tábla maximálisan 99 extentet kaphat.
9.3 Táblák partíciónálása
A táblákat, mint az indextáblákat is, particionálhatjuk. A particionálás lehetőséget ad a nagyon nagy táblák és indextáblák kezelésére. A particionálás során a nagy táblát kisebb és könnyebben kezelhető részekre osztja a rendszer.
Partíciónált tábla – olyan tábla, amelynek sorai kisebb azonos szerkezetű táblákba, partíciókra, vannak szétosztva.
A partíciók fizikailag különböző helyeken tárolhatjuk.
A partíciónálás előnyei:
Az I/O-terhelés jobb eloszlása
Biztonsági mentés és visszaállítás egyszerűbb végrehajtása
Az adatsérülés lehetőségének minimalizálása
Az archiválási folyamat segítése.
Példa.
CREATE TABLE nagy_tabla
(col1 VARCHAR2(10),
(col2 VARCHAR2(10))
)
PARTITION BY RANGE (col1, col2)
(PARTITION p1 VALUES LESS THEN (…) TABLESPACE p1,
PARTITION p2 VALUES LESS THEN (…) TABLESPACE p2);
Hivatkozás egy partícióra:
ALTER TABLE nagy_tabla DROP PARTITION p1;
ALTER TABLE parancs
Az oszlop hosszát lehet növelni még akkor is, ha a tábla adatokat tartalmaz. Az oszlop hosszát pedig csak akkor lehet csökkenteni, ha a tábla üres.
ALTER TABLE testtab ADD col2 VARCHAR2(100);
ALTER TABLE testtab MODIFY col2 VARCHAR2(150);
ALTER TABLE testtab STORAGE ( NEXT 10K
MAXEXTENTS 50);
ALTER TABLE testtab DROP COLUMN col1;
A táblákat átnevezhetjük:
RENAME testtab TO testtab1;
és törölhetjük:
DROP TABLE testtab;
Példa.
CREATE TABLE students(
id NUMBER(5) PRIMARY KEY,
first_name VARCHAR2(20),
last_name VARCHAR2(20),
major VARCHAR2(30), -- szak
current_credits NUMBER(3) ); -- leadott vizsgák száma
Az ORACLE-rendszer tartalmazz egy bemutató sémát, amelynek Scott a tulajdonosa:
CREATE TABLE scott.dept
(deptno NUMBER(2) NOT NULL,
dname VARCHAR2(14),
loc VARCHAR2(13),
CONSTRAINT pk_dept PRIMARY KEY (deptno));
CREATE TABLE scott.emp
(empno NUMBER(4) NOT NULL,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
sal NUMBER(7,2),
deptno NUMBER(2),
CONSTRAINT pk_emp PRIMARY KEY (empno));
Amikor egy olyan táblára (vagy más Oracle-objektumra) hivatkozunk, melynek nem mi vagyunk a tulajdonosa, akkor a tábla nevén kívül meg kell adni a tulajdonos nevét is
tulajdonos.tábla_név
9.4 CONSTRAINT integritási megszorítás alkalmazása
Hivatkozási integritás biztosítja, hogy egy adott oszlop csak olyan értékeket vehessen fel, amelyek megjelennek egy másik oszlopban. Integritási megszorításként lehet előírni.
Megszorítás – egy szabály vagy korlátozás az adatok egy részén kerül ellenőrzésre.
Integritási megszorítás – olyan szabály, amely egy vagy több oszlop lehetséges értékeinek körét határolják be. A megszorítást a tábla létrehozásánál az oszlopokhoz lehet hozzárendelni.
A CONSTRAINT záradékot a CREATE TABLE vagy ALTER TABLE parancsokban használhatjuk. A legtöbb megszorítás a CONSTRAINT záradék nélkül is megadható.
Léteznek:
táblamegszorítások
oszlopmegszorítások
Táblamegszorítás – olyan integritási megszorítás, amelyet egy tábla több oszlopára alkalmazunk. Oszlopmegszorítás pedig egy olyan integritási megszorítás, amelyet egy tábla oszlopához rendelünk.
A táblamegszorítások listája:
UNIQUE
PRIMARY KEY
FOREIGN KEY
REFERENCES
ON DELETE CASCADE
CHECK
ENABLE VALIDATE
DISABLE
Az oszlopmegszorítások:
NULL
NOT NULL
…
A többi oszlopmegszorítások a táblamegszorításokkal azonosak.
A DISABLE opciót a integritási megszorítás vagy trigger kikapcsolására (nem törlésére) alkalmazhatjuk. Leggyakrabban az ALTER TABLE parancsban alkalmazzák.
ALTER TABLE tabla DISABLE UNIQUE oszlop, oszlop,..
ALTER TABLE tabla DISABLE PRIMARY KEY
ALTER TABLE tabla DISABLE CONSTRAINT megszorítás_név
DISABLE ALL TRIGGERS
9.5. Beépített függvények
Típusok konvertálása
TO_CHAR(<number>) vagy
TO_CHAR(<number>, <format>)
TO_CHAR(<date>) vagy
TO_CHAR(<date>, <format>)
TO_DATE(<string>) vagy
TO_DATE(<string>, <format>)
TO_NUMBER(<string>)
Naptári függvények
ADD_MONTHS(<date>, n), a dátumhoz hozzáad n hónapót
ROUND(<date>)
ROUND(<date>, <format>)
Numerikus függvények
ABS(n)
COS(n)
COSH(n)
SIN(n)
SINH(n)
TAN(n)
TANH(n)
LN(n)
LOG(<base>, n) <base> - a logaritmus alapja
MOD(m, n) - m/n az osztás maradéka (mod(7,5): 2)
POWER(x,y) hatványozás (power(3,2): 9)
ROUND(n [,decimal_degits])
SIGN(n) (értékek: -1, ha n<0; 0, ha n=0; 1, ha n>0;)
CEIL(n) (ceil(10.7) : 11)
FLOOR(n) (floor(10.7): 10)
SQRT(n) (sqtr(25) : 5)
Karakteres függvények
ASCII(charakter)
CHR(n)
INITCAP(string) (Initcap(’szabó józsef’): Szabó József)
INSTR(input_string, sub_string [,n, [,m]])
Az n-ik karaktertől kezdve keresi az m-ik sub_string előfordulását az input_string-ben. Ha talált, visszaadja annak a helyét, ha nem talált, akkor az eredmény 0 lesz.
LENGTH (string) (Length(’Oracle’): 6)
LOWER (string) (Lower(’ABC’): abc)
UPPER (string)
LPAD (string, n)
LPAD (string, n[,pad_chars])
RPAD (string, n)
RPAD (string, n[,pad_chars])
LTRIM (string)
LTRIM (string [,set_of_chars])
RTRIM (string)
RTRIM (string [,set_of_chars])
SUBSTR (string, start [,length])
(Substr(’abcdef’, 3, 2): cd)
TRANSLATE (string, search_set, replace_set)
A string-ben a search_set karaktereket becseréli a megfelelő replace_set karakterekre.
TRANSLATE (’eger’, ’e’ , ’a’)=’agar’
Univerzális függvények
NVL(kifejezés, replace_value) - ha a kifejezés nem üres, akkor annak az értékét adja vissza. Ha a kifejezés NULL értékű, akkor a replace_value értéket adja vissza.
DECODE(expression, val_1, trans_1, val_2, trans_2,... val_n, trans_n, default)
A expression adatokban (pl. a Tabla oszlopában egy SELECT parancsban) a val_k értékeket helyetesíti a trans_k értékekkel. (k= 1,2,...,n). default – a többi értékeket nem változtatja meg.
Példa.
SELECT DECODE(job, ’clerk’, ’Ügyintéző’, ’president’ ’Elnök’, job) FROM emp;
JOB
-----
Elnök
ANALIST
Ügyintéző
Ügyintéző
ANALIST
Az Analist értéke nem változott meg, mivel az nem volt megadva a DECODE paraméterei között.
9.6 Fa-struktúrák alkalmazása a SELECT parancsban
Példa.
SELECT emp_no, e_name, job, fonok_no FROM emp;
emp_no e_name job fonok_no
---------- ---------- ----------- ------------
7369 Szabó clerk 7902
7499 Kiss salesman 7698
7521 Nagy salesman 7698
7698 Rontó manager 7839
7902 Orosz analist 7839
7839 Klapka president
Feladat. Egy olyan eredmény-táblát akarunk szerkeszteni, mely tartalmazza minden dolgozó és főnöke nevét. Lehet látni, hogy az eredmény struktúrája fa-szerkezetű. A hagyományos megoldás
SELECT f1.e_name, job, fonok_no FROM emp f1, emp f2
WHERE f1.fonok_no=f2.emp_no;
Az ORACLE9i-ben fa-szerkezetű lekérdezéseket lehet létrehozni. Ebben az esetben a SELECT parancs a következő opciókat tartalmazhatja:
CONNECT BY – egy táblán belül megadja az oszlopok közti kapcsolatot;
START WITH –meghatározza azt a sort, amelytől kezdődik a fa építése
SELECT emp_no, e_name, job, fonok_no FROM emp
CONNECT BY fonok_no= PRIOR emp_no
START WITH fonok_no IS NULL;
Ez a parancs a tábla sorait így rendezi át
emp_no e_name job fonok_no
---------- ---------- ----------- ------------
7839 Klapka president
7698 Rontó manager 7839
7902 Orosz analist 7839
7369 Szabó clerk 7902
7499 Kiss salesman 7698
7521 Nagy salesman 7698
9.7 NULL értékek
A parancsokban a NULL értékeket csak az IS NULL vagy IS NOT NULL operátorokkal lehet alkalmazni:
SELECT emp_no, e_name FROM emp WHERE comm IS NULL;
Ezért a következő parancs hibát tartalmaz:
SELECT emp_no, e_name FROM emp WHERE comm=NULL;
Példa.
SELECT e_name, sal+comm FROM emp;
ha a comm értéke NULL, akkor a sal+comm kifejezés értéke is NULL lesz, még ha adott is a sal érétke. A helyes megoldás a NVL függvény alkalmazása
SELECT e_name, sal+NVL(comm, 0) FROM emp;
és ha a comm értéke üres (NULL), akkor a NVL(comm, 0) függvény 0 értéket ad vissza. Lehet látni, hogy ilyen esetekben nélkülözhetetlen a NVL függvény.
9.8 Külső összekapcsolás (Lásd még 4.8.5.1)
Összekapcsolás – két vagy több tábla adatainak együttes feldolgozása egy SELECT parancsban. Külső összekapcsolás – olyan összekapcsolás, amikor az eredményben azok a sorok is jelennek meg, amelyeknek nincs megfelelője a másik táblában. A jelölése: (+).
SELECT d.dept_no, d.d_name, e.e_name
FROM dept d, emp e
WHERE d.dept_no (+) = e.dept_no;
A (+) művelet alkalmazása azt eredményezi, hogy az eredménytáblába kerül az összes dolgozó neve (e_name), és a részleg neve (d_name), de azoknak a részlegeknek a nevei is ki lesznek írva, melyekben jelenleg nem dolgozik senki.
Azonos feladat esetén, egy SELECT parancs gyorsabban hajtódik végre, ha külső összekapcsolást tartalmaz, mint a NOT IN-t tartalmazó konstrukció.
Például:
SELECT e_name, dept_no FROM emp
WHERE dept_no NOT IN (SELECT dept_no FROM dept);
vagy
SELECT e_name, dept_no FROM emp e, dept d
WHERE e.dept_no = e.dept_no(+) AND d.dept_no IS NULL;
9.9 Halmaz műveletek
UNION (egyesítés) – két lekérdezés eredményeinek unióját képezi. Az eredmény-táblába olyan sorok kerülnek, melyeket legalább az egyik tábla tartalmaz, de ismétlődő sorokat nem tartalmaz az eredmény-tábla;
INTERSECT (metszet) – két lekérdezés eredményeinek metszetét képezi. Olyan sorokat kapunk, melyek mindkét táblában előfordulnak;
MINUS (kivonás) – két lekérdezés eredményeinek különbségét képezi. Azokat a sorokat kapjuk, melyeket az első tábla tartalmazza, a másik – pedig nem.
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
UNION
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
INTERSECT
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
SELECT d_name FROM dept WHERE d_name LIKE ’%s%’
MINUS
SELECT d_name FROM dept WHERE d_name LIKE ’%o%’;
9.10 Táblák módosítása
INSERT – új sor beszúrása
UPDATE – adatok módosítása a már létező sorokban
DELETE – sorok törlése
TRUNCATE – az összes sorok gyors törlése
9.10.1 Sorok beszúrása a táblába (INSERT parancs)
Ha az adatokat a sor összes mezőjébe akarjuk beszúrni, akkor a mező-listát nem szükséges megadni. A mezők neveit akkor kell megadni, amikor csak egyes mezőkbe akarunk adatokat beszúrni. A NULL (üres értékeket) az adatok közt lehet megadni, de ha az adat-lista nem tartalmaz egy mezőt, akkor is az NULL értéket fog kapni.
Példa.
Először az SQL*Plus-ban ellenőrizzük a testtab tábla struktúráját:
DESCRIBE testtab;
NAME NULL ? TYPE
--------- ---------- --------
COL1 VARCHAR2(10)
COL2 NUMBER(38)
INSERT INTO testtab(col1, col2) VALUES(’szöveg’, 123);
Ugyan ezt az eredményt kapjuk, ha az
INSERT INTO testtab VALUES (’szöveg’, 123);
parancsot alkalmazzuk.
A NULL-értékeket beszúrása-
INSERT INTO testtab (col1, col2) VALUES (’szöveg’, NULL);
vagy
INSERT INTO testtab (col1) VALUES (’szöveg’);
Arra is van lehetőség, hogy a táblába az INSERT parancs egyszerre több sort szúrjon be (e célból alkalmazzuk a beágyazott SELECT parancsot)
INSERT INTO testtab (col1, col2)
SELECT e_name, emp_no FROM emp;
9.10.2 Tábla létrehozása egy másik tábla alapján
CREATE TABLE emp_copy AS
SELECT * FROM emp;
CREATE TABLE emp_copy2 AS
SELECT emp_no, e_name FROM emp
WHERE e_name LIKE ’%a%’;
SELECT * FROM emp_copy2;
EMP_NO E_NAME
-------------- -------------
7499 allen
7654 martin
9.10.3 Adatok módosítása (UPDATE parancs)
Az UPDATE parancs módosítja az összes olyan sorokat, amelyekre teljesül a WHERE-feltétel. Ha az UPDATE parancs WHERE- feltételt nem tartalmaz, akkor a módosítás minden sorban végrehajtódik. Ez nagyon ritkán fordul elő.
Példa.
UPDATE emp_copy2 SET e_name=’Kovács’
WHERE emp_no=7499;
UPDATE emp_copy2 ec SET (emp_no, e_name) =
(SELECT emp_no, e_name FROM emp e
WHERE e.emp_no=ec.emp_no)
WHERE e_name LIKE ’I%’;
Az utolsó parancsban ec és e a táblák másodlagos nevei. Az utolsó WHERE-feltétel az egész parancshoz tartozik (az UPDATE-hoz), és azokat a sorokat adja meg, amelyeket módosítani akarunk. A beágyazott SELECT parancs azokat az értékeket szerkeszti, melyek bekerülnek az emp_copy2 táblába. A SELECT-ben a WHERE-feltétel összekapcsolja a két tábla megfelelő sorait.
9.10.4 Sorok törlése (DELETE parancs)
DELETE FROM emp_copy2 WHERE emp_no=7876;
DELETE FROM emp_copy2 WHERE emp_no IN
(SELECT emp_no FROM emp_copy);
Mindegyik SQL parancsban függvényeket lehet alkalmazni.
Példa.
UPDATE emp_copy SET e_name=UPPER( SUBSTR(e_name, 1, 1)) || LOWER(SUBSTR(e_name, 2, LENGTH(e_name)-1));
Ugyan ezt az eredményt kapjuk, ha az INITCAP függvényt alkalmazzuk.
Adatok gyors törlése
A tábla összes sorait gyorsan lehet törölni a TRANCATE paranccsal:
TRANCATE TABLE emp_copy;
A parancs végrehajtása után a tábla struktúrája megmarad, de az egyetlen sort sem fog tartalmazni.
9.11 Tranzakciók
Tranzakció – SQL parancsoknak olyan sorozata, amelyet az Oracle egyetlen egységként kezel. A tranzakció által okozott változásokat az AB-ban a COMMIT parancs véglegesíti.
Véglegesítés – az adatok változásainak átvezetése az AB-ba. A változások érvénytelenítését a ROLLBACK parancs hajtja végre. Ez alapján az AB-ban történt változtatások vagy ténylegesen végrehajtódnak, vagy valami okból – nem.
Az elosztott tranzakció olyan adatokkal hajtódik végre, amelyek az elosztott AB-ban, hálózaton, több csomópontban tárolódnak.
Kétfázisú véglegesítés – az Oracle az elosztott tranzakciók kezelését a kétfázisú véglegesítéssel végzi. Ez biztosítja, hogy egy tranzakció a hálózat minden csomópontjában vagy véglegesítődik, vagy visszagörgetésre kerül.
Bankautomata működésének folyamata, mint egy tranzakció példája.
1. Lekérdezzük a számlaegyenlegünket
SELECT account_balance FROM bank_table WHERE account_number=1111111
AND account_type= ’SAVINGS’;
Az SQL-parancs az SGA-n keresztül a kiszolgáló-folyamathoz kerül, amely ellenőrzi, hogy a az SQL-terület tartalmazza-e parancs futtatható változatát. Ha a parancs nincs ott, akkor elemzi a parancsot, és azt a végrehajtható formában az SQL-területre helyezi és utána végrehajtja. A kliens gyorsító-tárból leolvassa az egyenleget és közli azt a felhasználóval. Például, legyen az 250000 Ft.
Utána kérünk 20000 forintot. A kliens-folyamat fogadja a kérésünket, és az alapján szerkeszt egy SQL-parancsot
UPDATE bank_table SET account_balance=230000 WHERE WHERE account_number=1111111 AND Account_type= ’SAVINGS’;
Ezt a folyamatot bővebben lépésenként így lehet leírni:
1. A kliens-folyamat a parancsot az SGA-n keresztül eljuttatja a kiszolgáló-folyamathoz.
2. A kiszolgáló-folyamat ellenőrzi, hogy rendelkezésére áll-e a parancs végrehajtható formája. Ha Igen, akkor a 4 lépésben, ha Nem – akkor a 3 lépésben folytatódik a feldolgozás.
3. Létrehozza a parancs végrehajtható formáját és az SQL-területre helyezi.
4. Végrehajtja a parancsot.
5. A manipulált adatok az adatgyorsítóban vannak? Ha Igen - 7, ha Nem – 6.
6. Az adatokat az Oracle beolvassa az adatállományból az adatgyorsítóba.
7. Oracle rögzíti az adat régi értékét a visszagörgető szegmensbe (25000).
8. Oracle másolatokat készít a tranzakcióról a változásnaplóban.
9. Az adatgyorsító-tárban lévő adatot megváltoztatja az új értékre (23000).
10. A bankautomata jelzi, hogy befejezte a tranzakciót.
11. Az az esemény, hogy befejeződött a tranzakció, rögzítésre kerül a változásnaplóban.
12. Az Oracle törli a visszagörgető szegmensben tárolt visszaállítási információt.
13. Az automata kiadja a pénzt.
Az első tranzakció akkor kezdődik, amikor a felhasználó belép a rendszerbe és elindít egy művelet sorozatot az AB-ban. A következő tranzakciók a COMMIT vagy a ROLLBACK paranccsal kezdődik.
A COMMIT parancs a tranzakció által végzett módosítások véglegesítésére használható. A COMMIT explicit használata nélkül a program egészének végrehajtása egyetlen tranzakcióként tekintendő és nem kerül véglegesítésre a program befejeződéséig. Ennek az a hátránya, hogy ez idő alatt a többi felhasználó hozzáférését gátolja. A COMMIT parancsot ajánlatos használni minél gyakrabban.
A tranzakció végét a COMMIT vagy a ROLLBACK parancsok jelzik. A tranzakció alatt végrehajtott módosítások véglegesen a táblákban a csak a COMMIT parancs által történnek. A ROLLBACK parancs esetén ezek a változtatások nem lesznek rögzítve a táblákban, ami azt jelenti, hogy a ROLLBACK parancs után a táblák tartalma a tranzakció kezdeti állapotában kerül.
Például, ha egy UPDATE parancs több mint egy sort módosít, és hiba csak az egyik sorban történt, akkor is a ROLLBACK parancs a tábla egyetlen sora sem kerül módosításra.
A tranzakció végrehajtása alatt az Oracle zárolhatja a tábla sorait. Az Oracle csak azokat a sorokat zárolja, amelyekkel az INSERT, UPDATE, DELETE parancsok hajtják végre a műveleteket. A zárolás automatikusan történik, és a felhasználónak nem kell azzal foglalkozni. Mivel a zárolás csak egyes sorokat érint (és nem az egész táblát), ez idő alatt a táblával a többi felhasználó párhuzamosan dolgozhat.
Az Oracle-ban lehetőség van a visszalépést a tranzakció bár-melyik pontjára végrehajtani. E célból a SAVEPOINT parancsot alkalmazhatjuk. Ha létrehoztunk egy SAVEPOINT pontot, akkor a visszalépést a ROLLBACK TO SAVEPOINT paranccsal lehet végrehajtani.
Példa.
SAVEPOINT MyPoimt;
Savepoint created.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7499 allen
7566 jones
7788 scott
7654 martin
5 rows selected.
DELETE FROM emp WHERE e_name LIKE ’%a%’;
2 rows deleted.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7566 jones
7788 scott
3 rows selected.
ROLLBACK TO SAVEPOINT MyPoint;
Rollback complete.
SELECT emp_no, e_name FROM emp;
EMP_NO E_NAME
-------------- -------------
7369 smith
7499 allen
7566 jones
7788 scott
7654 martin
5 rows selected.
9.12 Privilégiumok
Privilégium (jogosultság) a felhasználó számára lehetővé teszi, hogy az AB-ban bizonyos műveleteket hajthasson végre.
A privilégium kéttípusú lehet:
· rendszer-privilégium;
· objektum-privilégium.
A rendszer-privilégiumok lehetővé teszik adatdefiníciós és adatvezérlő parancsok végrehajtását, és az AB-ba való belépést. Az objektum-privilégiumok az AB objektumokkal való műveletekhez adnak jogosultságot. A felhasználó a létrehozása után egyetlen privilégiummal sem rendelkezik, és a privilégiumokat az AB adminisztrátortól később kapja. Amikor a felhasználó kap egy privilégiumot, utána az engedélyezett műveteket végrehajtatja a felsorolt AB-objektumaival.
Egy AB-hoz általános esetben több felhasználó is kapcsolódhat. Az Oracle-ban minden objektumnak van felhasználó-tulajdonosa. A nem tulajdonos-felhasználó csak akkor végezhet bizonyos műveleteket az objektumokkal, ha megkapta a megfelelő privilégiumokat. Létezik több mint nyolcvan rendszer-privilégium:
ALTER
DELETE
EXECUTE
INDEX
INSERT
REFERENCES
SELECT
UPDATE
…
A következő táblázat tartalmazza egyes privilégiumok és AB-objektumok közti lehetséges kapcsolatokat.
Privilégium
Table
View
Sequence
Procedure
ALTER
+
+
DELETE
+
+
EXECUTE
+
INDEX
+
INSERT
+
+
REFERENCES
+
SELECT
+
+
+
UPDATE
+
+
A INSERT, UPDATE és REFERENCES privilégiumokat lehet a tábla egyes oszlopaihoz kötni. Ha megakarjuk tudni, hogy milyen rendszer privilégiumokat lehet alkalmazni, végre kell hajtani a következő parancsot:
SELECT UNIQUE privilege FROM dba_sys_priv;
9.12.1 Privilégiumok adományozása
Az AB adminisztrátor a privilégiumokat a GRANT paranccsal adhatja meg a felhasználóknak:
GRANT privilégium_lista ON objektum_lista TO felhasználó_lista
[WITH GRANT OPTION];
GRANT privilégium_lista ON objektum_lista TO szerepkör_lista
[WITH GRANT OPTION];
GRANT privilégium_lista ON objektum_lista TO PUBLIC
[WITH GRANT OPTION];
A WITH GRANT OPTION esetén a felhasználó az adott privilégiumot más felhasználónak is tovább adhatja.
Példa.
GRANT SELECT, UPDATE ON emp_copy TO test_user;
A test_user felhasználó az emp_copy táblával végrehajthatja a SELECT és UPDATE parancsokat. Ezekben a parancsokban nem elég a tábla nevét emp_copy megadni, mivel a tábla tulajdonosát is meg kell adni. Például, ha a scott felhasználó az emp_copy tábla tulajdonosa, akkor a helyes hivatkozás:
SELECT * FROM scott.emp_copy;
Bizonyos esetekben ez a követelmény problémát is okozhat. Például, ha a tábla tulajdonosa a program létrehozása és futtatási ideje között megváltozott, akkor ezt figyelembe kell venni az összes táblára való hivatkozásban. Ilyen esetekben célszerű alkalmazni a tábla szinonimáját:
CREATE SYNONIM test FOR scott.emp_copy;
A scott.emp_copy tábla megkapta a test szinonimát. Ha ezek után megváltozik a tábla tulajdonosa, akkor továbbra is a táblára lehet hivatkozni a szinonima segítségével
SELECT * FROM test;
A PUBLIC opció esetén az adott privilégiumokat az összes felhasználóra érvényes, ami azt jelenti, hogy az objektum nyilvános. A Nyilvános objektum elérhető, látható az összes felhasználó számára.
GRANT SELECT, UPDATE ON emp_copy TO PUBLIC;
Ha a privilégium tartalmazza az ANY opciót, akkor az az AB összes táblájára érvényes. A következő privilégiumok esetén:
DELETE ANY TABLE
UPDATE ANY TABLE
INSERT ANY TABLE,
a felhasználó az AB összes tábláit módosíthatja, még akkor is, ha nem tulajdonosa a táblának. Ezt a legnagyobb lehetséges jogosultság, és csak az adminisztrátor szintű felhasználó kaphatja azt.
A SESSION_PRIVS nézetben megtalálhatók az aktuális privilégiumok. Az ALL_TAB_PRIVS és ALL_COL_PRIVS nézetekből pedig megtudhatjuk, hogy milyen privilégiumokkal rendelkeznek a felhasználók.
9.12.2 Szerepkörök (ROLE)
Szerepkör – a privilégiumok együttese, és lehetőség a felhasználók csoportosítására. A felhasználókat egy csoportba lehet beosztani, és a csoporton belül mindegyik felhasználó azonos jogosultsággal rendelkezik. Például, létrehozunk egy szerepkört
CREATE ROLE kozos;
utána a szerepkörhöz privilégiumokat kapcsolunk
GRANT INSERT ON table_a TO kozos;
GRANT INSERT ON table_b TO kozos;
GRANT INSERT, DELETE ON table_c TO kozos;
GRANT UPDATE ON table_d TO kozos;
GRANT DELETE ON table_e TO kozos;
GRANT SELECT ON table_f TO kozos;
Ha a felh_1 és felh_2 felhasználók megkapják a kozos szerepkört
GRANT kozos TO x;
GRANT kozos TO y;
akkor rendelkezni fognak az összes kozos szerepkörhöz tartozó jogosultságokkal.
9.12.3 Beépített szerepkörök
Az Oracle-ban léteznek beépített szerepkörök is:
CONNECT-
· ALTER SESSION
· CREATE CLUSTER
· CREATE DATABASE LINK
· CREATE SEQUENCE
· CREATE SESSION
· CREATE SYNONIM
· CREATE TABLE
· CREATE VIEW
RESOURSE-
· CREATE CLUSTER
· CREATE PROCEDURE
· CREATE SEQUENCE
· CREATE TABLE
9.12.4 Jogosultság a programok végrehajtására
Az AB-ban tárolódhatók
· Eljárások (PROCEDURE)
· Csomagok (PACKAGE)
· Függvények (FUNCTION).
Ezek az objektumok csak akkor érhetők el, ha a felhasználó EXECUTE privilégiummal rendelkezik.
Példa.
GRANT EXECUTE ON my_package TO PUBLIC;
GRANT EXECUTE ON my_func TO felh_2;
GRANT EXECUTE ON my_proc TO felh_1;
9.12.5 Privilégiumok visszavonása
Az AB adminisztrátor a privilégiumot a felhasználótól a REVOKE parancs által visszavonhat:
REVOKE privilégium ON objektum FROM felhasználó
[CASCADE CONSTRAINTS];
A CASCADE CONSTRAINTS a REFERENCES privilégium megvonása esetén törli az összes hivatkozási integritási megszorítást, amelyet a felhasználó hozott létre (CASCADE – lépcsőzetes).
REVOKE UPDATE ON emp_copy FROM test_user;
Ez a parancs után a test_user felhasználó nem módosíthatja a emp_copy táblát, de a SELECT parancsot továbbra is alkalmazhatja.
REVOKE SELECT ON classes FROM user_1;
REVOKE ALTER TABLE, EXECUTE ANY PROCEDURE FROM user_2;
REVOKE kozos FROM felh_1;
9.13 Indexek
Indexeket azzal a céllal hozzák létre, hogy a tábla bizonyos oszlopainak értékei ne ismétlődjenek, vagy (és) hogy gyorsabban történjen az adatok keresése. Az index létrehozása után azok a parancsok, melyek módosítják a táblát (UPDATE, DELETE, INSERT), az indexek szerinti sorrendjét továbbra is aktuális állapotban tartják. Ez időt igényel, és ezért minél több indexe van egy táblának, annál lassabban hajtódnak végre az UPDATE, DELETE, INSERT parancsok. A SELECT parancs a WHERE része alapján határozza meg a szükséges és felhasználandó indexeket, és ez biztosítja a parancs leggyorsabb végrehajtását.
Az indexeket létre lehet hozni:
· direkt módon, a CREATE INDEX paranccsal,
· automatikusan, a CREATE TABLE parancsban,
· ALTER TABLE paranccsal.
Használhatók:
· egyedi (nem ismétlődő) indexek, az értékei különbözőek, amikor a CREATE TABLE parancs a PRIMARY KEY vagy UNIQUE megszorításokat tartalmazza;
· ismétlődő értékeket tartalmazó indexek.
Példa.
CREATE INDEX Test_ind ON Test(col1)
TABLESPACE users
STORAGE (INITIAL 20K
NEXT 20K
PCTINCREASE 75);
Példa.
CREATE TABLE sample_3
(col_a VARCHAR(30),
col_b VARCHAR(30),
col_c VARCHAR(30));
CREATE INDEX col_c_ind ON sample_3(col_c) ;
CREATE UNIQUE INDEX col_a_ind ON sample_3(col_a) ;
A cola_ind index nem tartalmazhat ismétlődő értékeket, a colc_ind index pedig tartalmazhat.
A táblák indexeit a user_indexes nézetből lehet lekérdezni.
Példa.
SELECT index_name FROM user_indexes
WHERE table_name=’SAMLE_3’;
INDEX_NAME
-------------------
COL_A_IND
COL_B_IND
Láthatjuk, hogy a sample_3 táblához két index tartozik COL_A_IND, COL_B_IND. A következő parancs megsemmisíti (DESABLE) a COL_A_IND indexet.
ALTER TABLE semple_3 DESABLE CONSTRAINT COL_A_IND;
SELECT index_name FROM user_indexes
WHERE table_name=’SAMPLE_3’;
INDEX_NAME
-------------------
COL_B_IND
Most a semple_3 táblához csak egy COL_B_IND index tartozik. A következő parancs visszaállítja (ENABLE) a COL_A_IND indexet:
ALTER TABLE semple_3 ENABLE CONSTRAINT COL_A_IND;
A CREATE, ALTER parancsokban meg lehet adni, hogy az Oracle az indexek tárolására menyi memóriát adjon:
ALTER TABLE emp ADD CONSTRAINT pk_emp PRIMARY KEY (emp_no)
USING INDEX
INITRANS 5
MAXTRANS 10
TABLESPACE user_date
STORAGE ( INITIAL 20K
NEXT 20K
MINEXTENTS 1
MAXEXTENTS 99
PCTINCREASE 0)
PCTFREE 10;
Ha egy táblában a FOREIGN KEY vagy REFERENCES megszorításokkal külső kulcsokat hozunk létre, akkor azokat is kell indexelni, hogy a táblák közti kapcsolatot létrehozása után gyorsabban lehessen végrehajtani az adatok keresését:
ALTER TABLE emp ADD CONSTRAINT fk_demt FOREIGN KEY (dept_no)
REFERENCES dept(dept_no);
CREATE INDEX fk_dept_ind ON emp(dept_no) ;
A fk_dept_ind index ismétlődő értékeket tartalmazhat. Ezek után a következő parancs
gyorsabban hajtódik végre:
SELECT e.e_name, d.name FROM emp e, dept d
WHERE e.dept_no=d.dept_no;
Nagy táblák esetén az indexek megsemmisítése és visszaállítása sok időt igényelhet. Az indexet ideiglenesen is kikapcsolhatjuk (KEEP opcióval), úgy hogy az index továbbra is létezzen. Például,
ALTER TABLE emp KEEP INDEX pk_emp;
A DROP INDEX parancs az indexet véglegesen megsemmisíti, ha az nem PRIMARY KEY vagy UNIQUE index.
DROP INDEX Test_ind;
Sok esetben a programok indexelés nélkül is alkalmazhatók, de a végrehajtásuk lassabb lesz (legalább is elméletileg). Ne felejtsük, hogy gyakorlati szempontból mindegyik táblában kell, hogy legyen legalább egy PRIMARY KEY vagy UNIQUE index. Az indexeket az indexszegmens tartalmazza.
9.14 Táblák integritása
A UNIQUE és PRIMARY KEY indexeket az Oracle automatikusan hoz létre, amikor a CREATE TABLE parancsot végrehajtja
CREATE TABLE test (test_no NUMBER(5), …,
PRIMARY KEY(test_no), …);
A már létező táblában is létrehozhatunk elsődleges kulcsot:
ALTER TABLE test ADD
PRIMARY KEY(test_no);
Figyelem! Ha a tábla már tartalmaz sorokat, és azoknak az adatai a létrehozandó indexel konfliktusban vannak, akkor az ALTER parancs hibát jelez.
Az indexeket lehet törölni, vagy kikapcsolni törlés nélkül. Ezeket a műveleteket nem lehet végrehajtani, ha egy másik tábla idegen kulcsa hivatkozik az adott kulcsra.
Az ENABLE opció által egy indexet bekapcsolhatunk, az index kikapcsolására a DISABLE opció szükséges. Az alapértelmezés alapján (ha nincs megadva sem az ENABLE sem a DISABLE opció) az Oracle az ENABLE opciót fogja értelmezni.
ALTER TABLE test DISABLE PRIMARY KEY;
Ha ki akarjuk kapcsolni egy kapcsolatban levő idegen kulcsot, akkor ezt így lehet megvalósítani
ALTER TABLE test DISABLE PRIMARY KEY CASCADE;
Az index törlését hasonló képen lehet végrehajtani:
ALTER TABLE test DROP PRIMARY KEY;
Ha az index az ENABLE állapotban van, akkor a táblák közti integritási kapcsolatok minden módosítási művelet után is érvényesek maradnak. A DISABLE állapotban az integritási kapcsolatok megsérülhetnek. Ha az integritási kapcsolat egyszer megsérül, akkor az Oracle az indexet az ENABLE állapotába már nem képes visszaállítani.
9.15 Szekvenciák (sorozatok)
Ha egy Oracle alkalmazásban szükség van egy numerikus adatsorozatra (például, elsődleges kulcsra), melynek az értékei egyediek legyenek, akkor szekvenciákat lehet alkalmazni.
Szekvencia – egy olyan Oracle objektum, amely képes számokat generálni, és elérhetővé téve őket a sorszámozott elsődleges kulcsok számára.
Szekvenciák létrehozása:
CREATE SEQUENCE sor START WITH n
A START WITH n – megadja szekvencia kezdő értékét.
A szekvencia aktuális értékét a
sor.CURRVAL
attribútum adja vissza.
A szekvencia következő értékét (elemét) a
sor. NEXTVAL
attribútummal lehet megkapni.
Példa.
Ha a student tábla id mezője elsődleges kulcs, akkor annak az értékeit a student_sequence szekvencia által kapjuk meg:
CREATE SEQUENCE student_sequence START WITH 10000;
INSERT INTO students (id, first_name, last_name, major, current_credits)
VALUES (student_sequence.NEXTVAL, 'Scott', 'Smith', 'Computer Science', 0);
INSERT INTO students (id, first_name, last_name, major, current_credits)
VALUES (student_sequence.NEXTVAL, 'Margaret', 'Mason', 'History', 0);
SELECT id FROM students;
ID
-------
10001
10002
A szekvenciát általánosabb formában is létre lehet hozni:
CREATE SEQUENCE test_seq
INCREMENT BY 4
START WITH 50
MAXVALUE 70
MINVALUE 50
CYCLE
CACHE 3;
A test_seq szekvencia a következő sorozatot fogja generálni
50, 54, 58, 62, 66, 70, 50, 54,...
Az INCREMENT BY 4 az jelenti, hogy a szekvencia értékei néggyel fognak növekedni, hanem néggyel,
a MAXVALUE értékének elérése után a CYRCLE újból visszaállítja a MINVALUE értéket. A CACHE 3 egyszerre három generált számot fog elhelyezni a SGA-kesbe.
Figyelembe kell venni, hogy a ROLLBACK parancs a szekvencia kezdő állapotát nem állítja vissza, mely a tranzakció elején volt aktuális.
A szekvencia módosítása:
ALTER SEQUENCE test_seq
INCREMENT BY 10
MAXVALUE 1000
MINVALUE 50
NOCYCLE
CACHE 20;
és törlése:
DROP SEQUENCE test_seq;
9.16 Klaszterek (Fürtök)
Klaszter – olyan táblák adatainak együttes tárolása, amelyek közös adatokat tartalmaznak, és egy időben kerülnek feldolgozásra.
Klaszterkulcs – a klaszterizált táblák közös oszlopai közül azok az oszlopok, amelyek a tárolás vagy elérés kulcsául szolgálnak.
Ha a lekérdezések gyakran hivatkoznak két táblából álló összekapcsolt tábla-együttesre, akkor az AB adminisztrátor úgy dönthet, hogy ezeket a táblákat közösen egy klaszterben tárolja. A klasztert a CREATE CLASTER paranccsal lehet létrehozni.
Példa.
CREATE CLASTER Diak_Tanar (tantargy NUMBER(3))
TABLESPACE users
STORAGE( INITIAL 200K
NEXT 300K
MINEXTENTS 2
MAXEXTENTS 20);
A tantargy oszlop a klaszter kulcsa, és általa valósul meg a két tábla közti kapcsolat.
A már létező klaszterben táblákat lehet létrehozni:
CREATE TABLE Diak(tantargy NUMBER(3) PRIMARY KEY, …)
CLUSTER Diak_Tanar (tantargy);
CREATE TABLE Tanar(nev VARCHAR2(15) NOT NULL, …
tantargy NUMBER(3) REFERENCES Diak)
CLUSTER Diak_Tanar (tantargy);
A klaszter indexét még akkor kell létrehozni, amikor a táblák üresek, egyetlen sort sem tartalmazhat.
CREATE INDEX Diak_Tanar_Index
ON CLUSTER Diak_Tanar
TABLESPACE users
STORAGE( INITIAL 50K
NEXT 50K
MINEXTENTS 2
MAXEXTENTS 20);
A klasztert és az indexét különböző táblaterületben lehet tárolni. Ha töröljük a klaszter indexét, akkor a klaszter tábláit már nem lehet használni.
A klaszter módosítása az ALTER CLUSTER paranccsal történik:
ALTER CLUSTER Diak_Tanar
PRTFREE 30;
9.17 Nézetek (VIEW)
A nézet tartalmazza egy SQL-lekérdezés eredményét. A programokban ugyanúgy alkalmazhatjuk a nézeteket, mint a táblákat. Mivel a nézetek az AB-ban nem tárolódnak, úgy is lehet rájuk tekinteni, mint virtuális táblákra. Egy nézetet úgy is értelmezhetjük, mint egy tárolt SELECT parancs eredménytábláját, mely a nézet mindegyik megnyitásakor újból létrejön.
A nézet létrehozása:
CREATE VIEW v_customer_sales_rgn AS
SELECT surname, sales_region FROM customer;
A nézeteket a parancsokban úgy alkalmazhatjuk, mint a táblákat:
SELECT * FROM v_customer_sales_rgn;
A nézetet akkor nevezzünk egyszerűnek, ha az nem tartalmaz:
agregáló függvényt;
felhasználó által létrehozott függvényt;
beágyazott lekérdezést;
lekérdezések unióját.
A nézet nem tartalmazhat
ORDER BY
FOR UPDATE
záradékokat.
Az egyszerű nézet INSERT, DELETE, UPDATE parancsokkal módosítható. A módosítások azokban az táblákban rögzítődnek, amelyek alapján a nézetet szerkesztették.
A nézeteket kényelmes alkalmazni az összetett lekérdezések helyet:
CREATE OR REPLACE VIEW emp_dept_view AS
SELECT e.emp_no, e.e_name, d.dept_no, d.d_name
FROM emp e, dept d
WHERE e.dept_no=d.dept_no;
és
SELECT * FROM emp_dept_view;
Előfordulhat, hogy a módosítások után a táblában olyan változások történnek, hogy a tábla egyes sorai már nem kerülnek be a következő VIEW-lekérdezésbe, mivel nem felelnek meg a WHERE-feltételnek. Ilyen módosításokat meg lehet akadályozni, ha a nézet létrehozásának parancsa a WITH CHECK OPTION megszorítást tartalmazza.
A nézetet az ALTER paranccsal nem lehet módosítani. A módosítást csak úgy lehet végrehajtani, hogy először töröljük a nézetet
DROP VIEW test;
és utána újból létrehozzuk a nézetet, de már a módosított változatában.
A nézeteket biztonsági okokból is szokták alkalmazni. Például, ha egy felhasználónak egy tábla csak bizonyos oszlopait vagy sorait engedélyezzük elérni, akkor egy olyan nézetet hozunk létre, mely csak a megengedett adatokat tartalmazza, a felhasználó, pedig megkapja a megfelelő privilégiumokat erre a nézetre.
9.18 Szinonimák
Szinonima – egy olyan név, melyet táblához vagy nézethez lehet hozzárendelni, és az eredeti név helyett használni.
A szinonima létrehozása után a parancsokban az objektum eredeti neve helyett a szinonimával lehet rá hivatkozni.
Léteznek személyes és nyilvános (PUBLIC) szinonimák. A személyes szinonimákat egy-egy felhasználó hozza létre, és a továbbiakban csak ő használhatja.
CONNECT test/test
CREATE SYNONIM emp FOR scott.emp
A Test nevű felhasználó az emp táblára, melynek a tulajdonosa scott, létrehozott emp nevű szinonimát.
A nyilvános szinonimákat csak az AB adminisztrátor hozhat létre, és az ilyen szinonimát mindegyik olyan felhasználó alkalmazhatja, aki megfelelő privilégiummal rendelkezik
CREATE PUBLIC SYNONIM emp FOR scott.emp
A szinonima törlése:
DROP SYNONIM emp;
A távoli AB objektumára is lehet szinonimát létrehozni
CREATE PUBLIC SYNONIM synon FOR felh.aru@AB_1
A synon nevű nyilvános szinonimát hoztunk létre a távoli AB_1 AB-ban a felh.aru táblára.
Az SQL (Structured Query Language)- Strukturált Lekérdező Nyelv.
Az SQL szabványos adatbázis-kezelő
nyelv. A lekérdezési funkciók mellett a nyelv több olyan elemmel is
rendelkezik, amelyek más adatkezelési funkciók végrehajtására is alkalmasak. A
nyelv legújabb szabványos változatai, pedig már egészen kiterjedt
adatbázis-kezelési műveletek megvalósítására is használhatók.
Az SQL lekérdező része megfelel a relációs algebrának, ezért alkalmas a relációs adatmodell kezelésére, és az SQL
segítségével meg lehet fogalmazni a matematikailag megalapozott műveleteket.
Lehetőség van az SQL parancsokba történő beépítésére, ami hatékony, gyors
lekérdezési lehetőséget biztosít.
Az SQL-nek több verziója van.
Általában a különböző ABKR implementációk a saját képükre formált SQL
megvalósítással rendelkeznek.
· az ANSI (American National Standards Institute
= Amerikai Nemzeti Szabványügyi Intézet) által definiált SQL;
· SQL-92 vagy SQL2
- az 1992-ben elfogadott módosított
szabvány. Később ezeket az ISO
(International Standars Organization)
Nemzetközi Szabványügyi Szerveze) is elfogadta;
· az SQL3.
Minden SQL parancs egy kulcsszóval
kezdődik, amelyet paraméterek, esetleg további kulcsszavak követhetnek. A
paraméterek általában azok az objektumok, melyekre a parancsok vonatkoznak.
Ilyen lehet például egy tábla vagy attribútum neve, esetleg egy konstans, vagy
valamilyen azonosító.
A parancsok lehetnek egyszerűek vagy
összetettek, ami azt jelenti, hogy egy parancson belül egy másik parancs is
előfordulhat.
Az SQL parancsokat két fő csoportra
oszthatjuk:
parancsok. A DDL parancsok definiálják az AB objektumait, a DML parancsok, pedig végrehajtják azokkal a műveleteket. A DML
egyik legfontosabb parancsaihoz tartozik a lekérdezési
parancs.
(Bővebben – az Oracle fejezetben)
4.2 Táblák létrehozása, módosítása, törlése
A tábla definiálásának parancsában
meg kell adni a tábla nevét, a tábla attribútumait, azok típusát és méretét. (Táblák létrehozása az Oracle-ben)
· Valós számok, lebegőpontos
tárolással. Ebben az esetben is különböző
mérető számokat adhatunk meg. A FLOAT és a REAL a hagyományos programozás nyelvekből
is ismert normál lebegőpontos számot jelenti. A DOUBLE PRECISION duplapontos számot jelent, míg
speciálisan az SQL-ben használhatjuk a DECIMAL(<számjegy>,<tizedesjegy>) formát is,
ahol explicit módon megadhatjuk, hogy a szám hány számjegyből állhat, illetve
hány tizedes-jegyet tartalmazhat.
· Fix vagy változó
hosszúságú karaktersorozatok. Megadásuk a CHAR(<hossz>),
illetve a VARCHAR(<hossz>)
paranccsal történik. A CHAR segítségével olyan attribútumot definiálhatunk,
amely pontosan a megadott hosszúságú
karaktersorozatként fogja tárolni az adatokat, míg a VARCHAR esetén a megadott
attribútumoknál csak az aktuális számú karakter kerül tárolásra. Látszólag a VARCHAR
szolgáltatja a jobb megoldást, azonban az SQL elég rugalmas ahhoz, hogy a CHAR típust is
jól kezelje.
A táblákat a következő paranccsal
lehet létrehozni:
Az <attribútumdefiníció> paraméterben adjuk meg az egyes
attribútumok nevét és típusát, a következő módon:
<név> <típus> [DEFAULT <érték>]
A
<név> jelenti az attribútum nevét, míg a <típus>
adja meg a típust és a méretet, a fentiekben ismertetett módon. A DEFAULT paranccsal alapértelmezett értékeket
adhatunk meg az egyes attribútumoknak. Ennek használata nem kötelező.
A létező
táblát módosíthatjuk az ALTER TABLE
paranccsal. Lehetőség van arra is, hogy új oszlopot adjunk. Ez a
következőképpen történhet:
ALTER TABLE <táblanév> ADD
<attribútumdefiníció>
Hasonlóan történhet egy oszlop
eltávolítása a táblából. Ebben az esetben elegendő az attribútum a nevét
megadni:
ALTER TABLE <táblanév>
DROP <attribútumnév>
Lehetőségünk van az egész tábla
törlésére is:
Egy tábla definiálásakor a tábla
nevén és az attribútumokon kívül egyéb információt is lehet megadni. Ilyenek a
· az attribútum értékekre vonatkozó megszorítások.
Először a kulcsok, és az egyedi
értékekkel bíró attribútumok megadásának módját ismertetjük. Az SQL-ben
alapvetően az elsődleges kulcs megadására van
lehetőségünk, ahogy azt a legtöbb ABKR megköveteli. Ha az elsődleges kulcsot
szeretnénk definiálni, akkor a tábla létrehozását kibővíthetjük megfelelő
opciókkal (záradékokkal). Ez a következőképpen néz ki:
CREATE TABLE
<táblanév> { <attribútumdefiníció> [UNIQUE] [,<attribútumdefiníció> [UNIQUE]]… [,PRIMARY KEY (<kulcsattribútum>
[,<kulcsattribútum>]…)|UNIQUE (<kulcsattribútum>)
]}
A UNIQUE kulcsszó segítségével
minden egyes attribútumnál megadhatjuk, hogy az adott attribútum csak egyedi
értékeket vehet fel. A <kulcsattribútum> paraméterben kell megadni annak az
attribútumnak a nevét, amely a kulcsot alkotja, vagy annak egy részét képezi.
Amennyiben csak egy attribútum tartozik a kulcshoz, akkor használhatjuk mind a PRIMARY KEY, mind
a UNIQUE parancsokat.
Több attribútumból álló kulcsot csak a PRIMARY KEY kulcsszóval definiálhatunk.
4.3 Idegen kulcsok alkalmazása
Az SQL lehetőséget biztosít az idegen kulcsok definiálására is.
Ennek módja az alábbi:
CREATE TABLE <táblanév>
{ <attribútumdefiníció>
[REFERENCES <táblanév> (<attribútumnév>)]
[,<attribútumdefiníció>
[REFERENCES <táblanév> (<attribútumnév>)]]… [,FOREIGN KEY (<kulcsattribútum>
[,<kulcsattribútum>]…) <táblanév>
(<kulcsattribútum>[,<kulcsattribútum>]…) ]}
Láthatjuk, hogy az idegen kulcs
megadása hasonló az elsődleges kulcshoz.
A különbség mindössze annyi, hogy az
idegen kulcsnál mindig meg kell adni,
hogy az attribútum melyik másik tábla kulcsmezőjéhez kapcsolódik.
Amennyiben az idegen kulcs egy attribútumból
áll, használhatjuk a REFERENCES záradékot, ha azonban az idegen kulcs
összetett, akkor a FOREIGN
KEY záradékkal kell definiálnunk.
Az ABKR-nek gondoskodnia kell a hivatkozási
épség fenntartásáról. Ez azt jelenti, hogy ha egy idegen kulcsban
hivatkozunk egy másik táblának egy kulcsértékére, akkor a megadott értékű
előfordulásnak létezni kell.
Amennyiben olyan módosító, vagy törlő művelet
hajtódik végre, amely a hivatkozási épséget megsérti, akkor az ABKR-nek ezt kezelnie kell.
Az ABKR-nek következő lehetőségei
vannak:
· a műveletet nem
engedi végrehajtani
· a műveletet
megengedi, de a hivatkozási épség fenntartása érdekében automatikusan
korrigálja az adatbázist
Ez a korrigálás kétféleképpen
történhet.
· Az egyik az, hogy
ha egy hivatkozott sort törlünk, vagy módosítunk, akkor a rá hivatkozó
előfordulások is törlődnek, vagy módosulnak a másik táblában
· A másik lehetőség
az, hogy a helytelen hivatkozásokat az ABKR egy NULL (üres)
értékkel korrigálja.
Ha azt akarjuk, hogy egy korrigáló eljárás aktiválódjon a
hivatkozási épség megsérülésekor, akkor azt a tábla definiálásában kell
megadni. Mivel a hivatkozási épség az
idegen kulcsokra vonatkozik, ezért azt csak az idegen kulcsokkal kell
alkalmazni. Ezeket a megszorításokat a REFERENCES záradékban lehet megadni:
REFERENCES <táblanév>
(<attribútumnév>) [[ON DELETE SET
NULL|CASCADE] [ON UPDATE SET NULL|CASCADE]]
Az ON DELETE részben azt adhatjuk meg,
hogy a törlés során bekövetkezett hivatkozás épség sérülését hogyan kezelje a
rendszer, míg az ON
UPDATE részben a módosításkor bekövetkezőt.
Mindkét esetben a két lehetőség közül
választhatunk:
· SET
NULL – a NULL érték beállítása
· CASCADE – a hivatkozó
táblában is korrigálást hajtunk végre.
4.4 Megszorítások definiálása
A tábla definiálásakor más
megszorítások is megadhatók Ennek legegyszerűbb esete az, amikor a megszorítás az egyes attribútumok értékeire
vonatkozik. Ezt az attribútum leírásakor kell megadni, és ennek a formája a
következő:
<attribútumdefiníció> NOT NULL|CHECK (<feltétel>)
A NOT NULL
opció azt jelenti, hogy az adott attribútum nem vehet fel NULL (üres) értéket. A CHECK kulcsszó után
tetszőleges feltételt adhatunk. Az erre vonatkozó szabályok megegyeznek a SELECT
parancsban használt WHERE záradék lehetséges feltételével.
A feltétel ellenőrzése sor beszúrásakor, vagy
az attribútum módosításakor történik.
Ennél
általánosabb megszorítások is megfogalmazhatók. Lehetnek olyanok, amelyek sorokra vonatkoznak, és lehetnek olyan globális megszorítások, amelyek a teljes
adatbázisra vonatkoznak. A sorokra vonatkozó megszorítások ellenőrzése a
sorban történő bármilyen módosításkor megtörténik. A teljesen általános
megszorítások ellenőrzése minden olyan módosításkor bekövetkezik, aminek az
adott feltételre hatása lehet. A sorra vonatkozó feltételek megadása szintén a CHECK paranccsal történik, ezt a tábla
definiálásának a végén kell megadni. Formája az alábbi:
CREATE TABLE <táblanév>
{ <attribútumdefiníció>
[,<attribútumdefiníció>]…
[CHECK <feltétel>]}
A globális megszorítások definiálása
külön kulcsszóval történik, melynek formája a következő:
CREATE ASSERTION <név> CHECK <feltétel>
Példa
Adjuk meg azt az SQL parancsot,
amely létrehozza a Dolgozó táblát!
CREATE TABLE Dolgozó
{A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
A létrehozott tábla az alábbi:
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
Fizetése
|
Példa
Adjuk meg
azt az SQL parancsot, amely létrehozza a
Dolgozó táblát, és az elsődleges kulcsnak az A_dolgozó_törzsszáma mezőt definiálja!
CREATE TABLE Dolgozó
{A_dolgozó_törzsszáma CHAR(7) PRIMARY
KEY, Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) }
Egy másik lehetséges megoldás:
CREATE TABLE Dolgozó
{A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30) Sz_Ideje DATE, Fizetés DECIMAL(7,0) PRIMARY KEY (A_dolgozó_törzsszáma)}
Példa
Tegyük
fel, hogy a Kifizetés táblában
található A_dolgozó_törzsszáma
nevű mező idegen kulcs, amely a Dolgozó táblával való kapcsolatot valósítja meg.
Adjuk meg azt az SQL parancsot, amely a fenti Kifizetés táblát létrehozza, úgy hogy
a hivatkozási épség sérülésekor az ABKR azt automatikusan frissítéssel
korrigálja!
CREATE TABLE Kifizetés
{A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7) REFERENCES Dolgozó
(A_dolgozó_törzsszáma) ON UPDATE CASCADE
ON DELETE CASCADE}
Egy másik lehetséges megoldás:
CREATE TABLE Kifizetés
{A_kifizetés_dátuma DATE, A_kifizetett_bér DECIMAL(7,0), A_levont_adóelőleg DECIMAL(7,0), A_dolgozó_törzsszáma CHAR(7), FOREIGN KEY (A_dolgozó_törzsszáma)
Dolgozó (A_dolgozó_törzsszáma) ON UPDATE
CASCADE ON DELETE CASCADE}
A létrehozott tábla a következő:
A kifizetés dátuma
|
A kifizetett
bér
|
A levont
Adóelőleg
|
A dolgozó
törzsszáma
|
Példa
Adjuk meg
azt az SQL parancsot, amely a Dolgozó
táblát úgy definiálja, hogy a Fizetés mező
esetén mindig ellenőrzésre kerüljön, hogy az éppen megadott érték eléri-e egy
minimális bér összegét, mondjuk 55000 Ft-ot!
CREATE TABLE Dolgozó
{A_dolgozó_törzsszáma CHAR(7), Név VARCHAR(50), Sz_Helye VARCHAR(30), Sz_Ideje DATE, Fizetés DECIMAL(7,0) CHECK A_dolgozó_fizetése >55000}
Példa
Adjuk meg
azt az SQL parancsot, amely egy olyan globális megszorítást definiál, amely
ellenőrzi, hogy a Dolgozó táblában az
összes fizetés együttesen ne haladja meg a 10.000.000 Ft-ot!
CREATE ASSERTION
Összefizetés CHECK (10000000 >= (SELECT SUM(Fizetés) FROM Dolgozó))
4.5 Táblák indexelése
Példa
CREATE INDEX Diak_NeveInd ON Students
( Diak_Neve)
A Student tábla Diak_Neve attribútum indexelve lesz, és az index neve Diak_NeveInd.
Egy
másik lehetőség:
CREATE UNIQUE INDEX Diak_NeveInd
ON Students ( Diak_Neve)
Az
index törlése:
DROP INDEX Diak_NeveInd
4.6 Példák a CREATE parancs alkalmazására
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,
Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,
Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL UNIQUE,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
PRIMARY KEY (Stud_Num, Tantargy_Num)
)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK (Jegy =<5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5),
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num)
CHECK (Jegy IN ( 4, 5) AND Datum> 15/06/2001)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER CHECK IN (1, 2, 3, 4, 5)
DEFAULT = 5,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num INTEGER
NOT NULL,
UNIQUE (Stud_Num,Tantargy_Num) )
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL,
Tantargy_Num
INTEGER NOT NULL,
FOREING KEY ( Stud_Num )
REFERENCES Students (Stud_Num))
Stud_Num
– külső kulcs, kapcsolat a Students-el.
Vagy
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES
Students (Stud_Num),
Tantargy_Num
INTEGER NOT NULL )
Ha a Students-ben a Stud_Num
attribútum PRIMARY KEY, akkor a szülő-táblában azt nem kell megadni:
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL
REFERENCES
Students,
Tantargy_Num
INTEGER NOT NULL )
Adjuk meg
azt az SQL parancsot, amely hozzáadja a
Dolgozó táblához a dolgozó lakcímét!
ALTER TABLE Dolgozó ADD A_dolgozó_lakcíme VARCHAR(50)
A módosított Dolgozó tábla így fog kinézni:
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
A dolgozó
lakcíme
|
Adjuk meg
azt az SQL parancsot, amely a Dolgozó
táblából törli Sz_
helye attribútumot!
ALTER TABLE Dolgozó DROP Sz_Helye
A módosítás után a Dolgozó tábla:
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
A dolgozó
lakcíme
|
Adjuk meg azt az SQL parancsot,
amely a Dolgozó táblát törli!
DROP Dolgozó
4.7 Példák az adatintegritásra
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num
INTEGER NOT NULL,
UPDATE
OF Students CASCADES,
DELETE
OF Students RESTICTED)
CREATE TABLE Jegyek ( Azon INTEGER NOT NULL PRIMARY KEY,
Jegy INTEGER,
Datum DATE,
Stud_Num INTEGER NOT NULL REFERENCES Students,
Tantargy_Num
INTEGER NOT NULL,
DELETE
OF Students NULLS)
Lekérdezések az SQL-ben
4.8.1 Egyszerű lekérdezések
A lekérdezés a leggyakoribban alkalmazott SQL parancs. A
lekérdezés szinonimja a kérdés.
Virtuális oszlop –
azon oszlop egy lekérdezés eredményében, amelynek értékét más oszlopok
értékeiből határozzuk meg.
Lehívási fázis – a
lekérdezés olyan fázisa, amikor a keresési feltételnek eleget tevő sorok az
AB-ból a pufferbe töltődnek.
A
lekérdezés a projekció relációalgebrai művelet
megvalósítása.
A parancs
legegyszerűbb változatát a következő szintaxis írja le:
A parancs első részében a * jel azt jelenti, hogy a lekérdezés a tábla összes
oszlopára (attribútumára) vonatkozik.
Az <oszlopnévlistá>-ban megadhatjuk azokat az oszlopokat,
melyeket a lekérdezés eredménytáblájában
akarjuk helyezni. Lehetőség van különböző módosításokra, például a listában
szereplő elemeket átnevezhetjük, esetleg kifejezéseket
képezhetünk belőlük.
Emellett alkalmazhatunk különböző
függvényeket is, első sorban aggregáló
függvényeket.
Általános esetben az <oszlopnévlista> szintaxisa
a következő:
<oszlopkifejezés>[,<oszlopkifejezés>]…
Amennyiben az oszlopkifejezés
aggregáló függvényt tartalmaz, akkor az eredménytáblában nem a tábla egyes
soraiból kiválasztott adatok jelennek meg, hanem azoknak a megfelelő
aggregáltjai. Az aggregáló függvény a tábla soraiból álló megfelelő halmazokkal
hajtódik végre.
4.8.1.1 Aggregáló függvények
Az <oszlopkifejezés> a következő aggregáló függvényeket
tartalmazhat:
· SUM
–
megadja a paraméterében szereplő oszlop adatainak az összegét az összes sorra.
Csak numerikus attribútumra alkalmazható.
· AVG
– megadja a
paraméterében szereplő oszlop adatainak az átlagát az összes sorra. Csak
numerikus attribútumra alkalmazható.
·
MIN – megadja a
paraméterében szereplő oszlop adatainak a minimumát az összes sorra. Csak
numerikus attribútumra alkalmazható.
· MAX
– megadja a paraméterében szereplő
oszlop adatainak a maximumát az összes sorra. Csak numerikus attribútumra
alkalmazható.
Lehetőség van oszlopok átnevezésére
is. Ennek a szintaxisa a következő:
Az eredménytáblában az <oszlopnév>
paraméterben megadott másodlagos név szerepel. Sok ABKR-ben az AS kulcsszó elhagyható.
A
parancsban használható ALL és DISTINCT kulcsszavaknak speciális jelentése van.
Előfordulhat, hogy egy lekérdezés végrehajtása után a keletkezett elemek között
ugyanaz a sor többször előfordul. Ilyenkor az ALL opció alkalmazásakor,
illetve alapértelmezés szerint az azonos előfordulások többszörösen fognak
megjelenni az eredményben. Amennyiben a DISTINCT opciót alkalmazzuk, akkor minden azonos előfordulás csak egyszer
jelenik meg az eredménytáblában. A következőkben nézzünk néhány példát az
egyszerű lekérdező parancsok alkalmazására.
Példa
Dolgozó tábla:
A dolgozó
törzsszáma
|
A dolgozó
Neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T234578
|
Kiss István
|
Eger
|
1968. 12. 11.
|
120000
|
T456734
|
Nagy József
|
Budapest
|
1972. 01. 30.
|
150000
|
T429877
|
Kovács János
|
Szeged
|
1967. 05. 12.
|
120000
|
A teljes tábla lekérdezése a következő
paranccsal történhet:
SELECT * FROM Dolgozó
Példa
Tegyük fel, hogy szeretnénk
lekérdezni az egyes dolgozók nevét a fizetésükkel együtt. A megfelelő parancs a
következő:
SELECT Név,
Fizetés FROM Dolgozó
A keletkezett eredménytábla a
következőképpen néz ki:
A dolgozó
neve
|
A dolgozó
fizetése
|
Kiss István
|
120000
|
Nagy József
|
150000
|
Kovács János
|
120000
|
Példa
Készítsünk
olyan eredménytáblát, amely tartalmazza a dolgozók nevét, fizetését, valamint a
10%-kal megemelt fizetéseket. Az új
oszlop neve legyen A_dolgozó_emelt_fizetése. A feladatot az alábbi paranccsal oldhatjuk meg:
SELECT Név, Fizetés,
1.1*Fizetés AS 'A dolgozó emelt
fizetése' FROM Dolgozó
Az eredménytábla tartalma:
A dolgozó
Neve
|
A dolgozó
fizetése
|
A dolgozó
emelt
fizetése
|
Kiss István
|
120000
|
132000
|
Nagy József
|
150000
|
165000
|
Kovács János
|
120000
|
132000
|
Példa
Jelenítsük
meg a dolgozók fizetését úgy, hogy a listában ne legyen két azonos érték. A feladatot az alábbi paranccsal oldhatjuk meg:
SELECT DISTINCT Fizetés FROM Dolgozó
A keletkezett eredménytábla a
következő:
A dolgozó
fizetése
|
120000
|
150000
|
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat dolgozóinak számát, az összes és az
átlagos fizetéseket. Az oszlopok neveinek sorrendje legyen: A dolgozók száma, A dolgozók
összes fizetése, A dolgozók átlagos fizetése. A
feladatot a következő módon oldhatjuk meg:
SELECT COUNT(Név) AS 'A dolgozók száma' , SUM(Fizetés) AS 'A dolgozók összes fizetése', AVG(Fizetés) AS 'A
dolgozók átlagos fizetése' FROM Dolgozó
A keletkezett eredménytábla a
következő:
A dolgozók
száma
|
A dolgozók
összes fizetése
|
A dolgozók
átlagos fizetése
|
3
|
390000
|
130000
|
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat dolgozóinak nevét és születési évét.
A születési évet tartalmazó oszlop neve legyen ’A dolgozó születési éve’. A feladatot
a következő módon oldhatjuk meg, feltéve, hogy a rendszerünkben létezik a LEFT(<karaktersorozat>, <darab>) függvény,
amely a <karaktersorozat>
paraméterben megadott karaktersorozat bal oldaláról levág a <darab>
paraméterben megadott számú karaktert. Azt is feltételezünk, hogy a Sz_Ideje oszlop karakter típusú.
SELECT Név, LEFT(Sz_Ideje,
4) AS 'A dolgozó születési éve' FROM Dolgozó
Az eredménytábla:
A dolgozó
neve
|
A dolgozó
születési éve
|
Kiss István
|
1968
|
Nagy József
|
1972
|
Kovács János
|
1967
|
4.8.2 Kiválasztó lekérdezések
A kiválasztást végrehajtó parancs a WHERE <feltétel> záradékot
tartalmazza. Az eredménytáblába csak azok a sorok adatai kerülnek, melyekre
teljesül a feltétel. A feltétel
műveleteket és operátorokat tartalmazhat.
Az operátorok
· összehasonlító (<,>,<=,>=,<>)
· aritmetikai (+,-,*,/)
· logikai (AND, OR, NOT)
műveleteket hajthatnak végre.
A műveletek
· konstansok
· reláció
attribútumok (oszlopnevek)
· függvényhivatkozások
lehetnek.
A műveletekre érvényesek a szokásos precedencia
szabályok, amelyeket zárójelezéssel felülbírálhatunk. Ügyelnünk kell arra, hogy
végeredményben a kifejezés mindig logikai értéket kapjon, mivel az eredménytáblába
azok az előfordulások (sorok) kerülnek be,
amelyekre
a megadott kifejezés igaz (TRUE) értéket kap.
A kifejezések
következő predikátumokat tartalmazhatnak:
·
BETWEEN
·
IN
· LIKE
A BETWEEN predikátum a következőképpen
használható:
<oszlopkifejezés> BETWEEN <alsóérték> AND <felsőérték>
Az <alsóérték>, illetve <felsőérték>
valamely elemi típusú (numerikus, dátum) értékek,
az <oszlopkifejezés>
ugyanilyen típusú kifejezés, amely oszlopnevekből van képezve.
Eredményként azok a rekordok fognak
eleget tenni a feltételnek, amelyekre a kifejezés értéke az alsóérték és a felsőérték közé esik.
Ennek a feltételnek akkor van
értelme, ha az alsóérték
kisebb, mint a felsőérték.
Az IN predikátum
a következőképpen használható:
<oszlopkifejezés> [NOT] IN <értéklista>
A kifejezés hatására annak
vizsgálata történik meg, hogy az oszlopkifejezés értéke szerepel-e a megadott értéklistában,
vagy nem. Ha szerepel, akkor a kifejezés értéke igaz lesz. Amennyiben a NOT kulcsszót használjuk, a kifejezés akkor
lesz igaz, ha az értéke nem szerepel a listában. Az értéklista paraméterben a
kifejezés típusának megfelelő értékeket kell vesszővel elválasztva felsorolni.
<oszlopkifejezés>
LIKE
<karakterlánc>
A karakterláncban idézőjelek között
adhatunk meg karaktersorozatot.
A karaktersorozatban két karakternek speciális
jelentése van, ezek a % illetve az _ jelek.
Az oszlopkifejezés paraméternek karakteres értékűnek kell lenni,
amely összehasonlításra kerül a konstanssal. Amennyiben a kettő megegyezik, a
feltétel igaz lesz.
Ha a konstansban a % jelet
használjuk, akkor a két karakterláncnak csak eddig a jelig kell egyezni ahhoz,
hogy a feltétel igaz legyen. Ennek megfelelően a % jelet csak egyszer kell
használnunk. Az _
jelet többször is alkalmazhatjuk, ilyenkor az összehasonlításnál a megadott
pozíción bármilyen jel szerepelhet, és azon a helyen az egyezésnek fog
számítani.
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat azon dolgozóinak nevét és fizetését,
akik 150000 Ft felett keresnek!
A feladatot a következő módon
oldhatjuk meg:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés >= 150000
A keletkezett eredménytábla a
következő:
A dolgozó
neve
|
A dolgozó
Fizetése
|
Nagy József
|
150000
|
Példa
Feltételezve,
hogy a Sz_Ideje oszlop dátum típusú,
készítsünk olyan táblázatot, amely megadja a vállalat azon dolgozóinak nevét és
fizetését, akik 1960.01.01-e után születtek, és a fizetésük 100000 Ft felett
van!
A feladatot a következő módon
oldhatjuk meg:
SELECT Név, Fizetés FROM Dolgozó WHERE Sz_Ideje > {1960.01.01.} AND Fizetés >= 100000
A keletkezett eredménytábla a
következő:
A dolgozó
neve
|
A dolgozó
fizetése
|
Kiss István
|
120000
|
Nagy József
|
150000
|
Kovács János
|
120000
|
Példa
Készítsünk olyan táblázatot, amely
megadja a vállalat azon dolgozóinak nevét és fizetését, akiknek a fizetése
100000 és 120000 Ft közé esik!
A feladatot a következő módon
oldhatjuk meg:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés BETWEEN
100000 AND 120000
A feladatot másképpen is
megoldhatjuk:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés >= 100000
AND Fizetés <= 120000
A keletkezett eredménytábla a
következő:
A dolgozó
neve
|
A dolgozó
Fizetése
|
Kiss István
|
120000
|
Kovács János
|
120000
|
Példa
Készítsünk olyan táblázatot, amely
megadja a vállalat azon dolgozóinak nevét és fizetését, akiknek a fizetése
100000 vagy 150000 Ft!
A feladatot a következő módon
oldhatjuk meg:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés IN (100000,
150000)
A keletkezett eredménytábla a
következő:
A dolgozó
neve
|
A dolgozó
fizetése
|
Nagy József
|
150000
|
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat azon dolgozóinak nevét és születési
helyét, akik Egerben, Szegeden vagy Debrecenben születtettek!
A feladatot a következő módon
oldhatjuk meg:
SELECT Név, Sz_Helye FROM Dolgozó WHERE Sz_Helye IN ("Eger", "Szeged",
"Debrecen")
A keletkezett eredménytábla a
következő:
A dolgozó
neve
|
A dolgozó
születési helye
|
Kiss István
|
Eger
|
Kovács János
|
Szeged
|
Példa
Készítsünk olyan táblázatot, amely
megadja a vállalat Kovács nevű
dolgozóinak adatait!
A feladatot a következő módon
oldhatjuk meg:
SELECT * FROM Dolgozó WHERE Név LIKE "Kovács%"
A keletkezett eredménytábla a
következő:
A dolgozó
törzsszáma
|
A dolgozó
Neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T429877
|
Kovács János
|
Szeged
|
1967. 05. 12.
|
120000
|
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat
Kiss vagy Koós vezetéknevű
dolgozóinak adatait!
A feladatot a következő módon
oldhatjuk meg:
SELECT * FROM Dolgozó WHERE Név LIKE "K__s%"
A keletkezett eredménytábla a
következő:
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T234578
|
Kiss István
|
Eger
|
1968. 12. 11.
|
120000
|
Példa
Készítsünk
olyan táblázatot, amely megadja a vállalat
T4-gyel kezdődő törzsszámú nem szegedi vagy debreceni születésű, vagy T2-vel kezdődő törzsszámú 1968-ban született dolgozóit!
Feltételezzük, hogy a rendszerünkben
egy dátum típusú adat évének lekérdezésére létezik a YEAR(<Dátumkifejezés>)
függvény. A feladatot a következő módon oldhatjuk meg:
SELECT * FROM Dolgozó WHERE ((LEFT(A_dolgozó_törzsszáma,2) LIKE "T4") AND (Sz_Helye NOT IN ("Szeged",
"Debrecen"))) OR ((LEFT('A
dolgozó törzsszáma',2) LIKE "T2") AND (YEAR(Sz_Ideje) = 1968))
A keletkezett eredménytábla a
következő:
A dolgozó
törzsszáma
|
A dolgozó
Neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T234578
|
Kiss István
|
Eger
|
1968. 12. 11.
|
120000
|
T456734
|
Nagy József
|
Budapest
|
1972. 01. 30.
|
150000
|
4.8.3 Csoportosító lekérdezés (GROUP BY záradék)
A csoportosítás azt jelenti, hogy a rekordokat egy adott mező értékei szerint
csoportokra bontjuk. Egy csoportba az
adott mezőben azonos értékeket felvevő rekordok kerülnek. A csoportokhoz
tartozó rekordokra különböző műveleteket hajthatunk végre, például
alkalmazhatjuk az aggregáló függvényeket, vagy a csoportokra vonatkozóan
kiválasztó műveletet alkalmazhatunk.
A csoportosítás a következő záradék
által adható meg:
GROUP BY
<oszlopnév>,[<oszlopnév>]…
A csoportosítás a megadott
oszlopnevek azonos értékei alapján fog történni. Amennyiben több oszlopot adunk
meg, akkor az első oszlop azonos értékein belül a második oszlop azonos értékei
szerint csoportosít, majd a harmadik szerint, stb. Az egyes mezőkhöz tartozó
értékeket a megadás sorrendjében egymás mellé rakja a rendszer, és az így
kapott minta alapján csoportosít.
Az
eredménytáblába minden egyes csoportra egy sor kerül.
Mivel speciális műveletről van szó, használata
során a SELECT parancs egyéb részeire vonatkozóan is
megkötéseket kell tennünk.
Így a lekérdezendő oszlopok adataira vonatkozóan
mindenképpen alkalmaznunk kell valamilyen aggregáló függvényt, vagy ha ezt nem
tesszük, akkor az oszlopnak szerepelnie kell a csoportosításban részt vevő
oszlopok között, azaz a GROUP BY után.
Az SQL nyelv lehetőséget biztosít
arra is, hogy a csoportosított adatokra vonatkozóan feltételeket adhassunk meg.
Ebben az esetben a feltételt nem a WHERE kulcsszót használjuk, hanem a HAVING kulcsszót:
HAVING <csoportfeltétel>
A <csoportfeltétel>
paraméterben a hagyományos módon adhatunk meg feltételeket, azzal a
különbséggel, hogy
a
feltételben szereplő oszlopneveknek tartalmazniuk kell valamilyen aggregáló
függvényt, és ennek ugyancsak szerepelnie kell a SELECT
után.
Példa
Tegyük fel ezúttal, hogy a Dolgozó
táblánk az alábbi módon néz ki:
A dolgozó
törzsszáma
|
A dolgozó
Neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T234578
|
Kiss István
|
Eger
|
1968. 12. 11.
|
120000
|
T3443234
|
Kiss Timót
|
Eger
|
1970. 02. 28.
|
105000
|
T456734
|
Nagy József
|
Budapest
|
1972. 01. 30.
|
150000
|
T768545
|
Vári Ödön
|
Budapest
|
1958. 07. 12.
|
210000
|
T429877
|
Kovács János
|
Szeged
|
1967. 05. 12.
|
120000
|
Készítsünk olyan listát, amely
megadja városonként, hogy az adott városban hány dolgozó született! Az alábbi
parancsot használhatjuk:
SELECT Sz_Helye AS 'Születési hely', COUNT(A_dolgozó_törzsszáma) AS 'A dolgozók száma' FROM Dolgozó GROUP BY Sz_Helye
Eredményképpen a következő táblát
kapjuk:
Születési
hely
|
A dolgozók
Száma
|
Eger
|
2
|
Budapest
|
2
|
Szeged
|
1
|
Példa
Készítsünk
olyan listát, amely megadja városonként, hogy az adott városban született
dolgozóknak mennyi az összes illetve az átlagfizetése!
Az alábbi parancsot használhatjuk:
SELECT Sz_Helye AS 'Születési hely', SUM(Fizetés) AS 'A dolgozók összes fizetése', AVG(Fizetés) AS 'A
dolgozók átlagfizetése' FROM Dolgozó
GROUP BY Sz_Helye
Eredményképpen a következő táblát
kapjuk:
Születési
hely
|
A dolgozók
összes fizetése
|
A dolgozók
átlagfizetése
|
Eger
|
225000
|
112500
|
Budapest
|
360000
|
180000
|
Szeged
|
120000
|
120000
|
Példa
Készítsünk
olyan listát, amely megadja azokat a városokat, amelyekre igaz, hogy az adott
városban született dolgozóknak az átlagfizetése legfeljebb 120000 Ft!
Az alábbi parancsot használhatjuk:
SELECT Sz_Helye AS
'Születési hely', AVG (Fizetés) AS 'A dolgozók átlagfizetése'
FROM Dolgozó GROUP BY Sz_Helye HAVING AVG(Fizetés) <= 120000
Eredményképpen a következő táblát
kapjuk:
Születési
hely
|
A dolgozók
Átlagfizetése
|
Eger
|
112500
|
Szeged
|
120000
|
4.8.4 Rendezés (ORDER BY záradék)
Az SQL lehetőséget biztosít arra, hogy
lekérdezéseink eredményét rendezetten jelenítsük meg. ORDER BY záradék formája a következő:
ORDER BY <oszlopnév|oszlopsorszám>
[ASC|DESC], <oszlopnév|oszlopsorszám> [ASC|DESC]]…
A rendezés a megadott oszlopok
szerint történik. Első szempontként az első oszlopot, további szempontként az
utána megadott oszlopokat veszi figyelembe. A
rendezési szempontként megadott oszlopnak szerepelni kell a SELECT parancs után is.Az oszlopok kétféleképpen
adhatók meg:
· Nevükkel
· egy számmal, ami az oszlop sorszáma. A számozás 1-től
kezdődik a táblázat fejrészében megadott sorrend szerint.
Fontos még az ASC és a DESC
kulcsszavak jelentése.
Az ASC az alapértelmezés, ami azt jelenti, hogy a rendezés a növekvő sorrend szerint történik. Ha a DESC
kulcsszót használjuk, akkor a megadott oszlopban a rendezés csökkenő lesz.
Példa
Készítsünk
olyan listát, amely a dolgozók nevét
és fizetését név szerint ábécé
sorrendben adja meg!
Az alábbi parancsot használhatjuk:
SELECT Név, Fizetés FROM Dolgozó ORDER BY Név
A keletkezett eredménytábla az
alábbi:
A dolgozó
neve
|
A dolgozó
fizetése
|
Kiss István
|
120000
|
Kiss Timót
|
105000
|
Kovács János
|
120000
|
Nagy József
|
150000
|
Vári Ödön
|
210000
|
Példa
Készítsünk
olyan listát, amely a dolgozók nevét és fizetését a fizetés szerint csökkenő,
illetve azonos fizetés esetén név szerint ábécé sorrendben adja meg!
Az alábbi parancsot használhatjuk:
SELECT Név, Fizetés FROM Dolgozó ORDER BY Fizetés DESC, Név
A keletkezett eredménytábla az
alábbi:
A dolgozó
neve
|
A dolgozó
fizetése
|
Vári Ödön
|
210000
|
Nagy József
|
150000
|
Kiss István
|
120000
|
Kovács János
|
120000
|
Kiss Timót
|
105000
|
4.8.5 Több táblára vonatkozó lekérdezések
Legtöbb esetben az adatbázis
szerkezete olyan, hogy a szükséges információk több táblában találhatók.
Különösen igaz ez, ha normalizált relációkkal dolgozunk, hiszen mint láttuk, a
normalizálás alaptevékenysége a több relációra bontás. Ilyen esetekben az
adatok összegyűjtéséhez minden táblára szükségünk van, ezért a lekérdezéseket
ki kell terjeszteni az úgynevezett többtáblás
lekérdezésekké, melyeknek az általános formája a következő:
SELECT [ALL|DISTINCT] * | <oszlopnévlista> FROM
<táblanév> [<másodnév>][,<táblanév> [<másodnév>]]…
A kérdés az, hogyan kell
értelmeznünk azt, amikor a FROM kulcsszó után több tábla neve szerepel. A választ
a relációs modell adja. Ilyen esetben a
táblákon a Descartes szorzat relációalgebrai művelet hajtódik
végre, s az eredményt a szorzat reláció
adja. A gyakorlatban általában egy Descartes szorzat nagyon ritkán használható.
Például, ha az egyik táblában a dolgozók adatai, a másikban a fizetési adatok
találhatók, akkor ezek Descartes szorzatában minden dolgozóhoz hozzárendelődik
az összes kifizetés, az is, ami nem az adott dolgozóhoz tartozik. Ennek nincs
semmi értelme, mivel az eredménytábla felesleges sorokat tartalmaz, és azokat
el kell távolítani a szorzatból. Erre használhatjuk a kiválasztó műveletet,
vagyis a WHERE záradékot, amely tartalmazza a
megfelelő feltételt.
Amennyiben a lekérdezéseinkben több
tábla szerepel, akkor előfordulhat, hogy valamely attribútumnak mindkét
táblában ugyanaz az neve. Ebben az esetben az attribútum neve elé oda kell írnunk a megfelelő tábla nevét.
Ugyancsak előfordulhat, hogy egy táblát saját magával kell összekapcsolni.
Ilyenkor a tábla önmagával való Descartes szorzata képződik. Azonban itt az
attribútumok nevei mellett magukat a táblák példányait is egymástól el kell
különítenünk. Ilyenkor kell megadnunk a
másodlagos nevet (másodnevet, alias nevet).
Másodlagos
név – olyan ideiglenes név,
amelyet egy SQL parancsban egy táblához vagy egy oszlophoz rendelünk hozzá. Ezt
a nevet csak az adott parancsban alkalmazhatjuk. A parancson belől a további
hivatkozásokban ezt a nevet használhatjuk.
4.8.5.1 Összekapcsolás (Lásd még a 9.8)
Az SQL nyelv lehetőséget biztosít az összekapcsolás relációalgebrai műveletek
közvetlen megvalósítására is. Ez azt jelenti, hogy speciális utasítások állnak
rendelkezésre, amelyek az összekapcsolás
különböző fajtáit adják meg.
A legelső ilyen parancs magát a Descartes szorzatot hozza létre. A
parancs megadásánál csak a FROM kulcsszó utáni részt definiáljuk:
A parancs hatására az SQL a megadott
két tábla Descartes szorzatát képezi. Mint tudjuk, sokkal természetesebb a feltételt tartalmazó összekapcsolás.
Ennek formája az alábbi:
…<táblanév>
JOIN <táblanév> ON <feltétel>
Az ON záradékban tetszőleges feltételt
adhatunk meg.
Az összekapcsolások egy speciális
fontos fajtája a külső összekapcsolás, ami
akkor jelentkezik, ha a két
összekapcsolandó tábla valamely sorához a másik táblából nem tartozik egyetlen
sor sem. Ilyenkor az összekapcsolás művelet definíciója alapján ez a sor
nem kerül be az eredménytáblába. A gyakorlatban előfordulhat, hogy ezekre a "lógó" sorokat (előfordulásokat)
is szeretnénk szerepeltetni az összekapcsolt relációban. Ilyenkor használhatjuk
a külső összekapcsolásokat.
Egy
külső összekapcsolás abban különbözik a hagyományostól, hogy az eredménybe
minden olyan sor is bekerülhet, amely a másik tábla egyetlen sorához sem
kapcsolódik.
Egy külső összekapcsolás háromféle
módon valósulhat meg. Az egyik mód az, amikor mindkét tábla "lógó" sorai bekerülnek
az eredménybe, a másik kettő, pedig amikor csak a bal, illetve a jobboldali
tábláé.
Ennek megfelelően a következő
záradékokat alkalmazhatunk:
Ebben az
esetben mindkét tábla "lógó" sorai bekerülnek az eredménytáblába.
Ebben az
esetben a LEFT opció hatására csak
az első <táblanév> paraméterben megadott tábla
"lógó" sorai kerülnek be az eredmény táblába.
Ebben az esetben a RIGHT
opció hatására csak a második <táblanév>
paraméterben megadott tábla "lógó" sorai kerülnek be az eredmény
táblába.
Példa
Tekintsük
most a Dolgozó
és Kifizetés
táblákat, amelyek az alábbi módon néznek ki:
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T234578
|
Kiss István
|
Eger
|
1968. 12. 11.
|
120000
|
T343234
|
Kiss Timót
|
Eger
|
1970. 02. 28.
|
105000
|
T456734
|
Nagy József
|
Budapest
|
1972. 01. 30.
|
150000
|
T768545
|
Vári Ödön
|
Budapest
|
1958. 07. 12.
|
210000
|
T429877
|
Kovács János
|
Szeged
|
1967. 05. 12.
|
120000
|
A kifizetés
dátuma
|
A kifizetett
Bér
|
A levont
adóelőleg
|
A dolgozó
törzsszáma
|
2000.01.02.
|
76000
|
45000
|
T234578
|
2000.01.02
|
69000
|
43000
|
T343234
|
2000.01.02.
|
90000
|
50000
|
T456734
|
Készítsünk olyan listát, amely a dolgozók nevét és a számukra kifizetett összeget, adóelőleget, és a kifizetés dátumát név szerint ábécé sorrendben adja meg!
A megoldás hagyományos módon a külső
összekapcsolás nélkül:
SELECT Név,
A_kifizetett_bér, A_levont_adóelőleg, A_kifizetés_dátuma FROM Dolgozó, Kifizetés WHERE Dolgozó.A_dolgozó_törzsszáma =
Kifizetés.A_dolgozó_törzsszáma ORDER BY Név
Ugyanez megvalósítható a külső összekapcsolással:
SELECT Név,
A_kifizetett_bér, A_levont_adóelőleg, A_kifizetés_dátuma FROM Dolgozó JOIN Kifizetés
ON Dolgozó.A_dolgozó_törzsszáma =
Kifizetés.A_dolgozó_törzsszáma ORDER BY
Név
A keletkezett eredménytábla az
alábbi:
A dolgozó
Neve
|
A kifizetett
bér
|
A levont
adóelőleg
|
A kifizetés
dátuma
|
Kiss István
|
76000
|
45000
|
2000.01.02.
|
Kiss Timót
|
69000
|
43000
|
2000.01.02
|
Nagy József
|
90000
|
50000
|
2000.01.02.
|
Példa
Készítsünk
olyan listát, amely az előző példában szereplő feladatot úgy oldja meg, hogy a
listába azok a dolgozók is belekerülnek, akiknek még nem történt kifizetés.
A megoldás a következő:
SELECT Név,A_kifizetett_bér,
A_levont_adóelőleg, A_kifizetés_dátuma FROM
Dolgozó LEFT OUTER JOIN Kifizetés
ON Dolgozó.A_dolgozó_törzsszáma =
Kifizetés.A_dolgozó_törzsszáma ORDER BY Név
A keletkezett eredménytábla az
alábbi:
A dolgozó
neve
|
A kifizetett
bér
|
A levont
adóelőleg
|
A kifizetés
dátuma
|
Kiss István
|
76000
|
45000
|
2000.01.02.
|
Kiss Timót
|
69000
|
43000
|
2000.01.02
|
Kovács János
|
|||
Nagy József
|
90000
|
50000
|
2000.01.02.
|
Vári Ödön
|
Példa
Készítsünk
olyan listát, amely az azonos városban
született dolgozókat listázza ki páronként, úgy hogy a listán egy pár csak
egyszer szerepeljen!
Az alábbi parancsot használhatjuk:
SELECT Dolgozó1.Név,
Dolgozó2.Név FROM Dolgozó Dolgozó1, Dolgozó Dolgozó2
WHERE Dolgozó1.Név
< Dolgozó2.Név AND Dolgozó1.Sz_Helye
= Dolgozó2.Sz_Helye
Figyeljük meg a másodlagos nevek
használatát, valamint azt, hogy a feltételek között a Descartes szorzatból
kiszűrjük az egyes rekordoknak az önmagukkal való szorzatát, továbbá a
Dolgozó1.Név < Dolgozó2.Név
feltétellel azt, hogy egy pár
kétszer szerepeljen a listában.
A keletkezett eredménytábla az
alábbi:
Dolgozó1.A dolgozó neve
|
Dolgozó2.A
dolgozó neve
|
Kiss István
|
Kiss Timót
|
Nagy József
|
Vári Ödön
|
4.9 Beágyazott lekérdezések
Az SQL nyelv lehetőséget biztosít
arra, hogy a lekérdezések feltételében is használhatunk SQL lekérdező
parancsot. Ilyenkor a külső és a belső SELECT parancsot megkülönböztetünk, és
az ilyen jellegű lekérdezéseket beágyazott lekérdezéseknek(=alkérdésnek) nevezzük.
Főkérdés – a legkülső szintű kérdés, amely alkérdést (beágyazott
kérdést) tartalmazz.
Korrelált kérdés – olyan alkérdés, amely a főkérdés által kiválasztott
minden sorra újra végrehajtódik. Az alkérdés végrehajtásának a kimenete az
adott sortól függ.
A SELECT parancsok
szintaxisa megegyezik a már ismert formákkal, csupán arra kell ügyelnünk, hogy
a belső lekérdezésekre vonatkozóan bizonyos megkötéseknek kell teljesülnie.
A belső lekérdezés jellege alapján
következő eseteket különböztethetünk meg:
·
A belső lekérdezés egyetlen értéket szolgáltat. Ez a legegyszerűbb eset, ugyanis
ilyenkor minden a hagyományos módon történik, azzal a különbséggel, hogy a
feltételként megadott kifejezésben a belső lekérdezés által szolgáltatott
értéket használja fel a rendszer.
·
A belső lekérdezés egyoszlopos relációt szolgáltat. Ekkor olyan feltételeket adhatunk
meg, amelyek a belső lekérdezés által visszaadott oszlop adatait használja fel.
Ebben az esetben különböző predikátumokat használhatunk.
a).
<oszlopkifejezés> [NOT] IN <belső lekérdezés>
Ennél a típusnál az <oszlopkifejezés> paraméterben megadott
kifejezés értékéről fogja eldönteni a rendszer, hogy szerepel-e a belső
lekérdezés által előállított oszlop adatai között. Ha szerepel, akkor a
feltétel értéke igaz, ha nem, akkor hamis lesz. A NOT kulcsszó hatására a feltételt fordítva kell értelmezni.
Ennél a típusnál az <oszlopkifejezés>
paraméterben megadott kifejezés értékére vonatkozóan azt fogja vizsgálni a
rendszer, hogy a megadott reláció művelet
teljesül-e a belső lekérdezés által előállított oszlop adataira. Ha az ALL kulcsszót
használjuk, a feltétel csak akkor lesz
igaz, ha a reláció művelet az
oszlop minden elemére teljesül, míg az ANY használatakor elegendő egyetlen elemre
teljesülnie. A NOT
kulcsszó a feltétel ellentettjét jelenti.
·
A legáltalánosabb eset az, amikor a belső
lekérdezés eredménye általános reláció lesz. Ekkor csak kétféle feltételt
alkalmazhatunk.
a). Az egyik az, hogy a keletkezett reláció üres vagy sem. Ehhez a vizsgálathoz az EXISTS kulcsszót kell használnunk, amit
természetesen a NOT módosíthat. Az
opció formája az alábbi:
[NOT] EXISTS <belső
lekérdezés>
b). A
másik eset hasonló az egyoszlopos
relációról leírtakhoz, azzal a különbséggel, hogy a feltételben több
oszlopkifejezést adhatunk meg, amelyek egyezését külön‑külön fogja vizsgálni a
rendszer a belső lekérdezés által adott tábla sorainak elemeivel. Természetesen
a megadott lista és a lekérdezés eredménytáblája sorainak száma azonos kell,
hogy legyen. A szintaxisa a következő:
(<oszlopkifejezés> [,<oszlopkifejezés>]…) [NOT] IN <belső
lekérdezés>
Példa
Készítsünk
olyan listát, amely a Dolgozó táblából kilistázza azon dolgozók nevét és fizetését, akik az átlag alatt keresnek!
Az alábbi parancsot használhatjuk:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés < (SELECT
AVG(Fizetés) FROM Dolgozó)
A keletkezett eredménytábla az
alábbi:
A dolgozó
Neve
|
A dolgozó
Fizetése
|
Kiss István
|
120000
|
Kiss Timót
|
105000
|
Kovács János
|
120000
|
Példa
Készítsünk
olyan listát, amely a Dolgozó táblából kilistázza azon dolgozók nevét és fizetését, akik a fizetése a legnagyobb fizetéstől legfeljebb csak
60000 Ft-tal tér el!
Az alábbi parancsot használhatjuk:
SELECT Név, Fizetés FROM Dolgozó WHERE Fizetés+60000 >
(SELECT MAX(Fizetés) FROM Dolgozó)
A keletkezett eredménytábla az
alábbi:
A dolgozó
neve
|
A dolgozó
Fizetése
|
Nagy József
|
150000
|
Vári Ödön
|
210000
|
Példa
Az
előzőekben látott Kifizetés
tábla felhasználásával készítsünk olyan listát, amely a Dolgozó táblából kilistázza azon
dolgozók nevét és törzsszámát, akik számára még nem történt kifizetés!
Az alábbi parancsot használhatjuk:
SELECT Név,
A_dolgozó_törzsszáma FROM Dolgozó WHERE A_dolgozó_törzsszáma NOT IN
(SELECT A_dolgozó_törzsszáma FROM Kifizetés)
Egy másik lehetséges megoldás:
SELECT Név,
A_dolgozó_törzsszáma FROM Dolgozó WHERE NOT EXISTS (SELECT A_dolgozó_törzsszáma FROM Kifizetés WHERE Kifizetés.A_dolgozó_ törzsszáma =
Dolgozó.A_dolgozó_törzsszáma)
Figyeljük meg, hogy ez a második
megoldás egy olyan speciális esetet foglal magába, amikor a belső lekérdezésben
felhasználjuk a külső lekérdezés táblájának egy mezőjét is.
A keletkezett eredménytábla az
alábbi:
A dolgozó
neve
|
A dolgozó
törzsszáma
|
Vári Ödön
|
T768545
|
Kovács János
|
T429877
|
Példa
Készítsünk
olyan listát, amely a Dolgozó táblából kilistázza azon dolgozók adatait,
akik minden Egerben vagy Szegeden született dolgozónál többet
keresnek!
Az alábbi parancsot használhatjuk:
SELECT * FROM Dolgozó WHERE Fizetés > ALL (SELECT Fizetés FROM Dolgozó
WHERE Sz_Helye LIKE "Eger" OR Sz_Helye
LIKE "Szeged")
A dolgozó
törzsszáma
|
A dolgozó
neve
|
A dolgozó
születési
helye
|
A dolgozó
születési
ideje
|
A dolgozó
fizetése
|
T456734
|
Nagy József
|
Budapest
|
1972. 01. 30.
|
150000
|
T768545
|
Vári Ödön
|
Budapest
|
1958. 07. 12.
|
210000
|
Relációs műveletek
=
>
<
>=
<=
<> (vagy !=) - nem egyenlő
Fontosabb szimbólumok
( ) - lista,
:= - értékadás,
|| - konkatenáció,
-- - megjegyzés,
/* */ - megjegyzés.
Értékadás
<Változó> := <kifejezés>;
Példa.
String_1 := ‘Hello’ || ’World’ || ’!’;
10.1 Vezérlési struktúrák
10.1.1 IF parancs
IF logikai_kifejezés THEN
parancsok;
[ELSEIF logikai_kifejezés THEN
parancsok; ]
…….
[ELSE
parancsok;]
END IF;
Példa.
A következő blokk IF parancsot tartalmazz.
DECLARE
V_helyek_szama Szoba.helyek_szama;
v_Comment VARCHAR2(35);
BEGIN
SELECT termek INTO v_helyek_szama
FROM Szoba WHERE kod = 15;
IF v_helyek_szama < 50 THEN v_Comment := 'Kicsi';
ELSIF v_helyek_szama < 100 THEN v_Comment := 'Közepes';
ELSE v_Comment := 'Nagy';
END IF;
END;
10.1.2 Üres ( NULL) parancs
DECLARE
K NUMBER := 7;
BEGIN
IF K < 5 THEN
INSERT INTO temp (col) VALUES ('Nagyon kicsi');
ELSIF Kr < 10 THEN
INSERT INTO temp (col) VALUES ('Megfelel');
ELSE
NULL;
END IF;
END;
10.1.3 Címkék és GOTO parancs
A parancsok előtt << címke >> állhat:
<< címke >> parancs
A címkét a << ,>> határoló-jelek közé kell helyezni.
A
GOTO << címke >>;
parancs a vezérlést a << címke >> után álló parancsra adja. A GOTO parancs a vezérlést nem adhatja a beágyazott blokkba, vagy FOR ciklus , illetve IF parancs belsejébe.
Példa.
DECLARE
k BINARY_INTEGER := 1;
BEGIN
LOOP
INSERT INTO temp VALUES (k, 'Lépések száma');
k := k + 1;
IF k > 50
THEN GOTO Vége;
END IF;
END LOOP;
<<Vége>> INSERT INTO test (col) VALUES ('Vége!');
END;
A PL/SQL-ben három fajta ciklus létezik.
10.1.4 Egyszerű (LOOP) ciklus
LOOP
<Parancsok>
EXIT [WHEN feltététel]
END LOOP;
EXIT - feltétel nélküli kilépés a ciklusból,
EXIT WHEN <feltététel> – feltételes kilépés a ciklusból (ha a feltétel igaz).
Példa.
DECLARE
K BINARY_INTEGER := 1;
BEGIN
LOOP
INSERT INTO test (num_col) VALUES (K);
K := K + 1;
EXIT WHEN K > 50;
END LOOP;
END;
Vagy
DECLARE
k BINARY_INTEGER := 1;
BEGIN
LOOP
INSERT INTO test VALUES (k, 'A ciklus indexe');
k := k + 1;
IF k > 50
THEN EXIT;
END IF;
END LOOP;
END;
Példa.
A következő ciklus a kurzor soraival hajtja végre a műveleteket.
DECLARE
V1 VARCHAR2(20);
V2 VARCHAR2(20);
CURSOR Cursor_Students IS
SELECT nev, kod FROM students;
BEGIN
OPEN Cursor _Students;
LOOP
FETCH Cursor _Students INTO V1, V2;
EXIT WHEN Cursor_Students%NOTFOUND;
/* Parancsok, a cilkus magja. */
END LOOP;
CLOSE Cursor_Students;
END;
A kurzornak következő fontosabb attribútumai vannak:
· %FOUND – sort lehet leolvasni a kurzorból;
· %NOTFOUND – nincs több sor a kurzorban;
· %ISOPEN – meg van-e nyitva a kurzor;
10.1.5 WHILE ciklus
WHILE <feltétel> LOOP
<Parancsok>
END LOOP;
Példa.
DECLARE
k BINARY_INTEGER := 1;
BEGIN
WHILE k <= 50 LOOP
INSERT INTO test VALUES (k, ' A ciklus indexe’);
k := k + 1;
END LOOP;
END;
10.1.6 FOR ciklus
FOR <változó> IN [REVERSE] i_min .. i_max LOOP
<Parancsok, Ciklus magja>
END LOOP;
A <változó> felveszi i_min .. i_max minden értékét növekvő, vagy REVERSE esetén csökkenő irányban, és az adott érték mellett végrehajtódik a ciklus magja.
<változó>=i_min, i_min+1, i_min+2,..., i_max;
REVERSE esetén- <változó>I=i_max, i_max-1, i_max-2,..., i_min.
Példa.
BEGIN
FOR k IN 1..50 LOOP
INSERT INTO test VALUES (k, ' A ciklus indexe');
END LOOP;
END;
BEGIN
FOR k IN REVERSE 1..50 LOOP
INSERT INTO test VALUES (k, ' A ciklus indexe ');
END LOOP;
END;
10.1.7 KURZOR FOR ciklus
DECLARE
CURSOR Kurzor_Név IS
SELECT-parancs;
BEGIN
FOR Kurzor _Változó IN kurzor
LOOP
Parancsok
END LOOP;
END;
A kurzor FOR ciklus kényelmes eszköz a kurzor alkalmazására, mivel ebben az esetben nincs szükség a kurzor megnyitására, a sorainak leolvasására, és a kurzor bezárásába.
Példa.
DECLARE
...
CURSOR Cursor_Students IS
SELECT nev, kod FROM students;
BEGIN
K:=0;
FOR C_valt IN Cursor _Students;
LOOP
K:=K+1;
INSERT INTO test_tabla VALUES (C_valt.nev, K);
END LOOP;
END;
10.2 Blokkok
A PL/SQL program-konstrukcióknak blokk szerkezetűk van.
Két fajta blokk létezik
· névtelen blokk (Anonymous block)
· névvel rendelkező blokk (Named block).
A névtelen blokk a DECLARE vagy a BEGIN kulcsszóval kezdődik és az Oracle a blokkok mindegyik végrehajtása előtt újból kell lefordítja (compile). A névtelen blokk nem tárolódhat az AB-ban, és a program-egységek nem hivatkozhatnak rá.
A blokkot a következő program-egységek
eljárások
függvények
csomagok (modulok)
triggerek
tartalmazzák, és ezek a program-egységek tárolhatók az AB-ban.
A blokk általános struktúrája
[<<blokk_név>>]
[DECLARE ….]
BEGIN
….
[EXCEPTION….]
END;
A névtelen blokk nem tartalmazz <<blokk_nev>>-et.
DECLARE ….- a változók deklarálása (nem kötelező része a blokknak)
BEGIN...END; - a blokk törzse, a blokk egyetlen kötelező része
EXCEPTION…. – a blokk kivételkezelője (opcionális, nem kötelező része a blokknak).
Példa.
<<Pelda>>
DECLARE
v_Num1 NUMBER := 3;
v_Num2 NUMBER := 4;
v_String1 VARCHAR2(50) := 'Hello World!';
v_String2 VARCHAR2(50) := '-- ';
v_OutputStr VARCHAR2(50);
BEGIN
INSERT INTO test (num_col, char_col)
VALUES (v_Num1, v_String1);
INSERT INTO test (num_col, char_col)
VALUES (v_Num2, v_String2);
SELECT char_col INTO v_OutputStr
FROM test WHERE num_col = v_Num1;
DBMS_OUTPUT.PUT_LINE(v_OutputStr);
SELECT char_col INTO v_OutputStr
FROM test WHERE num_col = v_Num2;
DBMS_OUTPUT.PUT_LINE(v_OutputStr);
END Pelda;
10.3 Változók deklarálása
A változókat a DECLARE szekcióban deklaráljuk. Az Oracle lehetőséget ad a saját típusokat szerkesztésére is. A változó deklarálása:
Változó-neve típus [CONSTANT] [NOT NULL] [:= érték] ;
Leggyakoribb adattípusok:
· VARCHAR2
· NUMBER
· DATE
· BOOLEAN.
Numerikus típusok:
DEC
DECIMAL
DOUBLE PRECISION
INTEGER
INT
NUMERIC
REAL
SMALLINT
BINARY_INTEGER (- 2147483647... 2147483647)
NUMBER (m, n)
Példák
NUMBER 12.36 12.36
NUMBER (3) 123 123
NUMBER (3) 1234 HIBA
NUMBER (4,3) 1.234567 1.235
NUMBER (4,-3) 1234 1000
NUMBER (4,-1) 1234 1230
A BOOLEAN változó lehetséges értékei- TRUE, FALSE, NULL. Ha a lehetséges NULL értéket is figyelemben vesszük, akkor a logikai műveletek táblázatait lehet leírni, mint három-értékű logikát.
AND (és) táblázat
AND
T
F
NULL
T
T
F
Ismeretlen
F
F
F
F
NULL
Ismeretlen
F
Ismeretlen
OR (vagy) táblázat
OR
T
F
NULL
T
T
T
T
F
T
F
Ismeretlen
NULL
T
Ismeretlen
Ismeretlen
NOT (nem) táblázat
NOT
T
F
F
T
NULL
Ismeretlen
Egy változó típusát egy AB tábla oszlopának típusa alapján is lehet deklarálni a %TYPE bejegyzéssel.
Name student.nev%TYPE
A Name változó megkapja a student tábla nev oszlopának típusát. Ez a lehetőség különösen akkor hasznos, amikor az oszlop típusa valami okból később megváltozik, de a változó típusa is a %TYPE alapján automatikusan megváltozik, ami azt jelenti, hogy a programozónak ezzel a kérdéssel nem kell foglalkozni.
Példa.
DECLARE
Kod_diak NUMBER(5) := 10000;
V_Nev VARCHAR2(20);
BEGIN
SELECT Nev INTO V_Nev FROM students WHERE Id = Kod_diak;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO log_table (info) VALUES ('Nem létezik a 10000 kóddal jelölt Diák!');
END;
Példa.
DECLARE
v_Num1 NUMBER := 1;
v_Num2 NUMBER := 2;
v_String1 VARCHAR2(50) := 'Hello World!';
v_String2 VARCHAR2(50) := '-- ';
v_OutputStr VARCHAR2(50);
BEGIN
INSERT INTO test (num_col, char_col) VALUES (v_Num1, v_String1);
INSERT INTO test (num_col, char_col) VALUES (v_Num2, v_String2);
SELECT char_col INTO v_OutputStr FROM test WHERE num_col = v_Num1;
DBMS_OUTPUT.PUT_LINE(v_OutputStr);
SELECT char_col INTO v_OutputStr FROM test WHERE num_col = v_Num2;
DBMS_OUTPUT.PUT_LINE(v_OutputStr);
END;
10.4 Rekordok
A PL/SQL programokban rekordokat lehet létrehozni és utána alkalmazni. A rekord deklarációval egy új adattípust hozhatunk létre. Gyakran a rekord struktúráját úgy szerkesztik, hogy az megegyezzen egy tábla struktúrájának. Ebben az esetben a tábla sorai könnyen átírhatók a rekordba.
Először a rekord-típust kell deklarálni, és utána a rekord-változó megkaphatja a rekord-típust. A rekord mezőinek típusai PL/SQL adattípusúak lehetnek, de a %TYPE használatával hivatkozhatnak egy tábla oszlopának a típusára is. A mezőkhöz NOT NULL és DEFAULT záradékok tartozhatnak. A rekord mezőjére a következő képen hivatkozhatunk
rekord_változó.mező
Példa.
TYPE
Diak_Record IS RECORD (
Diak_Kod NUMBER (5),
Vezetek_Nev VARCHAR2 (20),
Kereszt_Nev VARCHAR2 (20));
Diak_Info Diak_Record;
A Diak_Info változó megkapja a Diak_Record típust.
DECLARE
TYPE t_Rec1Type IS RECORD (
Field1 NUMBER,
Field2 VARCHAR2(5));
TYPE t_Rec2Type IS RECORD (
Field1 NUMBER,
Field2 VARCHAR2(5));
v_Rec1 t_Rec1Type;
v_Rec2 t_Rec2Type;
/* v_Rec1 és v_Rec2 típusai különbözőek! */
BEGIN
v_Rec1 := v_Rec2; /* különböző típusok, HIBA !!! */
v_Rec1.Field1 := v_Rec2.Field1;
v_Rec2.Field2 := v_Rec2.Field2;
END;
DECLARE
TYPE Diak_Record IS RECORD (
Vezetek_Nev students.vezetek_nev%TYPE,
Kereszt_Nev students.kereszt_nev%TYPE,
Szak students.szak%TYPE);
V_Diak Diak_Record;
BEGIN
SELECT vezetek_nev, nev, szak INTO V_Diak
FROM students WHERE ID = 10000;
END;
A %ROWTYPE bejegyzés alkalmazása a rekord típusok deklarálásában
DECLARE
V_RoomRecord rooms%ROWTYPE
A %ROWTYPE által a V_RoomRecord rekord megkapja a room tábla struktúráját. Ez a lehetőség akkor lehet hasznos, ha például, a room tábla struktúrája megváltoztatjuk, de a %ROWTYPE alapján a rekord struktúrája is automatikusan megváltozik.
Az SQL parancsok változókat tartalmazhatnak, és ezzel összekapcsolhatók egymással egy program parancsai.
Példa.
DECLARE
v_NumCredits classes.num_credits%TYPE;
BEGIN
v_NumCredits := 3;
UPDATE Classes SET num_credits = v_NumCredits
WHERE szak = 'MAT' AND tantargy = 101;
END;
Példa.
DECLARE
v_DiakRecord students%ROWTYPE;
v_szak classes.szak%TYPE;
v_ tantargy classes.tantargy%TYPE;
BEGIN
SELECT * INTO V_DiakRecord
FROM students WHERE id = 10000;
SELECT department, course INTO v_szak, v_ tantargy
FROM classes WHERE kod = 99997;
END;
10.5 Objektum típusok
Az Objektumrelációs adatbázis-kezelő rendszer (ORDBMS – Object-Relation DataBase Management System) – támogatja mind a relációs eszközöket (kulcs, ...) mind az objektumorientált eszközöket (módszerek, ... ).
Az alkalmazások szempontjából fontos, hogy a PL/SQL programokban bizonyos összetett adat-struktúrákat egységesen lehessen kezelni. Ezzel a tulajdonsággal rendelkezik az objektum típus, amelyet absztrakt adattípusnak lehet tekinteni.
Az absztrakt adattípus – olyan adattípus, amely több altípusból tevődik össze. Az objektum típus attribútumokat és metódusokat tartalmazhat. Általános esetben, amikor az objektum típus metódusokat is tartalmaz, az két részből áll:
az objektum deklarálásából (specifikation);
az objektum törzséből.
Az objektum deklarálása az attribútumokat és a hozzá tartozó metódusok listáját tartalmazza. Az objektumban legalább egy attribútumnak kell lennie. Az objektumban a metódusok hiányozhatnak. Az objektum törzse a metódusok kódját tartalmazza. Egy objektumot csak az a felhasználó hozhat létre, aki a CREATE TYPE privilégiummal rendelkezik. A CREATE TYPE a RESOURCE szerephez tartozik. Más felhasználó akkor hozhat létre új típust, ha CREATE ANY TYPE privilégiummal rendelkezik. Ezek a feltételek a CREATE TYPE BODY parancsra is érvényesek.
10.5.1 Objektum típus létrehozása
CREATE [OR REPLACE] TYPE [felhasználó].típus_neve
AS OBJECT
(attribútum lista, [,metódusok listája])
Az attribútum deklarálása hasonlít a változók deklarálása a blokkban, de nem tartalmazhat %TYPE opciót, nem kaphat kezdő értéket, és a NOT NULL megszorítás sem alkalmazható.
Az objektum az AB szótárához tartozik, és mivel az objektumnak tulajdonosa kell, hogy legyen, ezért, ha a CREATE parancsban nincs megadva a felhasználó neve, akkor a deklarálandó objektumnak a tulajdonosa az adott felhasználó lesz. Egy másik felhasználó esetén annak a nevét meg kell adni. Csak az a felhasználó alkalmazhatja az objektumot, aki EXECUTE privilégiummal rendelkezik.
Hivatkozás az objektum attribútumára:
Objektum_neve.attribútum
Példa.
CREATE OR REPLACE TYPE StudentObj AS OBJECT (
ID NUMBER(5),
vezetek_nev VARCHAR2(20),
kereszt_nev VARCHAR2(20),
szak VARCHAR2(30),
kreditek NUMBER(3) );
Példa.
CREATE OR REPLACE TYPE Car AS OBJECT (
Model VARCHAR2(20),
Color VARCHAR2(20),
Cost NUMBER(6) );
CREATE OR REPLACE TYPE Car_Garage AS VARRAY(50) OF Car;
CREATE OR REPLACE TYPE Garage AS OBJECT (
Adress VARCHAR2(100),
CarCount NUMBER
AllCar Car_Garage);
A Car – objekt típus az autó egyedeket, a Garage – a garázs egyedeket, a Car_ Garage –típus pedig az autók csoportjait tartalmazzák.
10.5.1.1 Objektum típusú változó deklarálása
DECLARE Változó Objektum_típus;
DECLRE
MyCar Car;
MyGarage Garage;
A létrehozott típusok nem tartalmaznak metódusokat, ezért ebben az esetben nincs szükség az objektum törzsének deklarálására.
10.5.2 Metódusok
Mint már említettük, az objektum deklarálása tartalmazhat az objektumhoz tartozó metódusok listáját. A metódusok listája a következő deklarálási elemeket tartalmazhat:
[STATIC| MEMBER] PROCEDURE eljárás_deklarálása,
[STATIC| MEMBER] FUNCTION függvény_deklarálása,
……………………
Példa.
A Car objektumot kiegészítjük metódusokkal:
CREATE OR REPLACE TYPE Car AS OBJECT (
Model VARCHAR2(20),
Color VARCHAR2(20),
Cost NUMBER(6),
MEMBER FUNCTION GetCarInfo RETURN VARCHAR2,
PRAGMA RESTRICT_REFERENCES(GetCarInfo) );
A metódusokat az attribútumok után kell leírni. A PRAGMA RESTRICT_REFERENCES záradék engedélyezi a metódusokra való hivatkozást az SQL-parancsokból.
10.5.2.1 Metódusok implementálása
A metódusok kódját az objektum törzsében kell leírni:
CREATE [OR REPLACE] TYPE BODY [felhasználó].típus_neve AS| IS
<metódusok_törzseinek_listája>
Példa.
CREATE OR REPLACE TYPE BODY Car AS
MEMBER FUNCTION GetCarInfo RETURN VARCHAR2
IS
BEGIN
RETURN Modell || ’’ || Color || ‘’ || Cost;
END GetCarInfo;
END;
Hivatkozás a metódusra:
Objektum_neve.Metódus
Példa.
Az SQL*Plus-ban végrehajtjuk a következő programot:
DECLARE
Car1 Car:=
Car(’Audi’, ’Piros’, 3000000);
Car2 Car:=
Car(’BMW’, ’Fehér’, 2500000);
BEGIN
DBMS_OUTPUT.PUT_LINE(Car1.GetCarInfo);
DBMS_OUTPUT.PUT_LINE(Car2.GetCarInfo);
END;
Audi Piros 3000000
BMW Fehér 2500000
PL/SQL procedure successfully completed.
10.5.3 Kezdő érték bevitele az objektumba
Az objektum kezdő értékekeit a konstruktor által legegyszerűbben megadni. Az Oracle mindegyik objektum-típushoz létrehoz automatikusan egy konsztruktor-függvényt.
Például, a Garage objektum konstruktora a következő függvény lesz:
FUNCTION Garage(
Adress IN VARCHAR2(100);
CarCount IN NUMBER
AllCar IN CarGarage)
RETURN Garage;
10.5.4 Objektumok módosítása és törlése
ALTER TYPE [felhasználó.]<típus_neve>
REPLACE AS OBJECT
(<OBJECT-típus deklaráció>);
A parancsban nem csak a módosított elemeket kell megadni, hanem újból kell deklarálni azokat az elemeket, amelyek nem váltóznak. A metódus kódjának a módosítása a
CREATE OR REPLACE TYPE BODY [felhasználó.]típus_neve AS| IS
<metódusok_törzseinek_listája>
paranccsal történik.
Objektum-típus törlése
Az objektum-típus törlése több változatban történhet:
· DROP TYPE [felhasználó.]típus_neve
Ebben az esetben az Oracle csak akkor törli az objektum-típust, ha más objektum-típus nem hivatkozik rá.
· DROP TYPE [felhasználó.]típus_neve FORCE
A FORCE záradék az objektum-típus törlését engedélyezi még akkor is, ha az adott objektum-típusra más AB-objektum-típus hivatkozik.
· DROP TYPE BODY [felhasználó.]típus_neve
Ez a parancs törli az objektum-típus törzsét, de nem törli az objektum-típus deklarációját.
10.5.5 Objektumok az adatbázisban
Az Oracle fontos tulajdonsága, hogy az objektumokat az AB táblákban lehet tárolni. Ez két változatban valósítható meg. Az objektumot tárolni lehet, mint
· Objektum-oszlop;
· Objektum-sor.
10.5.5.1 Objektum-oszlop
Ebben az esetben az objektum a táblában ugyanúgy oszloponként tárolódik, mint a többi elsődleges típus.
Példa.
CREATE TABLE Cars(
Key NUMBER PRIMARY KEY,
OneCar Car);
A Cars tábla második oszlopa objektum-típusú.
INSERT INTO Cars VALUES(1,
Car(’Skoda’, ’Piros’, 2000000 ) );
INSERT INTO Cars VALUES(2,
Car(’Lada’, ’Zöld’, 1200000 ) );
Az adatok bevítelére a táblába az INSERT parancs a Car konstruktort alkalmazza.
A Car tábla tartalmát az SQL*Plus-ban így lehet megjeleníteni
SELECT * FROM Cars;
KEY ONECAR(MODEL, COLOR, COST)
1 CAR(’Skoda’, ’Piros’, 2000000)
2 CAR(’Lada’, ’Zöld’, 1200000 )
10.5.5.2 Objektum-sor
Ebben az esetben az objektum a tábla egész sorával azonosul, és a tábla nem tartalmazhat más oszlopokat.
CREATE TABLE Tábla_név OF objektum-típus;
Példa.
CREATE TABLE CarRows OF Car;
INSERT INTO CarRows VALUES(Car(’Skoda’, ’Piros’, 2000000 ) );
INSERT INTO CarRows VALUES(Car(’Lada’, ’Zöld’, 1200000 ) );
SELECT * FROM CarsRows;
MODEL COLOR COST
Skoda Piros 2000000
Lada Zöld 1200000
10.5.6 Objektumok az SQL parancsokban
Az SQL-parancsok végrehajtásának módja nem változik, ha egy tábla objektum-oszlopokat is tartalmaz. Például, egy objektum értékét egy vele azonos típusú objektum típusú változóba lehet átmásolni. Végrehajtunk néhány DML-parancsot a Cars táblával.
DECLARE
C CAR;
Id NUMBER;
BEGIN
SELECT MAX(Key) INTO Id FROM Cars;
SELECT OneCar INTO C FROM Cars
WHERE Key=Id;
C.Model:=’BMW’;
C.Color:=’Fekete’;
INSERT INTO Cars VALUES (Id+1, C);
END;
Az eredmény:
SELECT * FROM Cars;
KEY ONECAR(MODEL, COLOR, COST)
------ ---------------------------------------------
1 CAR(’Skoda’, ’Piros’, 2000000)
2 CAR(’Lada’, ’Zöld’, 1200000 )
3 CAR(’BMW’,’Fekete’, 1200000)
Az SQL parancsokban az objektum attribútumaira csak úgy hivatkozhatunk, hogy megadjuk a tábla másodlagos (alias) nevét is.
Példa.
SELECT C.OneCar.Model FROM Cars C;
ONECAR.MODEL
------------------------
Skoda
Lada
BMW
Akkor is szükség van a tábla másodlagos nevére, ha hivatkozni akarunk az objektum metódusára.
SELECT C.OneCar.GetCarInfo() FROM Cars C;
C.ONECAR.GETCARINFO()
----------------------------
Skoda Piros 2000000
Lada Zöld 1200000
BMW Fekete 1200000
Az objektum-sorok esetén az objektum attribútumait ugyanúgy lehet alkalmazni, mintha azok hagyományos relációs tábla oszlopai lennének.
SELECT C.OneCar.GetCarInfo() FROM CarsRows C;
C.GETCARINFO()
----------------------------
Skoda Piros 2000000
Lada Zöld 1200000
BMW Fekete 1200000
10.6 Összetett konstrukciók (COLLECTIONS)
Az Oracle a következő összetett konstrukciót tartalmaz:
Indexelt táblák (Index-by tables)
Beágyazott táblák (Nested tables)
Tömbök (Változó hosszuságuak),
amelyek objektum tulajdonsággal rendelkeznek, mivel tartalmaznak attribútumokat és metódusokat.
Az indexelt táblák és a beágyazott táblák a PL/SQL táblákat alkotják. A beágyazott táblákat az AB táblákban is lehet tárolni (ezért kapták a nevüket). Az indexelt táblák nem tárolódhatnak az AB táblákban, és csak a PL/SQL programokban alkalmazhatók.
10.6.1 Indexelt táblák
Az indexelt táblát nem azonosak az adatbázis táblával!.
Az indexelt tábla szintaxisa hasonlít a tömb szintaxisára. Mielőtt egy indexelt táblát deklarálnánk, egy PL/SQL blokkban létre kell hozni a típusát:
TYPE tábla_tipus IS TABLE OF tipus
INDEX BY BINARY_INTEGER;
A tábla típusa objektum típusú is lehet.
Az INDEX BY BINARY_INTEGER paraméter kulcs jellegű, kötelező az indexelt táblák esetén, de a beágyazott táblákban nem alkalmazhatók.
Az indexelt tábla két oszlopot tartalmaz:
KEY (kulcs)
VALUE (érték)
A kulcs típusa – BINARY_INTEGER, a kulcs lehetséges értékei
(-2147483647...+ 2147483647),
a VALUE típusát a deklarációban kell megadni.
Nem kötelező, hogy a tábla elemeinek indexei egymás utáni értékeket kapjanak.
Példa.
TYPE t_CharacterTable IS TABLE OF VARCHAR2(10)
INDEX BY BINARY_INTEGER;
Az indexelt tábla deklarálása:
V_Characters t_CharacterTable;
Példa.
DECLARE
TYPE t_NameTable IS TABLE OF students.vezetek_nev%TYPE
INDEX BY BINARY_INTEGER;
TYPE t_DateTable IS TABLE OF DATE
INDEX BY BINARY_INTEGER;
V_ Names t_NameTable;
V_ Dates t_DateTable;
A tábla elemeire az index által hivatkozhatunk
Tabla_név(index)
BEGIN
V_ Names(1):= ’Szabó’;
V_ Dates(-4):= SYSDATE - 1;
END;
SET SERVEROUTPUT ON
DECLARE
TYPE t_StudentTable IS TABLE OF students%ROWTYPE
INDEX BY BINARY_INTEGER;
V_Diak t_StudentTable;
BEGIN
SELECT * INTO V_Diak(10001)
FROM students WHERE id = 10001;
V_Diak(10001).vezetek_nev := 'Kovács';
DBMS_OUTPUT.PUT_LINE(V_Diak(10001).vezetek_nev);
END;
10.6.2 Beágyazott táblák
A Beágyazott táblára úgy tekinthetünk, mint egy adatbázis táblára, amelynek két oszlopa van
KEY (kulcs)
VALUE (érték)
(mint az indexelt táblában).
A beágyazott tábla egy AB tábla oszlopa lehet.
A beágyazott tábla típusának deklarálása:
TYPE tábla_típus IS TABLE OF típus;
A tábla elemeinek inicializálása a konstruktor-függvény használatával történik. A létrehozott tábla-elemek kezdő indexe csak egy lehet, és a következő értékei mindég csak eggyel növekedhetnek.
Példa.
DECLARE
K INTEGER;
TYPE Num_Tab IS TABLE OF NUMBER;
Tab_1 Num_Tab :=Num_Tab(-1);
Tab_2 Num_Tab :=Num_Tab(1, 2, 3, 5, 7);
Tab_3 Num_Tab :=Num_Tab( );
BEGIN
Tab_1(1):=12345;
FOR K IN 1..5 LOOP
DBMS_OUTPUT.PUT(Tab_2(K) || ‘ ‘);
END LOOP;
DBMS_OUTPUT.NEW_LINE;
END;
1 2 3 5 7
A példában az inicializáláskor a táblák elemei a következő értékeket kapták:
Tab_1(1)=( -1),
Tab_2(1)=(1), Tab_2(2)=(2), Tab_2(3)=(3), Tab_2(4)=(5), Tab_2(15=(7);
A Tab_3 létezik, de egyetlen elemet sem tartalmaz. A programban a Tab_1 tábla első eleme megváltozik (12345 értéket kap).
10.6.3 Tömbök
Az Oracle-ban használható tömb megfelel a C és a Java nyelvekben alkalmazott tömböknek. A tömb elemeire ugyanúgy lehet hivatkozni, mint az indexelt, vagy a beágyazott táblák elemeire. A tömb indexnek a kezdő értéke mindig egye, és eggyel növekszik.
A tömb típus deklarálása:
TYPE típus_név IS VARRAY <maximális_méret>
OF elemek_típusa [NOT NULL];
Az elemek_típusa alap-, rekord, vagy objektum típusú lehet. Ezenkívül, a %TYPE segítségével az AB tábla oszlop típusát lehet alkalmazni, a %ROWTYPE pedig az AB tábla sorai alapján egy rekord típust hoz létre.
A NOT NULL nem engedélyezi, hogy a tömb üres elemeket tartalmazzon.
Példa.
TYPE Num_List IS VARRAY (20)
OF NUMBER(3) NOT NULL;
TYPE Car_List IS VARRAY (100)
OF CarArr%ROWTYPE;
TYPE Car_Arr IS VARRAY (20)
OF Car;
A tömb kezdő értékeit a konstruktorok által lehet megadni.
DECLARE
TYPE Var_Num IS VARRAY (20) OF NUMBER;
Var_1 Var_Num := Var_Num(1, 2, 3);
BEGIN
DBMS_OUTPUT.PUT_LINE(Var_1(1));
Var_1(1):=15;
DBMS_OUTPUT.PUT_LINE(Var_1(1));
END;
1
15
A tömb méretét az EXTEND metódussal lehet növelni.
10.6.4 Összetett konstrukciók metódusai
Mivel a tömbök és beágyazott táblák objektum típusú konstrukciók, azok metódusokkal is rendelkeznek, az indexelt táblákhoz pedig attribútumok tartoznak. A metódusokra, mint az attribútumokra is s következő képen lehet hivatkozni:
konstrukció_eleme.metódus
vagy
konstrukció_eleme.attribútum
A metódusok csak a blokkokban alkalmazhatók, és nem az SQL-parancsokban.
Az Oracle felismeri a következő beépített metódusokat:
EXISTS (az eredmény típusa – BOOLEAN)
COUNT (az eredmény típusa – NUMBER)
FIRST (az eredmény típusa – BINARY_INTEGER)
LAST (az eredmény típusa – BINARY_INTEGER)
NEXT (az eredmény típusa – BINARY_INTEGER)
PRIOR (az eredmény típusa – BINARY_INTEGER)
EXTEND (új elemeket szúr be a konstrukcióba)
TRIM (törli a konstrukció utolsó elemeit)
DELETE (törli az elemeket a konstrukcióban)
10.6.4.1 EXISTS metódus.
Az EXISTS metódust akkor alkalmazzuk, ha akarjuk megállapítani, hogy létezik-e az n-ik elem
EXISTS(n)
A metódus eredménye TRUE, ha az adott elem létezik, különben FALSE.
Példa.
DECLARE
TYPE t_Vezetek_NevTable IS TABLE OF students.vezetek_nev%TYPE
INDEX BY BINARY_INTEGER;
Vezetek_Nevs t_Vezetek_NevTable;
BEGIN
Vezetek_Nevs(1) := 'Szabó';
Vezetek_Nevs(3) := 'Kiss';
IF Vezetek_Nevs.EXISTS(1) THEN
INSERT INTO test (char_col) VALUES
( 'Az 1 sor létezik!');
ELSE
INSERT INTO test (char_col) VALUES
(' Az 1 sor nem létezik!!');
END IF;
IF Vezetek_Nevs.EXISTS(2) THEN
INSERT INTO test (char_col) VALUES
(' A 2 sor létezik!');
ELSE
INSERT INTO test (char_col) VALUES
(' A 2 sor nem létezik!');
END IF;
END;
10.6.4.2 COUNT metódus
A COUNT metódus nem tartalmaz paramétereket, és az eredménye a konstrukció elemeinek száma.
Példa.
DECLARE
TYPE Tabla_1 IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
Szamok Tabla_1;
Osszesen NUMBER;
BEGIN
FOR k IN 1..50 LOOP
Szamok(k) := k;
END LOOP;
Osszesen := Szamok.COUNT;
DBMS_OUTPUT.PUT_LINE(Osszesen);
END;
50
10.6.4.3 NEXT, PRIOR, FIRST és LAST metódusok
A NEXT metódus növeli a kulcs (KEY) értékét. A
NEXT(n)
visszaadja az n után következő indexet (növekvő irányban),
a PRIOR metódus pedig csökkenti a kulcs (KEY) értékét
PRIOR(n)
az n előtti indexet kapjuk (csökkenő irányban).
Ha az adott értékű kulcs (n) nem létezik, akkor a NEXT és PRIOR eredménye NULL lesz.
A FIRST metódus az index első értékét adja, a LAST pedig – az utolsó értékét. A FIRST és a LAST metódusok nem tartalmaznak paramétert.
Példa.
DECLARE
TYPE Nev_Table IS TABLE OF students.nev%TYPE
INDEX BY BINARY_INTEGER;
v_Nev Nev_Table;
v_Index BINARY_INTEGER;
BEGIN
-- Új sorokat szúrunk be a táblába.
v_Nev(43) := 'Sándor';
v_Nev(50) := 'Mária';
v_Nev(47) := 'Iván';
v_Index := v_Nev.FIRST; -- v_Index=43
v_Index := v_Nev.LAST; -- v_Index=50
END;
Példa.
DECLARE
TYPE Szakok IS TABLE OF students.szak%TYPE
INDEX BY BINARY_INTEGER;
v_Szak t_Szakok;
v_Index BINARY_INTEGER;
BEGIN
v_Szak(-7) := 'Számítástechnika';
v_Szak(4) := 'Történelem';
v_Szak(5) := 'Matematika';
v_Index := v_Szak.FIRST;
LOOP -- a v_Index a következő értékeket kapja a ciklusban- -7, 4, 5.
INSERT INTO test (num_col, char_col) VALUES (v_Index, v_Szak(v_Index));
EXIT WHEN v_Index = v_Szak.LAST;
v_Index := v_Szak.NEXT(v_Index);
END LOOP;
END;
Példa.
DECLARE
TYPE Char_Tab IS TABLE OF CHAR(1);
Char_1 Char_Tab:= Char_Tab(‘a’, ’b’, ’c’, ’d’, ’e’);
Ind INTEGER;
BEGIN
Ind:=Char_1.FIRST;
WHILE Ind<= Char_1.LAST LOOP
DBMS_OUTPUT.PUT(Char_1(Ind));
Ind:=Char_1.NEXT(Ind);
END LOOP;
DBMS_OUTPUT.NEW_LINE;
Ind:=Char_1.LAST;
WHILE Ind >= Char_1.FIRST LOOP
DBMS_OUTPUT.PUT(Char_1(Ind));
Ind:=Char_1.PRIOR(Ind);
END LOOP;
DBMS_OUTPUT.NEW_LINE;
END;
abcde
edcba
10.6.4.4 EXTEND metódus
Az EXTEND metódus új elemeket szúr be a konstrukcióba. A metódus három formában alkalmazható
· EXTEND
· EXTEND(n)
· EXTEND(n, i)
Az EXTEND paraméterek nélkül a konstrukció végére NULL (üres) elemet szúr be;
EXTEND (n) a konstrukció végére n NULL (üres) elemet szúr be;
EXTEND (n, i) az i számú elemet n-szer a konstrukció végére másolja át.
Ha a konstrukció a NOT NULL záradékkal volt létrehozva, akkor az EXTEND csak az utolsó formájában alkalmazható.
Példa.
A SQL*Plus-ban:
DECLARE
TYPE Num_Tab IS TABLE OF NUMBER;
TYPE Num_Var IS VARRAY(25) OF NUMBER;
Tab_1 Num_Tab :=Num_Tab(1, 2, 3, 4, 5);
Tab_2 Num_Var :=Num_Var(1, 2, 3, 4, 5);
BEGIN
Tab_1(26) := -7; -- A Tábla 26-ik eleme nem létezik
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
DBMS_OUTPUT.PUT_LINE(‘A Tábla 26-ik eleme nem létezik’);
END;
--A PL/SQL táblát lehet bővíteni:
Tab_1.EXTEND(30);
Tab_1(26) := -7; -- most már Tab_1(26) létezik
-- A tömböt csak a maximális méretig (25) lehet bővíteni.
Tab_2(26) := -7;
EXCEPTION
WHEN SUBSCRIPT_OUTSIZE_LIMIT THEN
DBMS_OUTPUT.PUT_LINE(‘Nem sikerült a tömb méretét növelni a 30-ik elemig’);
END;
END;
10.6.4.5 TRIM metódus
A TRIM metódus törli a konstrukció utolsó elemét (elemeit). Két formája létezik
TRIM és
TRIM(n)
A TRIM az utolsó elemet törli. A TRIM(n) törli az utolsó n elemet. Ha n>COUNT, akkor SUBSCRIPT_BEJOND_COUNT kivételes szituáció következik be. A TRIM végrehajtása után a COUNT értéke is megváltozik.
10.6.4.6 DELETE metódus
A DELETE metódus egy vagy több elemet töröl az indexelt vagy beágyazott táblából. A DELETE a tömbök esetén nem alkalmazható. Három formája van
DELETE;
DELETE(n);
DELETE(n, m)
DELETE törli az egész táblát.
DELETE(n) azt az elemet törli, amelynek az indexe = n.
DELETE(n, m) azokat az elemeket törli, amelyeknek az indexe n és m között van.
Példa.
DELETE (5) -- törli az 5. elemet
DELETE(5, 8) -- törli az 5,6,7,8 indexű elemeket
DECLARE
TYPE Tabla_ertekek IS TABLE OF VARCHAR2(10)
INDEX BY BINARY_INTEGER;
Ertekek Tabla_ertekek;
BEGIN
Ertekek(1) := 'Egy';
Ertekek(3) := 'Három';
Ertekek(-2) := 'Minusz kettő';
Ertekek(0) := 'Zeró';
Ertekek(100) := 'Száz';
DBMS_OUTPUT.PUT_LINE('Törlés előtt, összesen=' || Ertekek.COUNT);
Ertekek.DELETE(100);
DBMS_OUTPUT.PUT_LINE('Első törlés után, összesen=' || Ertekek.COUNT);
Ertekek.DELETE(1,3); -- Törli az 1 és 3 indexű elemeket
DBMS_OUTPUT.PUT_LINE('Második törlés után, összesen=' || Ertekek.COUNT);
Ertekek.DELETE; -- Törli az összes elemet
DBMS_OUTPUT.PUT_LINE(' Utólsó törlés után, összesen=' || Ertekek.COUNT);
END;
10.6.5 Összetett konstrukciók alkalmazása az adatbázisban
A beágyazott táblákat és a tömböket (indexelt táblákat nem) lehet tárolni az adatbázisban. Az összetett konstrukciókat akkor lehet bevinni az AB táblába, ha mint az SQL, mint a PL/SQL-parancsokból láthatók (elérhető) a konstrukció típusa. Ez csak akkor lehetséges, ha a konstrukció a CREATE TYPE paranccsal volt létrehozva, mint objektum típus, és nem lokálisan egy PL/SQL-blokkban.
Példa.
CREATE OR REPLACE TYPE NameList AS
VARRAY(20) OF VACHAR2(30);
Miután létrehoztuk a NameList típust, utána ezt a típust alkalmazhatjuk a blokkokban, eljárásokban, és csomagokban a változók deklarálására.
DECLARE
TYPE DateList AS
VARRAY(10) OF DATE;
v_DateList DateList;
v_Names NameList;
BEGIN
NULL;
END;
Az a típus, amelyet a CREATE OR REPLACE TYPE parancs hozott létre (például, NameList), az globális típus. A DateList- lokális típus, mivel az csak az adott blokkban érvényes, és az AB-ból nem érhető el.
Az AB tábla oszlopa tömb-típusú is lehet. Ebben az esetben a tábla egy sorához egy tömb tartozik. Tehát, a különböző sorok más és más tömböket tartalmazhatnak.
Példa.
CREATE OR REPLACE TYPE ArrStr AS
VARRAY(20) OF VACHAR2(30);
CREATE TABLE Varray_Tab (
Id NUMBER PRIMARY KEY,
Name VARCHAR2(20),
VarStr ArrStr);
INSERT INTO Varray_Tab VALUES(1, ’Gyümölcsök’, ArrStr(’Körte’, ’Alma’, ’Szilva’));
INSERT INTO Varray_Tab VALUES(2, ’Zöldségek’, ArrStr(’Káposzta’, ’Paradicsom’));
Az AB tábla oszlopában beágyazott táblák is tárolódhatnak. Ebben az esetben a tábla mindegyik sora tartalmaz egy hozzá tartozó beágyazott táblát.
Példa.
CREATE OR REPLACE TYPE Nested_Table AS
TABLE OF NUMBER;
CREATE TABLE Test_Nested (
Id NUMBER,
Name VARCHAR2(20),
Tab_Values Nested_Table)
NESTED TABLE Tab_Values STORE AS N_Tab;
Az N_Tab a tárolási tábla (store table) neve, és ez a tábla a Tab_Values beágyazott táblákat tárolja. Ez azt is jelenti, hogy a Test_Nested tábla a beágyazott táblákat direkt módon nem tárolja, hanem csak a mutatókat tárolja a beágyazott táblákra. Új sorok beszúrása a tárolt táblák esetén is az INSERT SQL DML paranccsal történhet.
INSERT INTO Test_Nested VALUES(1, ’első sor’, Nested_Table(1, 1, 1, 2, 2, 3, 3));
INSERT INTO Test_Nested VALUES(2, ’második sor’, Nested_Table(5, 6));
INSERT INTO Test_Nested
VALUES(1, ’harmadik sor’, Nested_Table(7, 8, 9, 10, 11, 12));
Az adatok módosítására az UPDATE parancsot alkalmazzuk, az adatok törlésére pedig – a DELETE parancsot. Az összetett konstrukciókat az AB táblából a SELECT paranccsal változókba lehet átírni (mint alap típusú adatokat). Amikor egy beágyazott táblát átírunk egy PL/SQL változóba, akkor a változó elemei megkapják az index értékeit növekvő sorrendbe egytől kezdve, az index maximális értéke pedig COUNT lesz. A következő példák bemutatják, hogy kaphatjuk meg a beágyazott tábla elemeit.
SELECT Tab_Values FROM Test_Nested
WHERE Id = 1;
TAB_VALUES
-------------------
NESTEDTABLE(1, 1, 1, 2, 2, 3, 3)
Egy másik lehetőség-
SELECT * FROM TABLE (SELECT Tab_Values
FROM Test_Nested WHERE Id = 1);
COLUMN_VALUE
------------------------
1
1
1
2
2
3
3
SELECT * FROM TABLE (SELECT Tab_Values
FROM Test_Nested WHERE Id = 1)
WHERE Column_Value>1
ORDER BY Column_Value DESC;
COLUMN_VALUE
------------------------
3
3
2
2
SELECT * FROM TABLE (SELECT Varray_Tab.VarStr
FROM Varray_Tab WHERE Id = 1);
COLUMN_VALUE
------------------------
Körte
Alma
Szilva
http://aries.ektf.hu/~holovacs/AB/Referencia.htm#Referencia
http://sql.misi.eu/
http://szoftverkli.biz/sql_alapok/elmelet.html
http://sql.misi.eu/
http://szoftverkli.biz/sql_alapok/elmelet.html
http://www.sze.hu/~szorenyi/sz03/htm/doc/INNJOIN.htm
https://www.nive.hu/index.php?option=com_content&view=article&id=727
http://www.sze.hu/~szorenyi/sz03/htm/doc/_gzacc.htm
https://www.nive.hu/index.php?option=com_content&view=article&id=727
http://www.sze.hu/~szorenyi/sz03/htm/doc/_gzacc.htm
Nincsenek megjegyzések:
Megjegyzés küldése