SQL tanköny tartalomjegyzéke
----- ----- --------- ----- ----
2.1. Bevezetés 1
2.2. Adat definició 3
2.3. Adat manipulálás 5
2.4. Cursor műveletek 7
2.5. Nézetek 9
2.6. Adat vezérlés 10
2.7. Néhány eltérés a DB2-töl 12
3.1. Alap adat tárgyak 16
3.2. Modulok, eljárások, beágyazott SQL. 20
3.3. Adatvédelem, integritás és tranzakció
feldolgozás 23
3.4 Alapvetö nyelvi elemek 26
3.5. Jelölés 28
4. Adatdefinició: a séma leiró nyelv
4.1. Szintaxis 31
4.2. Alap táblák 32
4.3. Privilégiumok 35
5. Adat manipul ció: a modul nyelv
5.1. Szintaxis 37
5.2. Eljárások, paraméterek és manipulativ
utasitások 38
5.3. Indikátor paraméterek 40
5.4. COMMIT és ROLLBACK 42
6. Adat manipuláció: cursor müveletek
6.1. Bevezetés 43
6.2. Cursorok 44
6.3. Cursoron alapuló manipulációk 47
6.4. Egy globális példa 49
7. Adat manipuláció: nem cursor müveletek
7.1. Bevezetés 53
7.2. SELECT 53
7.3. INSERT 56
7.4. Keresett UPDATE 57
7.5. Keresett DELETE 58
8. Nézetek
8.1. Bevezetés 60
8.2. Nézet definició 62
8.3. Visszanyerési müveletek 64
8.4. Aktualizálási müveletek 66
9. Általános nyelvkonstrukciók
9.1. Lekérdezés kifejezések 70
9.2. Lekérdezés specifikációk 71
9.3. Skalár kifejezések 72
9.4. Függvények 74
9.5. Tábla kifejezések 77
9.6. Keresési feltételek 84
9.7. Nem kvantoros predikátumok 85
9.8. Al-lekérdezések 91
9.9. Kvantoros predikátumok 93
10. Beágyazott SQL
10.1. Bevezetés 96
10.2. Egy teljes példa 96
10.3. Felmerülö szempontok 98
11. Definiciós kiterjesztések
11.1. Bevezetés 101
11.2. Alaoértékek 101
11.3. CHECK követelmények 102
11.4. Referenciális integritás 103
12. Manipulativ kiterjesztések
12.1. Ortogonalitás továbbfejlesztések 109
12.2. Csusztató cursorok 111
A. Függelék
Mintafeladatok
A.1. Bevezetés 112
A.2. Adat definició 112
A.3. Adat manipuláció: visszanyerési müveletek 115
A.4. Adat manipuláció: akzualizálási müveletek 119
A.5. Beágyazott SQL 119
A.6. Válaszok 120
B. Függelék
Egy SQL nyelvtan
B.1. Bevezetés 130
B.2. Séma definiáló nyelv 131
B.3. Modul nyelv 132
B.4. Manipulativ utasitások 132
B.5. Lekérdezés kifejezések 134
B.6. Keresési feltételek 134
B.7. Skalár kifejezések 136
B.8. Egyebek 137
C. Függelék
Nyelvi szintek és konformancia 138
Betűrendes mutató 140
__________ ______ ____ _____ _______ ______ _______________
Az SQL áttekintése
2.1 BEVEZETÉS
A jelen fejezet célja a szabványos SQL fö lehetöségei közül
néhánynak rövid és nagyon "informális" bevezetö ismertetése,
és ezzel az ut egyengetése az ezt követö fejezetekben a nyelv
szabályszerü és alaposabb leirásának megértéséhez. A fejezet
nagyjából a szerzönek a Relational Database: Selected Writings
/relációs adatbázis| válogatott irások/, /Addison-Wesley,1986/
könyvében lévö 1.fejezeten /"Relációs adatbázis:áttekintés"/
alapul.
Az SQL nyelvnek az a feladata, hogy támogassa egy relá-
ciós adatbázisban lévö adatok definiálását, manipulálását és
vezérlését. Egy relációs adatbázis egyszerüen olyan adatbázis,
amelyet a felhasználó táblák gyüjteményeként észlel - ahol
egy tábla sorok nem rendezett gyüjteménye /"reláció" egysze-
rüen egy matematikai kifejezés egy ilyen táblázathoz/. Egy pld,
a szállitók és alkatrészek adatbázisa, a 2.1-es ábrában lát-
ható. Ebben az ábrában az S, P és SP táblák a szállitókat, al-
katrészeket illetve a szállitók által az alkatrészek elszálli-
tásait reprezentálják. Megjegyezzük, hogy mindegyik tábla fájl-
ként is tekinthetö ugy, hogy a sorok a rekordokat és az oszlo-
pok a mezöket reprezentálják. Az SQL szabvány azonban mindig
a "sor" /row/ és "oszlop" /column/ kifejezéseket használja,
sohasem használja a "rekord" /record/ és "mezö" /field/ kifeje-
zéseket és ebben a könyvben ezért mi is általában hasonlóképpen
teszünk.
Az SQL "adatmanipuláló" utasitások, melyek adat vissza-
nyerési és aktualizálási feladatokat hajtanak végre - vagy in-
teraktiv módon, vagy egy alkalmazási programból hivhatók meg.
a 2.2 ábra mutatja mindkét esetet; bemutat egy olyan adat
visszanyerési müveletet /SELECT az SQL-ben/, amely mind /a/
interaktiv módon, mind pedig /b/ egy PL/I programból hasz-
nálható.
sql.doc Page: 2
2.1 ábra. Szállitók és alkarészek adatbázis /minta értékek/
___ _____ ______ ______ ___ ___ ___
S SNO SNAME STATUS CITY SP SNO PNO QTY
___ _____ ______ ______ ___ ___ ___
S1 Smith 20 London S1 P1 300
S2 Jones 10 Paris S1 P2 200
S3 Blake 30 Paris S1 P3 400
S4 Clark 20 London S1 P4 200
S5 Adams 30 Athens S1 P5 100
S1 P6 100
___ _____ ______ ______ ____ S2 P1 300
P PNO PNAME COLOR WEIGHT CITY S2 P2 400
___ _____ ______ ______ ____ S3 P2 200
P1 Nut Red 12 London S4 P2 200
P2 Bolt Green 17 Paris S4 P4 300
P3 Screw Blue 17 Rome S4 P5 400
P4 Screw Red 14 London
P5 Can Blue 12 Paris
P6 Cog Red 19 London
ahol:
SNO = szállitó száma
SNAME = szállitó neve
STATUS = állapot
CITY = város
PNO = alkatrész száma
PNAME = alkatrész neve
COLOR = szin
WEIGHT = suly
Nut = anya
Bolt = fejes csavar
Can = bütyök
Cog = fogaskerék
Red = vörös
Green = zöld
Blue = kék
QTY = mennyiség
2.2 ábra. SQL visszanyerésre példa
/a/ Interaktiv meghivás:
______
SELECT S.CITY Eredmény: CITY
FROM S ______
WHERE S.SNO = 'S4' London
/b/ Meghivás egy alkalmazási programból /PL/I/:
______
EXEC SQL SELECT S.CITY INTO :SC Eredmény: SC
FROM S ______
WHERE S.SNO = 'S4'; London
sql.doc Page: 3
Altalában az interaktiv meghivás azt jelenti, hogy a kérdéses
utasitás interaktiv terminálról hajtodik végre és /vissza-
nyerés esetén / az eredmény terminálon jelenik meg. Egy
alkalmazási programból meghivás azt jelenti, hogy az utasitás
a program végrehajtási folyamatának részeként hajtódik végre
és /visszanyerés esetén/ az eredmény a programon belüli in-
put területre töltödik /fetch/ /":SC" a 2.2/b/ ábrában/.
Megjegyzés: a 2.2 ábrában egy alkalmazási programból az SQL
meghivására bemutatott szintaxis tipus nem az egyetlen lehet-
séges tipus. Lásd a 3. fejezet.
Egy további megjegyzés: Az olvasót majd figyelmeztetni
fogjuk, hogy minösitett oszlop neveket használtunk /S.SNO,
S.CITY/ a 2.2 ábrában. Az SQL tulajdonképpen lehetövé teszi,
hogy a minösitök kimaradhassanak sok összefüggésböl /ez föleg
a SELECT és a WHERE klauzulákra érvényes/ feltéve, hogy az ilyen
kihagyásokból semmilyen félreérthetöség nem származhat. Igy
például a 2.2 ábra két SELECT klauzulája mindkét esetben lerö-
vidithetö lehetett volna egyszerüen a "SELECT CITY" klauzulára.
Ebben a könyvben, világos megfogalmazási és szabatos kifeje-
zési okok miatt, általában minösitett neveket fogunk használni,
még akkor is, ha ezekre szigoruan véve nincs szükség - kivéve
természetesen az olyan szöveg összefüggéseket, ahol ezek tiltva
vannak. Egy olyan szöveg összefüggésre példa, melyben a minö-
sitett nevek tiltva vannak, egy UPDATE utasitásban egy SET
klauzula értékadás baloldala. Lásd a 2.3 alfejezetet.
2.2 ADAT DEFINICIO
A 2.1 ábra, a szállitók és alkatrészek adatbázisa, természe-
tesen ezt az adatbázist ugy reprezentálja, ahogyan valamilyen
adott idöpontban megjelenik. A megfelelö adatbázis definició,
vagy séma/*/, a 2.3 ábrában látható. Az AUTHORIZATION TED klauzula
azt adja meg, hogy a TED felhasználó ennek a sémának a létre-
hozója; a három CREATE TABLE müvelet három üres táblát defini-
ál a megadott nevekkel és a megadott , megnevezett oszlopokkal.
Az S táblán belül az SNO oszlop NOT NULL-ként és UNIQUE-ként
van definiálva; hasonlóan a P táblában lévö PNO oszlophoz és
az SP táblában a /SNO,PNO/ oszlopok kombinációjához. Az ada-
tok ezt követöen ezekbe a táblákba az SQL INSERT utasitással,
melyet a következö alfejezetben tárgyalunk, vihetök be.
___________________
* Pontosabban megfogalmazva egy séma az adatbázisnak azt a
részét definiálja, amely valamilyen specifikus felhasználó
tulajdonában van. A komplett adatbázis definició általában
több sémából fog állni, nem csak egyböl.
___________________
sql.doc Page: 4
2.3 ábra. Példa séma definiálására
CREATE SCHEMA AUTHORIZATION TED
CREATE TABLE S ( SNO CHAR(5) NOT NULL,
SNAME CHAR(20),
STATUS DECIMAL(3),
CITY CHAR(15),
UNIQUE ( SNO ))
CREATE TABLE P ( PNO CHAR(6) NOT NULL,
PNAME CHAR(20),
COLOR CHAR(6),
WEIGHT DECIMAL(3),
CITY CHAR(15),
UNIQUE ( PNO ))
CREATE TABLE SP ( SNO CHAR(5) NOT NULL,
PNO CHAR(6) NOT NULL,
QTY DECIMAL(5),
UNIQUE (SNO, PNO ))
Megjegyzés: Ezt a sémát alap sémaként fogjuk használni a
példáink nagyrészéhez a jelen könyvben mindenhol.
Kétfajta tábla definiálható egy SQL sémában:
alap táblák és nézet táblák /melyeket egyszerüen nézeteknek
nevezünk/. A 2.3 ábra táblái közül mindegyik alap tábla. Egy
alap tábla "valós" tábla - vagyis olyan tábla, amely fizikailag
létezik, abban az értelemben, hogy léteznek fizikailag tárolt
rekordok és esetleg fizikai elérési utak, mint például indexek,
a tárolt fájlok közül egyben vagy több-ben, melyek közvetlen tá-
mogatják ezt a táblát a tárolóban. Ezzel ellentétben egy nézet
"virtuális" tábla, vagyis olyan tábla, amely nem létezik
fizikai tárolóban, de a felhasználó számára ugy látszik, mint-
ha létezne. A nézetek egy vagy több alapul szolgáló alap táb-
la segitségével /kifejezéseivel/ vannak definiálva, a 2.5
alfejezetben elmagyarázására kerülö módon.
Megjegyzés: A jelen szakasz leirását nem szabad ugy értel-
mezni, hogy ez azt jelentené, hogy egy alap tábla fizikailag
táblaként van tárolva - vagyis fizikailag egymás mellett tárolt
rekordok készleteként ugy, hogy minden egyes rekord egyszerüen
az alap tábla egy sorának közvetlen másolatát tartalmazza. Az
alap tábla legjobban ugy tekinthetö, mint tárolt adatok vala-
milyen készletének absztrakciója - olyan absztrakció, melyben
számos tárolási szint részlet /ilyen például a fizikai adat
hely, fizikai rendezés, tárolt érték kódolások, fizikai elérési
utak, stb./ van elrejtve. Igy tehát általában sok különbség
van egy alap tábla és ennek tároló reprezentálása között. A lé-
nyeg azonban az, hogy a felhasználók az alaptáblákra mindig
ugy gondolhatnak, hogy ezek "fizikailag léteznek" , ugyanakkor
nem kell önmaguknak foglalkozni azzal, hogy ezek a táblák hogyan
vannak ténylegesen reprezentálva a tárolóban. Másrészröl azonban
a nézetek ebben az értelemben "fizikailag nem léteznek"; a
nézetek egyszerüen az alap táblákban lévö adatok másféle
"megtekintési" módjai. A nézeteket semmilyen saját külön, meg-
különböztethetö, fizikailag tárolt adatuk nem reprezentálja.
sql.doc Page: 5
2.3 ADAT MANIPULALAS
Négy alapvetö SQL adat manipulálási müvelet létezik: SELECT,
INSERT, UPDATE, és DELETE. Már megadtunk egy példát a SELECT-re
/két verzió/ a 2.2 ábrában. A 2.4 ábra példákat ad meg a másik
három müveletre - az ugynevezett aktualizálási müveletekre.
megjegyzés: Az "aktualizálás" /update/ kifejezésnek sajnos két
jelentése van az SQL-ben: generikusan használják egy osztályként
az INSERT, UPDATE és DELETE három müveletre utaláshoz és
specifikusan is használják az UPDATE müveletre utaláshoz.
Ebben a könyvben különbséget fogunk tenni a kétféle jelentés
között ugy, hogy mindig kisbetüt használunk, amikor a gene-
rikus jelentéshez szánjuk és nagybetüt, amikor a specifikus
jelentéshez szánjuk.
2.4 ábra. Update példák
INSERT Eredmény: A megadott sor hozzá-
INTO SP (SNO, PNO, QTY) adódik az SP táblához
VALUES ('S5','P1',1000)
UPDATE S Eredmény: A STATUS megkettözö-
SET STATUS = 2 * S.STATUS dik londoni szallitok
WHERE S.CITY = 'London' esetén /vagyis S1 és
S4/
DELETE Eredmény: Sorok törlése P táb-
FROM P lából P2-es, P3-as
WHERE P.WEIGHT > 15 és P6-os alkatrészek
esetén
Megjegyezzük, hogy a 2.4 ábra UPDATE és DELETE müveletei
közül mindkettö több soron fejti ki a hatását, nem csak egyet-
len soron. Altalában ugyanez igaz INSERT müveletekre /jól-
lehet a 2.4 ábra INSERT müvelete ténylegesen egysoros müvelet/,
és SELECT müveletekre is. Azonban SELECT esetében a szabvá-
nyos SQL nem engedi meg, hogy egy többsoros SELECT müvelet
közvetlenül végrehajtódjon /vagyis saját jogán, külön utasi-
tásként/; ehelyett definiálni kell egy plusz sort, mely "ér-
vényességi köreként" /scope/ tartalmazza ezt a SELECT müve-
letet és ezután egyenként kell elérni a SELECT /kiválasz-
tott/ sorokat ennek a corsornak a segitségével. Azonban ok-
tatási okok miatt a cursorok tárgyalását a 2.4 alfejezetig
elhalasztjuk és egyenlöre feltételezzük, hogy többsoros
SELECT-ek valóban közvetlenül végrehajthatók. /Megjegyezzük,
hogy egysoros SELECT-ek végrehajthatók közvetlenül a 2.2
ábrában láthatóak szerint./
A SELECT müveletnek "SELECT-FROM-WHERE" általános alakja
van a 2.5 ábrában bemutatottak szerint. Megjegyzés: Ebben az
ábrában a "<>" szimbólum "nem egyenlöt" jelent.
Figyelje meg, hogy a SELECT eredménye egy másik tábla
/olyan tábla, amely egy meglévö táblából származik, nem pedig
az adatbázisban tárolt tábla/. Többféle szempont merül fel
ezzel az egyszerü példával kapcsolatban:
sql.doc Page: 6
2.5 ábra. Az alap "SELECT-FROM-WHERE"
______ ______
SELECT DISTINCT P.COLOR, P.CITY Eredmény: COLOR CITY
FROM P ______ ______
WHERE P.WEIGHT > 10 Red London
AND P.CITY <> 'Paris' ---Red-----London---
ORDER BY P.COLOR DESC ---Red-----London---
Blue Rome
/A 2. és 3.sor ki-
marad, ha a felhasz-
náló DISTINCT-et
ir elö./
- Az eredmény tábla rendezve van az ORDER BY klauzula
szerint. Ha DESC /descending, csökkenö/ nincs megadva,
ASC /ascending, növekvö/ rendezés a feltételezés.
- Ha a teljes ORDER BY klauzula kimaradt, az eredmény imp-
lementálás - definiálta sorrendben jelenik meg.
- Ha a teljes WHERE klauzula kimaradt, a FROM tábla minden
sora minösit /qualify/.
- Ha DISTINCT nincs megadva, az eredmény kettös sorokat
tartalmazhat, /a példában négy sor fog vissztérni,
ha a DISTINCT nincs megadva, kettö ha meg van adva./
Összekapcsolás
Egy jellemzö, amely csaknem minden másnál nagyobb mérték-
ben megkülönbözteti a relációs rendszereket a nem relációs
rendszerektöl, a relációs összekapcsolási /join/ operátor
rendelkezésre állása. Altalában fogalmazva ez azt jelenti,
hogy lehetöség van több táblából adatok kiválasztására
egyetlen SELECT müvelet segitségével. Erre egy példát
adunk meg a 2.6 ábrában. Az "összekapcsolás" kifejezés abból
a tényböl származik, hogy /a példában/ az SP és S táblák
fogalmilag /konceptuálisan/ össze vannak kapcsolva a közös
SNO oszlopuknál. Figyelje meg, hogy ebben a speciális eset-
ben a WHERE klauzulában az S.SNO és SP.SNO oszlopokra hivat-
kozásokat minösiteni kell a félreérthetöség elkerülésére.
2.6 ábra. Összekapcsolást tartalmazó példa
___ ___ ___ ___ ______ ___ ______
SP SNO PNO ... S SNO ... CITY PNO CITY
___ ___ ___ ___ ______ ___ ______
S1 P1 ... S1 London P1 London
S1 P2 ... PLUS S2 Paris ==> P2 London
. . . ---- . . . .
. . . . . . .
. . . . . . .
S2 P1 ... P1 Paris
. . . . .
SELECT SP.PNO,S.CITY
FROM SP, S
WHERE SP.SNO = S.SNO
sql.doc Page: 7
Feladat: Minden leszállitott alkatrészhez keresse vissza
az alkatrész számot és az összes olyan városnak a nevét,
melyben van olyan szállitó, aki az alkatrészt szállitja.
Beépitett függvények
Az SQL speciális beépitett függvény halmazt biztosit: COUNT,
SUM, AVG, MAX, MIN és COUNT(*) /A "*" az érintett tábla egy
teljes sorára utal./. A 2.7 ábrában adunk meg példákat. Az
utólsó példa a GROUP BY klauzulát is mutatja, melyet egy táb-
lának /konceptuálisan/ csoportokra osztására használunk ugy,
hogy egy függvény, például SUM, alkalmazható legyen minden
egyes csoportra. /Egyébként figyelje meg, hogy az elsö három
példa mindegyike egysoros SELECT./
2.7 ábra. Példák SQL beépitett függvényekre
Eredmény:
Szállitók száma: SELECT COUNT (*) 5
FROM S
Az alkatrészeket SELECT COUNT (DISTINCT SP.SNO) 4
szállitó szállitók FROM SP
száma
P2 teljes mennyi- SELECT SUM (SP.QTY) 1000
sége: FROM SP
WHERE SP.PNO = 'P2'
___ ____
PNO QTY
___ ____
Az egyes leszálli- SELECT PNO, SUM (SP.QTY) P1 600
tott alkatrészekhez FROM SP P2 1000
tartozó alkatrész GROUP BY SP.PNO P3 400
szám és teljes meny- P4 500
nyiség P5 500
P6 100
2.4 CURSOR MÜVELETEK
Mint ahogyan a 2.3 alfejezetben már emlitettük, többsoros SELECT müvele-
tek közvetlenül nem hajthatók végre a szabványos SQL-ben. A dolgok ilyen
állásának az az oka, hogy a szabvány elsödlegesen olyan programozási
nyelvekkel kapcsolatban foglalkozik az SQL használatával, mint például
a PL/I és COBOL, és az ilyen nyelvek általában nincsenek jól "felszerel-
ve" azzal, hogy halmazokkal /melyek több sorból állnak/ egyedülálló ope-
randusokként foglalkozzanak. Tehát az amire szükség van, az egy mecha-
nizmus egy ilyen halmazon /készleten/ történö lépésenkénti keresztül ha-
ladáshoz és a sorok egyenkénti kiválasztására; a cursorok ilyen mecha-
nizmust biztositanak. A cursor egy SQL tárgy /objektum/, amely egy spe-
cifikus SELECT müvelettel van kapcsolatba hozva /megfelelö deklaráción
keresztül/./*/ Ahhoz hogy hozzáférjen azokhoz a sorokhoz, amelyek ezen
SELECT-nek megfelelnek, a felhasználónak a következöket kell tennie:
/a/ OPEN /meg kell nyitnia/ a cursort, mely /fogalmilag/
a SELECT végrehajtását eredményezi és ennek következté-
ben azonositja a megfelelö sorok halmazát;
sql.doc Page: 8
/b/ Ismétlödöen használnia kell a FETCH-t a megnyitott cur-
soron, mely /minden egyes végrehajtásá 242e42c nál/ tovább lépteti
a cursort a következö sorra a SELECT-en /kiválasztott/
halmazban és visszanyeri ezt a sort; és végül
/c/ CLOSE /le kell zárnia/ a cursort, amikor az összes szük-
séges sor feldolgozása már megtörtént.
___________________
* Pontosan megfogalmazva egy specifikus "lekérdezési kife-
jezéssel". Lásd a 6.2 és 9.1 alfejezeteket.
___________________
2.8 ábra. Példa cursor használatára
EXEC SQL DECLARE C CURSOR FOR
SELECT SP.SNO, SP.QTY
FROM SP
WHERE SP.PNO = 'P2' ;
DECLARE X CHAR (5) ;
DECLARE Y FIXED DEC (5) ;
DECLARE Z FIXED DEC (3) ;
EXEC SQL OPEN C ;
DO WHILE more rows to come ;
EXEC SQL FETCH C INTO :X, :Y ;
IF a row was found THEN
DO :
process X and Y ;
EXEC SQL UPDATE SP
SET QTY + :Z
WHERE CURRENT OF C ;
END ;
END;
EXEC SQL CLOSE C;
Az UPDATE és DELETE speciális alakjai is biztositva
vannak annak a sornak az aktualizálására vagy törlésére,
amelyben a cursor éppen elhelyezkedik. Erre a 2.8 ábrában
adunk meg egy példát /vázlatosan, sok fontos részlet kima-
radt/.
Megjegyzés: mint ahogyan a 2.1 alfejezetben már meg-
emlitettük, az SQL szabvány számos különbözö módszert enged
meg egy alkalmazási programból SQL müvelet meghivására.
A 2.9 ábra bemutatja a legáltalánosabb módszert, mely SQL
utasitásoknak közvetlenül a program forrás szövegbe történö
beágyazása. A beágyazott SQL utasitásokat EXEC SQL elötaggal kell
ellátni azért, hogy könnyen felismerhetö legyen. Ezek az uta-
sitások tartalmazhatnak hivatkozásokat /utalásokat/ Host nyelvü
változókra; az ilyen referenciák elé kettöspontot /:/ kell
elhelyezni, ismét felismerési célokra. A további részleteket
lásd a 3.2 alfejezetben vagy a 10. fejezetben.
sql.doc Page: 9
2.9 ábra. CREATE VIEW /példa/
CREATE VIEW LS (SNO, SNAME, STATUS)
AS SELECT S.SNO, S.SNAME, S.STATUS
FROM S
WHERE S.CITY = 'London'
2.5 NÉZETEK
Emlékezzünk vissza a 2.2 alfejezetböl arra, hogy egy nézet
/vagy "viewed table" /nézet tábla / / virtuális tábla -
vagyis olyan tábla, amely valójában "nem létezik", de a
felhasználó számára ugy látszik, mintha létezne. A nézeteket
közvetlenül nem támogatják a saját tárolt adataik; ehelyett
ezek definiciói, más táblák /alap táblák és/vagy nézetek/ ki-
fejezéseivel vannak megadva az adatbázis definició részeként.
Egy nézet definicióra a 2.9-es ábrában adunk meg példát.
Az LS /"London suppliers" /londoni szállitók// nézet
egyfajta ablakként müködik, melyen keresztül a felhasználó
az S alap táblában lévö azon sorok SNO, SNAME és STATUS érté-
keit /csak ezeket/ láthatja, melyekhez a London CITY érték
/csak ez az érték/ tartozik. Az ezt a nézetet definiáló
SELECT nem kerül végrehajtásra a nézet létrehozásakor, hanem
erre egyszerüen csak emlékezik a rendszer valamilyen módon.
Azonban a felhasználó számára ugy tünik, mintha ténylegesen
létezne LS nevü tábla az adatbázisban. A 2.10-es ábra az ehhez
a táblázathoz kiadott visszanyerésre mutat példát.
2.10 ábra. Egy nézethez kiadott visszanyerés /példa/
---
SELECT LS. SNO Eredmény: SNO
FROM LS ---
WHERE LS.STATUS < 50 S1
S4
Egy nézethez kiadott müveletek kezelése /konceptuálisan/
ugy történik, hogy helyettesitik a nézetre hivatkozásokat a
nézet definiciójával /vagyis azzal a SELECT müvelettel, amelyre
a rendszer emlékezett/. A rendszer igy logikailag "merges"
/összefésüli/ a 2.9 ábra SELECT-jét a 2.10 ábra SELECT-jével
azért, hogy megkapja a 2.10-es ábra módositott SELECT-jét.
2.11 ábra. Összefésült SELECT utasitás
---
SELECT S.SNO Eredmény: SNO
FROM S ---
WHERE S.STATUS < 50 S1
AND S.CITY = 'London' S4
A módositott SELECT most a normál módon hajtható végre.
Más szavakkal a nézeten az eredeti SELECT át van alakitva
egy ekvivalens SELECT-té az alapul szolgáló alap táblán. Az
aktualizálási müveletek kezelése hasonló módon történik;
azonban a nézeteken az aktualizálási müveletekre számos kü-
lönbözö megszigoritás érvényes, melyeknek a részletei a jelen
sql.doc Page: 10
fejezet vizsgálati körén tulnyulnak. Kissé leegyszerüsitve a
dolgokat, a szabványos SQL csak akkor engedi meg egy nézet ak-
tualizálását, ha ez egyetlen alapul szolgáló alap tábla egy-
szerü sor és oszlop részhalmazát reprezentálja /például nem
egy összekapcsolás/. A további részleteket lásd a 8. fejezet-
ben.
A nézetekre két további példa /mindkettö nem aktuali-
zálható/ látható a 2.12-es ábrában.
2.12 ábra. További nézet példák
CREATE VIEW PQ (PNO, SUMQTY)
AS SELECT SP.PNO, SUM (SP.QTY)
FROM SP
GROUP BY SP.PNO
CREATE VIEW CITY_PAIRS (SCITY, PCITY)
AS SELECT S.CITY, P.CITY
FROM S, SP, P
WHERE S.SNO = SP.SNO AND SP.PNO = P.PNO
2.6 ADAT VEZÉRLÉS
Mint ahogyan a 2.1-es alfejezetben is megemlitettük, az SQL
lehetöségeket biztosit adat vezérléshez valamint adat defi-
niáláshoz és adat manipuláláshoz. Az adat vezérlö lehetö-
ségek három kategóriába csoportosithatók: /a/ hiba elháritás
és konkurencia, /b/ adat védelem és /c/ integritás.
Hiba elháritás és konkurencia
A szabványos SQL támogatja a tranzakció fogalmat. A tranzakció
kezelést valamint a hiba elháritás és konkurencia ezzel kap-
csolatos fogalmait tartalmazó oktatási anyag a szerzönek
az An Introduction to Database Systems: /az adatbázis rend-
szerek bevezetése/: Volume 1 /1-es kötet/ /4. kiadás, Addison
Wesley, 1985./ könyvében található. A tranzakció kezeléséhez
az SQL jellemzök részletes tárgyalását a 3. fejezetre halaszt-
juk; az alábbiakban csak egy nagyon rövid, vázlatos áttekintést
adunk meg.
- Egy tranzakció egy olyan müveletsorozat, amely garantáltan
atomi /atomic/ a hibaelháritás és a konkurrencia szempontjá-
ból. Minden tranzakció vagy COMMIT /normál befejezés/ vagy
ROLLBACK /rendellenes befejezés/ végrehajtásával fejezödik be.
- Egy adott T1 tranzakció által végrehajtott adatbázis aktu-
alizálások semmilyen ettöl eltérö T2 tranzakció számára nem
láthatók mindaddig, amig a T1 végre nem hajt egy COMMIT-ot.
A COMMIT eredményeként a tranzakció végrehajtotta összes
aktualizálás más tranzakciók számára láthatóvá válik; az i-
lyen aktualizálások számára garantálva van, hogy sohasem tör-
lödnek. Ha ehelyett a tranzakció ROLLBACK-ot hajt végre, a
tanzakció végrehajtotta összes aktualizálás törlödik.
sql.doc Page: 11
- A konkurens /egyidejü/ tranzakciók sorozata /készlete/
interleaved párhuzamosan történö végrehajtásának sorba
rendezhetönek kell lennie abban az értelemben, hogy ugyanazt
az eredményt kell létrehoznia, mint ugyanezen tranzakciók
egyenkénti, valamilyen sorrendben történö végrehajtásának.
Adat védelem
SQL-ben az adatvédelemnek /security/ két aspektusa van, a né-
zet mechanizmus és a GRANT opció. Elöször, nézetek használha-
tók érzékeny adatoknak nem meghatalmazott felhasználóktól való
elrejtésére. Az ilyen módon használható nézetekre néhány példa
a 2.13-as ábrában látható. Az elsö csak a vörös alkatrészek-
hez tartozó információkat fedi fel; a második csak azokhoz az
alkatrészekhez tartozó információkat fedi fel /mutatja meg/,
melyeket a nézet felhasználója adott meg; a harmadik elrejti
a szállitó állapot információkat; és a negyedik megadja az
alkatrészenkénti étlagos mennyiséget, de nem adja meg az egyes
mennyiségeket. Megjegyzés: A "SELECT*" egy olyan SELECT rövi-
ditése, ami a tábla összes oszlopát megnevezi - vagyis egy
olyan SELECT-é, mely a teljes sorhoz hozzáfér /a WHERE klauzu-
lát kielégitö minden sorhoz./
2.13 ábra. Nézetek használata adatok elrejtésére /példák/
CREATE VIEW RED_PARTS AS
SELECT* FROM P WHERE P.COLOR = 'Red'
CREATE VIEW MY_PARTS AS
SELECT* FROM P WHERE P.PNO IN
(SELECT SP.PNO FROM SP
WHERE SP.SNO = USER)
CREATE VIEW STATUS_HIDDEN AS
SELECT S.SNO, S.SNAME, S.CITY FROM S
CREATE VIEW AVG_QTYS (PNO, AVGQTY) AS
SELECT SP.PNO, AVG (SP.QTY) FROM SP GROUP BY SP.PNO
A második a GRANT müvelet. Ahhoz, hogy egyáltalán bármi-
lyen SQL utasitás végrehajtásra kerülhessen, a felhasználónak
megfelelö privilégiummal kell rendelkeznie az érintett müvelet
és operandus kombinációjához /egyébként az utasitás figyel-
men kivül fog maradni/. A lehetséges privilégiumok a SELECT,
UPDATE, DELETE és INSERT, melyek minden egyes esetben a kér-
déses táblán /alap tábla vagy nézet/ a jelzett müveletet végre-
hajtásának privilégiumát reprezentálják. UPDATE esetében a
privilégium specifikus oszlopokra korlátozható. A privilégi-
umok hozzárendelése a következöképpen történik:
- Egy felhasználó, aki egy táblát létrehoz, automatikusan
megkapja ezen a táblán az összes alkalmazható privilégi-
umot "with the grant option" /a grant opcióval/.
- Bármelyik felhasználó, akinek "with the grant option"
/a grant opcióval/ egy privilégium van a birtokában,
átadhatja azt a privilégiumot más felhasználónak, ezen-
kivül opcionálisan tovább adhatja a grant opciót más fel-
használónak /ugy hogy most ez a felhasználó haladhat
tovább a privilégiumnak egy harmadik fél számára tör-
sql.doc Page: 12
ténö átadásához, és igy tovább/.
- A privilégiumok megadása a GRANT opció segitségével
történik, mely az adatbázis definició részeként van
megadva /vagyis a sémában/.
A GRANT-ra néhány példa a 2.14-es ábrában látható.
2.14 ábra. GRANT példák
GRANT INSERT, DELETE, UPDATE ON SP TO JOE
GRANT SELECT ON SP TO ALICE WITH GRANT OPTION
GRANT UPDATE (STATUS) ON S TO JUDY
GRANT DELETE ON SP TO BONNIE, CLYDE
Integritás
Az "integrity" /integritás/ kifejezés az adatbázisban az
adatok helyességére, pontosságára utal. A szabványos SQL
lehetövé teszi bizonyos adatbázis integritás követelmények
definiálását /a CREATE TABLE részeként/; minden aktualizálás,
amely bármelyik elöirt követelményt megszegné, visszautasi-
tásra kerül és az adatbázis változatlan marad. A lehetsé-
ges követelmények a következök:
- NOT NULL: bármelyik oszlophoz elöirható. Egy ilyen osz-
lopba null érték bevitelére irányuló minden kisérlet visz-
szautasitásra kerül. /Lásd a 3. alfejezetben a null érték
tárgyalását./
- UNIQUE: bármelyik oszlophoz vagy oszlopok kombinációjá-
hoz elöirható, feltéve, hogy a NOT NULL ugyancsak elö
van irva minden ilyen oszlophoz. Visszautasitásra fog
kerölni minden kisérlet, melynek során az elöirt oszlop-
ban vagy oszlop kombinációban valamilyen meglévö sorral
azonos értékü sort próbálnak bevinni.
A teljesség érdekében két további integritás jellemzöt
is meg kell emliteni: adat tipus ellenörzés és "the check
opcion" /a check opció/. Elöször, az SQL vissza fog utasitani
minden kisérletet, mely az adat tipus specifikációk elöirá-
sait megszegné - vagyis minden olyan kisérletet, melynek so-
rán karakter füzér értéket helyeznénk be DECIMAL-ként defi-
niált oszlopba. Másodszor az SQL a WITH CHECK OPTION klau-
zulát is támogatja a CREATE VIEW-ben. A részleteket lásd a
8. fejezetben.
2.7 NÉHANY ELTÉRÉS DB2-TÖL
A DB2-t vagy valamilyen más meglévö SQL implementációt ismerö
olvasók számos különbséget fognak észrevenni a jelen fejezet-
ben leirtak szerinti SQL és a jelenleg implementált SQL között.
Az alábbiakban vázlatosan megadunk ezen eltérések közül néhá-
nyat. Megjegyzés: az alábbiakban a DB2 jellemzöiként azonosi-
tott /rövidség kedvéért/ jellemzök nagy részének megvan a
közvetlen megfelelöje sok más SQL termékben.
sql.doc Page: 13
1. DB2-ben az adat manipulálási müveletek, a CREAT TABLE,
a CREAT VIEW és a GRANT müveletek /és számos más olyan müvelet
is, ami a szabványos SQL-ben egyáltalán nem jelenik meg/ min-
degyike mind interaktiv módon, mind pedig egy programból meg-
hivható. Szabványos SQL-ben ezze ellentétben:
/a/ Csak adat manipulálási müveletek hivhatók meg mind inter-
aktiv módon, mind pedig egy programból;
/b/ CREATE TABLE, CREATE VIEW és GRANT müveletek csak egy
"schema" /séma/ szöveg összefüggésében /context/ hivha-
tók meg - vagyis az adatbázis definició részeként; és
miközben a szabvány nem irja elö, hogy a rendszerbe ho-
gyan viszik be az adatbázis definiciót /lásd az alábbi
következö pontot/ ugy látszik, mintha az adatbázis defi-
niáló interfész valami olyan volna, amely különbözik
mind egy hagyományos interaktiv interfésztöl, mind pe-
dig egy hagyományos programozási interfésztöl. /*/
____________________
* A szabványban a definiáló és manipulativ müveletek szétvá-
lasztása szándékosan történt: lehetövé tette, hogy a bizottság
elkerüljön bizonyos olyan problémákat, amelyek abból a lehetö-
ségböl származnak, hogy ugyanahhoz a táblázathoz a kétfajta
müveletet egymással "keverve" hajtsák végre.
2. Az elözö pontból továbbhaladva: egy séma fogalma mint
ilyen egyáltalán nem létezik DB2-ben. A DB2 SQL-t mindig arra
szánták, hogy rendkivül dinamikus legyen - minden müvelet ren-
delkezésre áll minden összefüggésben /legalábbis minden olyan
összefüggésben, amelyben értelme van/ és ebbö következik,
hogy lehetöség van például arra, hogy bármikor interaktiv mó-
don uj alap táblát hozzanak létre. Ezzel ellentétben a séma
fogalom meglehetösen statikusnak látszik - jóllehet /mint
ahogy fent is jeleztük/ az a mechanizmus, amellyel a sémát
a rendszer számára ismertté teszik /vagyis a "schema language
processor" /séma nyelv processzor/ nincs elöirva a szabványban
és ebböl következik, hogy egy dinamikus, DB2-szerü módszer
lehetösége nincs teljesen kizárva.
3. A DB2 támogat néhány további definiciós müveletet
- ALTER TABLE, DROP TABLE és DROP VIEW /valamint számos na-
gyobb mértékben fizikailag orientált müveletet, ilyen pél-
dául a CREATE/DROP INDEX és CREATE/DROP TABLESPACE/.
4. A DB2 lehetövé teszi egy többsoros SELECT közvetlen
interaktiv végrehajtását cursor használata nélkül.
5. Egy DB2 cursor deklaráláshoz szükség van FOR UPDATE
klauzulára, ha egy UPDATE ... WHERE CURRENT müvelet fog vég-
rehajtódni ezen cursor használatával.
6. DB2-ben a konkurencia /egyidejü/ vezérlés zároláson
/locking/ alapul. Rendszerint a tesztelés, beállitás és zá-
rolások feloldási müveletei teljesen implicit müveletek, de
a DB2 támogat egy explicit LOCK TABLE müveletet.
sql.doc Page: 14
7. DB2-ben az interleaved végrehajtásokra nincs garan-
tálva, hogy azok sorba rendezhetöek, kivéve ha minden tranz-
akcióhoz a BIND parancsban elö van irva az RR /"repeatable
read" /ismételhetö olvasás/ /opció./ Megjegyzés: a BIND egy
parancs a DB2 SQL compilerhez nem pedig DB2 SQL utasitás.
Nincs megadva az alkalmazási programban.
8. A DB2 támogat egy REVOKE müveletet egy elözöleg meg-
adott privilégium eltávolitására /megszüntetésére/. A DB2
ezenkivül nagyszámu további privilégiumot is támogat, a szab-
ványos SQL által támogatott privilégiumokon tul és azok felett.
9. A DB2 támogatja a nem null alapértékeket /a CREATE
TABLE-ben és ALTER TABLE-ben a NOT NULL WITH DEFAULT megadásán
keresztül/. Ezek az értékek kerülnek felhasználásra nulla érté-
kek helyett hiányzó /nem megadott/ oszlopok esetén az INSERT
müveletekben. A definició szerint az alapértékek a következök:
nulla /numerikus oszlopokhoz/, space-k /fix hosszuságú karak-
ter füzér oszlopokhoz/ és az üres karakter füzér /változó
hosszuságú karakter füzér oszlopokhoz/. Megjegyezzük, hogy
az SQL szabvány nem támogat változó hosszuságú karakter füzér
adat tipust.
10. DB2-ben az egyértéküség a CREATE INDEX-ben van elö-
irva, nem pedig a CREATE TABLE-n. Nincs olyan követelmény, hogy
NOT NULL-nak érvényesnek kell lennie az egyértéküségi speci-
fikációban emlitett minden oszlopra.
11. A DB2 tartalmazza a katalógusnak nevezett rendszer
táblák halmazát, mely /lényegében/ az adatbázis definiciót
vagy sémát tartalmazza. A szokásos SQL SELECT utasitások hasz-
nálhatók a katalógus lekérdezésére.
Megjegyzések:
A következö véleményünket adjuk meg a tárgyalt eltéré-
sekre vonatkozóan /mindig figyelembe véve azt a feltéte-
lezett tényt, hogy a szabvány fö célja a program hordoz-
hatóság/. A megjegyzéseket a fenti 1-11-es szakaszok
szerint számoztuk.
1. Kivánatosabb a DB2 megközelités. Kivánatos az a ké-
pesség, hogy minden müvelet végrehajtásra kerüljön minden
olyan szöveg összefüggésben, melynek értelme van /jólle-
het természetesen esetleg nem nagyon fontos a program
hordozhatósága szempontjából./
2. Ugyanaz, mint 1.
3. Kivánatos az ALTER TABLE, DROP TABLE /stb./ támoga-
tása.
4. Kivánatos cursor használata nélküli interaktiv
többsoros SELECT végrehajtásának képessége.
sql.doc Page: 15
5. A FOR UPDATE klauzula egy hiba a DB2-ben; az X3H2-
nek joga volt arra, hogy ezt eltörölje /de lásd a 6.3 fe-
jezetben a "pozicionált UPDATE"-re tett megjegyzést./
6. Nincs megjegyzés.
7. Kissé szerencsétlen dolog, hogy a DB2 "RR" opció
a programon kivül van elöirva, mivel ez hatással lehet a
program logikára /nem lényeges pont/. Egyébként nincs meg-
jegyzés.
8. Kivánatos a REVOKE támogatása.
9. Kivánatos az alapértékek /lehetöleg felhasználó de-
finiálta/ támogatása. Lásd a 11. fejezetet.
10. A CREATE INDEX-ben az UNIQUE megadása egy további
DB2 hiba; az egyértéküség logikai tulajdonság és CREATE
TABLE-hez tartozik, ez az amit a szabvány megkövetel.
/ A CREATE TABLE-n egy PRIMARY KEY klauzula megkövetelése
még jobb lenne. Lásd a 11. fejezetet./
11. Miközben nehéz meglátni, hogy az X3H2 hogyan irhatna
elö egy szabványos katalógus struktúrát, a lényeg az, hogy
általánositott alkalmazási programoknak legalábbis gyakran
szükségük van katalógus információk, az általánositott termé-
szetük miatti pontos, olvasására és értelmezésére. /Az ilyen
általánositott alkalmazásra példa az IBM saját lekérdezést
kezelö lehetösége /Query Management Facility, QMF/, amely egy
ad hoc lekérdezö és jelentést iró "frontend" alrendszer mind
DB2-höz, mind SQL /DS-hez./ Egy szabványos katalógus struk-
tura hiánya valószinüleg súlyos korlátozásokat szab meg az
ilyen alkalmazások hordozhatóságára.
Megjegyzések vége.
sql.doc Page: 16
3
-------- ----- ------ ----- ----- -----------------
Elözetes ismeretek
3.1 ALAP ADAT TARGYAK
1. Az SQL szabvány egy nem definiált fogalommal kezdödik,
a környezet fogalmával /vagyis az implementációnak kell
elöirnia pontosan azt, hogy egy adott implementációnak mi
az, ami egy környezetet alkot/. Minden környezet ugy van
definiálva, hogy csak egyetlen adatbázist tartalmaz /vagyis
minden alkalmazási program csak egyetlen adatbázison müködik/.
Egy adott környezethez az adatbázis ugy van definiálva, hogy
ez az ebben a környezetben lévö összes séma által definiált
minden adatot magában foglal. Viszont minden egyes séma alap
tábla definiciók halmazából, nézet definiciók halmazából és
privilégium definiciók /GRANT müveletek/ halmazából áll. A
privilégiumokat a 3.3-as alfejezetben tárgyaljuk; az alap
táblákat és nézeteket az alábbiakban irjuk le.
2. Az adatbázisban lévö adatokat a felhasználó megneve-
zett táblák gyüjteményeként észleli, melyek közül nincs két
olyan, amelynek azonos neve lenne. Minden megnevezett tábla
vagy alap tábla, vagy nézet tábla /röviditve nézet/. Az alap
tábla "valós" tábla, - vagyis megnevezett, autonóm tábla
/ahol "automóm" azt jelenti, hogy "semmilyen más táblák
kifejezéseivel nincs definiálva"/. A nézet "virtuális" tábla
- vagyis megnevezett, származtatott tábla /ahol "származta-
tott" azt jelenti, hogy "nem autonóm"/. Az alap táblákat és
nézeteket CREATE TABLE illetve CREATE VIEW müveletek hozzák
létre; a szabvány semmilyen eszközt nem ir elö megsemmi-
sitésükre. Megjegyzés: egy lekérdezés kifejezés /lásd késöbb
a 9. fejezetben/ kiértékelésének eredménye ugyancsak egy
származtatott tábla /nézethez hasonló/, de nincs elnevezve.
Az ilyen tábla megszünik létezni azon utasitás végre-
hajtásának befejezésekor, amelyik ennek a lekérdezés
kifejezésének a kiértékelését eredményezi.
3. Egy tábla az oszlop fejrészének sorából, valamint nulla
vagy több adat érték sorból áll /általában különbözö idö pon-
tokban különbozö számu adat sorbol/. Egy adott tábla eseten:
- Az oszlop fejrész sor egy vagy több megnevezett oszlo-
pot ir le /megadva többek között egy adat tipust minden
ilyen oszlophoz/. Egy adott táblán belül nem lehet két
azonos nevü oszlop.
- Minden adat sor pontosan egyetlen értéket tartalmaz az
oszlop fejrész sorban megadott minden oszlophoz. Ezen-
kivül egy adott oszlopban minden érték azonos adattipusú,
nevezetesen az ehhez az oszlophoz az oszlop fejrész
sorban elöirt adat tipusu. Megjegyzes : Az " data row "
/adat sor/ kifejezést rendszerint egyszerüen "row"/sor/-
ra röviditjük.
sql.doc Page: 17
Megjegyzés: Itt követjük az SQL szabványt azzal, hogy
a "value" /érték/ nem minösitett kifejezést használjuk
arra utalásra, amely pontosabban skalár értéknek nevez-
hetö /vagyis egyedi szám vagy karakter füzér, lásd az
alábbi 4-es pont alatt/. A nem minösitett "value" /érték/
használattal kapcsolatban az a probléma, hogy nagyon
általános kifejezés és nagyon speciális jelentést kap,
ezért nehézzé teszi, hogy általánosabb, nem skalár
értékekröl - például egy lekérdezési kifejezés értékéröl
beszélhessünk.Ebben a könyvben rendszerint a "scalar"
/skalár/ vagy "scalar value" /skalár érték/ kifejezést
fogjuk használni annak a ténynek a hangsulyozására, hogy
a kérdéses érték skalár érték. Megjegyzés vége.
Két szempont merül fel a most tárgyalt definicióval kap-
csolatban.
- Figyelje meg, hogy nem történik emlités a sorok rendezéséröl.
Egy tábla sorait nem tekintjük rendezetteknek.
Lehetöség van, mint ahogyan a 2.3-as
alfejezetben már láttuk, arra hogy rendezést irjunk elö
azokra a sorokra, amelyek egy lekérdezésre válaszul
visszanyerésre kerülnek, de az ilyen rendezést semmivel
sem szabad többnek tekinteni, mint ami a felhasználó
kényelmét biztositja - a rendezés nem része a "table"
/tábla/ fogalmának.
- Az elsö szemponttal ellentétben egy tábla oszlopait
rendezettnek tekintjük balról jobbra haladva.Például
az S táblán /lásd a 2. fejezetben a 2.1 -es ábrát/ az
SNO oszlop az elsö oszlop, SNAME oszlop a második oszlop
és igy tovább./Valójában nagyon kevés olyan helyzet
van, melyben ez a balról jobbra rendezés jelentös es
még ezek is elkerülhetök kis alakitással /discipline/.
A gyakorlatban általában javasoljuk az ilyen elkerülését.
Adott táblázatban a sorok számát ezen táblázat kardina-
litásának nevezzük. Az oszlopok számát fokszámnak
nevezzük.
4. A skalár értékek két alapvetö tipusuak, karakter fü-
zérek/röviditve füzérek/ és számok. Megjegyzés: A specifikus
adat tipusokat a 4.fejezetben tárgyaljuk.
Ezenkivüla Host változókat és paramétereket
ugyancsak ugy tekintjük, hogy azok skalár értékeket repre-
zentálnak és ebböl következik, hogy a következö megjegyzések
az ilyen változókra és paraméterekre is vonatkoznak; lásd a
3.2-es alfejezetet.
- Egy karakter füzér egy vagy több karekterböl álló
sorozat. Bármilyen két karakter füzér egymással összehason-
litható; az ilyen összehasonlitások végrehajtása az imp-
lementáció definiálta karakter összevetési /collating/
sorrenddel összhangban történik. Ha két különbözö
hosszuságu karakter füzért kell összehasonlitani,
a rövidebbet konceptuálisan feltöltik jobboldalon
space karakterekkel azért, hogy ugyanolyan hosszuságu
legyen mint a hosszabb, mielött az összehasonlitás
sql.doc Page: 18
végrehajtásra kerülne.
- Egy szám vagy pontos vagy megközelitö szám.
- Egy pontos számnak van egy pontossága /p/ és egy
skálatényezöje /scale/ /q/, ahol p>=q>0 /és p>0/
A szám p szignifikáns számjegyböl áll és a következö-
vel egyenlö értékü
n * ( 10** (-q))
ahol n a p szignifikáns számjegy integer értéke /és
ahol xx hatványra emelést jelent; jegyezzük meg azon-
ban , hogy a szabványos SQL nem támogat exponenciális
operátort.
- Egy megközelitö számnak van egy pontossága /p/, ahol
p > 0. Az ilyen szám p szignifikáns számjegyü, elöje-
les mantisszából /m/ és egy elöjeles exponensböl /e/
áll és megközelitöleg az alábbival egyenlö értékü
m * (10** e)
Bármilyen két szám összehasonlitható egymással; az ilyen
összehasonlitások végrehajtása algebrai módon történik.
- Minden karakter füzér hozzárendelhetö karakter füzér tipusu
tárgyhoz /objektumhoz/. A forrás karakter füzért
konceptuálisan jobboldalon csonkitják vagy jobboldalon
szóköz karakterekkel feltöltik /szükség szerint/ azért,
hogy a cél tárgy hosszuságával azonos hosszuságuvá váljék,
az értékadás végrehajtása elött.
- Bármilyen szám; pontos vagy megközelitö, megadható meg-
közelitö numerikus tipusu tárgyhoz.Csak pontos szám ad-
ható meg pontos numerikus tipusu tárgyhoz. Mindkét esetben
a forrás számot konceptuálisan átalakitják a cél tárgy
pontosságára / és skálatényezöjének megfelelöen, ha szükséges/
az értékadás végrehajtása elött.
- Megjegyezzük, hogy a számok és karakter füzérek nem ha-
sonlithatók össze egymással, ugyancsak érvényes az is,
hogy szám nem adható meg karakter füzér tipus tárgyhoz, va-
lamint karakter füzér nem adható meg szám tipusu tárgyhoz.
5. A null érték /röviditve null/ egy speciális skalár
érték, amely oszlop értékként jelenhet meg egy alap táblában
vagy származtatott /derived/ táblában, de nem jelenhet meg
Host változó vagy paraméter értékként/legalábbis nem közvet-
lenül; lásd az m 5.3-as alfejezetet/. A null értéket arra szánták,
hogy azt jelentse, hogy "hiányzik az iformáció" /például
"érték ismeretlen" vagy " érték nem érvényes "/. A null rep-
rezentálását az inplementáció definiálja; azonban ennek olyan-
nak kell lennie, hogy a rendszer megkülönböztethesse a nullá-
kat minden "know" /ismert/ /vagyis nem null/ értéktöl. A
null-t az aritmetikai és skalár összehasonlitható operátorok
a következöképpen kezelik:
- Legyen A és B numerikus tipusu tárgyak. Ha A értéke
null, akkor a +A és -A kifejezések mindegyike a kiértékelés
alapján null.
Ha A null vagy B null, vagy mindkettö null, akkor a
következö kifejezések mindegyike
A + B A - B A x B A / B
a kiértékelés szerint null.
sql.doc Page: 19
- Legyen A és B összehasonlitható tárgyak. Ha A null vagy
B null, vagy mindkettö null akkor /egy WHERE vagy
HAVING klauzula kontextusában/ a következö kifejezések
mindegyike
A = B A < > B A < B A > B A <= B A >= B
a kiértékelés szerint ismeretlen igaz érték /vagyis a
kiértékelés eredménye nem az, hogy igaz , és nem az ,hogy
hamis érték/. Az ismeretlen igaz értéket a következö
igazság táblázatok definiálkják /T=tru /igaz/,
F=false /hamis/, ? = ismeretlen/:
AND | T ? F OR | T ? F NOT |
------------- ---------- -----
T | T ? F T | T T T T | F
? | ? ? F ? | T ? ? ? | ?
F | F F F F | T ? F F | T
Két speciális operátor , IS NULL és IS NOT NULL, van
megadva teszteléssel annak megállapitására, hogy egy
adott skalár érték null vagy nem null. Lásd a 9.fe-
jezetet.
- Az elözö pont dacára két null értéket egymással egyenlönek
tekintünk /ezzel egyenértéküen megfogalmazva, egymás
másolatainak tekintünk/ a másodpéldány elhagyás /DISTINCT/
a csoportositás /GROUP BY/ és a rendezés /ORDER BY/
céljaira.
Megjegyzések:
1. Egy korábban tett megállapitást megismételve: A
null-ok reprezentálásának olyannak kell lennie, hogy a
rendszer megkülönböztethesse ezeket az összes nem-null
értéktöl.Ebböl azonban nem következik, hogy a /például/
következö összehasonlitás "A<>3" a kiértékelés szerint
igaz, ha A null / a már elmagyarázottak szerint/.Ezért
kissé félrevezetö dolog azt állitani /ahogy a szabvány
állitja,/ hogy null egy érték; jobb lenne ugy tekinteni
ezt, mint egy hely foglalót egy értékhez, olyan érték-
hez, ami jelenleg ismeretlen.
2. Tulajdonképpen, az iró véleménye szerint, a
null értékek /legalábbis az SQL -ben definiáltak szerinti
null értékek/ elhibázott dolgot jelentenek és egyáltalán
sohasem szabad lett volna bevenni a szabványba.
Bizonyára elvitathatatlan , hogy az SQL tipusu null-ok
nagyon furcsa és nem konzisztens viselkedést mutatnak,
és gazdag hiba források, és zavart okozó források lehetnek
/ahogyan ez már az elözöekben a WHERE, a HAVING a DISTINCT,
a GROUP BY és ORDER BY paraméterekre vonatkozó megjegyzésekböl
is látható/. A gyakorlatban vonzóbb megoldás lehet a hiányzó
információknak olyan szokásos nem null értékkel történö
reprezentálása, mint például a szóközök és a -1 /minusz egy/.
Az SQL tipusu null-ok okozta problémák széles körü
tárgyalása a szerzönek a Relational Database:
Selected Writings /relációs adatbázis: válogatott irások
/ Addison - Wesley, 1986 / könyvében találhatók.
Megjegyzés vége.
sql.doc Page: 20
3.2 MUDULOK, ELJARASOK, ÉS BEAGYAZOTT SQL
1. Az SQL-nek egy szabványos alkalmazói programozási
verziója definiálásának kisérlete során az X3H2 bizottság
egy jelentös /jóllehet nem technikai / problémával került
szembe: az olyan nyelveknek, mint például a COBOL és a PL/1,
az ANSI szabványos verziói már definiálva vannak és már
léteznek ANSI bizottségok /például a COBOL esetében X3J4/ ezen
szabványos definiciók védelmére. Ezen szabványos nyelvek
mindegyikének külön-külön kiterjesztése, ugy hogy tartalmazza
a szükséges SQL függvényt, hatalmas mennyiségü munkával járna
- ezenkivül olyan munkával, amelynek általában kevés köze
lenne az adatbázis technológiához - és sok évvel késleltetné
egy SQL szabvány megjelenését. Ebböl következöen az X3H2
az ugynevezett modul nyelv megközelitést javasolta.
2. A modul nyelv lényegében egy kis nyelvböl áll tiszta
SQL szintaxis formátumban SQL adat manipulálási müveletek
kifejezéséhez. A modul nyelvben egy eljárás alapvetöen paraméter
deklarációk készletéböl és ezen paraméterek segitségével
összeállitott egyetlen SQL utasitásból áll. Például:
PROCEDURE DELETE_PART
SQLCODE
PNO_PARAM CHAR(6) ;
DELETE FROM P WHERE P.PNO = PNO_PARAM ;
Figyelje meg a /szükséges/ SQLCODE paramétert, melyet az el-
járást meghivó programhoz egy visszatéritési kód visszaadására
használunk. A nulla SQLCODE érték azt jelenti, hogy az utasitás
sikeresen végrehajtódott és semmilyen kivételes állapot nem
jött létre; +100-as érték azt jelenti, hogy nem volt olyan sor,
amely kielégitette volna a kérést; negativ érték azt jelenti,
hogy valamilyen hiba keletkezett.
A fent bemutatott eljárás a következöképpen hivható meg
egy PL/I programból:
DCL RETCODE FIXED BINARY(15) ;
DCL PNO_ARG CHAR(6) ;
DCL DELETE_PART ENTRY (FIXED BINARY(15), CHAR(6)) ;
........
PNO_ARG = 'P6' ; /* for example */
CALL DELETE_PART (RETCODE, PNO_ARG) ;
IF RETCODE = 0 THEN ...; /* delete operation succeeded */
ELSE ...; /* some exception occurred */
ahol:
for example = például
delete operation succeeded = törlési müvelet sikerült
some exception occurred = valamilyen kivételes állapot jött
létre.
Megjegyzés: /azoknak az olvasóknak,akik esetleg nem ismerik
aPL/I-et/: "DCL" egyszerüen a DECLARE-nek a szabványos PL/I
röviditése; egy "ENTRY" deklaráció egyszerüen egy külsö entry
pont vagy eljárás definiciója.
A modul nyelv igy biztositja a képességet, olyan host
nyelveken irt programok számára, mint például a PL/I,
COBOL, stb., SQL adat manipulálási müveletek végrehajtására
anélkül, hogy ezen nyelvek szintaxisában vagy szemantikájá-
sql.doc Page: 21
ban bármilyen változtatást kellene végrehajtani. Mindössze
arra van szükség,hogy /a/ a host / befogadó rendszer/ képes
legyen arra, hogy meghivjon olyan eljárásokat, amelyek más
nyelven vannak irva és külön vannak compillálva, valamint
hogy /b/ definiált összefüggés létezzen a host és a modul nyelv
adat tipusai között argumentum átadási célokra. Más szavakkal
a host nyelv szabvány és az SQL szabvány közötti összefüggés
analóg /ténylegesen azonos/ két host nyelv szabvány közötti
összefüggéssel: a host nyelvü program egy olyan külön compil-
lált programot /vagyis külsö eljárást/ hiv meg, mely törté-
netesen SQL -ben van irva, ahelyett, hogy a vizsgált host
nyelven vagy valamilyen más host nyelven lenne irva.
3. Az X3H2 bizottság nem szükségképpen akarja /vagy eset-
leg nem elsösorban azt akarja/, hogy a felhasználók ténylege-
sen kódoljanak közvetlen hivásokat a modul nyelvhez, ugy mint
ez a fenti példában látható. Ehelyett a normál müködési mód-
szer SQL utasitások közvetlen beágyazása a host nyelvü prog-
ram szövegébe, ugy mint ahogyan ez a 2. fejezetben a 2.2-es
és 2.9-es ábrákban látható. A fenti közvetlen hivás példának
megfelelö beágyazott SQL példa ugy nézhet ki, mint az alábbi-
akban látható példa. Megjegyzés: A példa nem teljes; az
SQLCODE és PNO deklarációkat "EXEC SQL BEGIN DECLARE SECTION;"
és "EXEC SQL END DECLARE SECTION;" utasitásokkal lehatárolt
"beágyazott SQL deklaráló részen" belül kell beágyazni.
/lásd a 10. fejezetet./
DCL SQLCODE FIXED BINARY(15) ;
DCL PNO CHAR (6) ;
........
PNO = 'P6' ; /* for example */
EXEC SQL DELETE FROM P WHERE P.PNO = :PNO ;
IF SQLCODE = 0 THEN ...; /* delete operation succeeded */
ELSE ...; /* dome exception occurred */
ahol:
for example = például
delete operation succeeded = törlési müvelet sikerült
some exception occurred = valamilyen kivételes állapot
jött létre.
Figyelje meg, hogy most sincs szükség a DELETE_PART eljárás
explicit definiálására. Azonban a "beágyazott SQL" az SQL
szabványnak mint olyannak, nem valódi része. Ehelyett a fent
látható beágyazott SQL kód egyszerüen a korábban látható, köz-
vetlen hivás verziónak /beleértve az explicit eljárás definiciót
is/ egyszerüen a szintaktikai röviditéseként van definiálva.
Egy beágyazott SQL implementálásnak biztositani kell valamilyen
fajta preprocesszort, melynek hatása egy beágyazott SQL program
logikai átalakitása ekvivalens közvetlen hivásu verzióvá.
Az X3H2 SQL specifikáció a COBOL-hoz, FORTRAN-hoz, Pascal-
hoz és PL/I-hez az SQL beágyazott verzióit definiáló "mellekletek"
vagy függelékek halmazát tartalmazza /melyek természetesen
nem részei a szabványnak./ Az ilyen nyelvekbe az SQL beágyazása
részleteinek leirását a 10. fejezetre halasztjuk.
4. Megjegyezzük, hogy a modul nyelv megközelités nem zárja
ki eleve a host nyelvek esetleges kiterjesztésének lehetöséget
ugy, hogy természetes SQL támogatást biztositsanak. Azonban az
sql.doc Page: 22
SQL szabvány explicit módon nem javasol semmifajta ilyen
természetes támogatást a korábbiakban vázolt okok miatt.
5. A modul nyelv használatára megadunk egy másik példat
annak a szempontnak a bemutatására, hogy általában a para-
méterek olyan mechanizmusként is szolgálnak, mellyel az értékek
visszaadhatók a meghivott programnak. Természetesen ezt a
szempontot a fenti DELETE példa már bemutatta az SQLCODE
paraméter speciális esetére.
PROCEDURE GET_WEIGHT
SQLCODE
PNO_PARAM CHAR(6)
WEIGHT_PARAM DECIMAL(3) ;
SELECT P.WEIGHT
INTO WEIGHT_PARAM
FROM P
WHERE P.PNO = PNO_PARAM ;
Lehetséges meghivás PL/I-böl:
DCL RETCODE FIXED BINARY (15) ;
DCL PNO_ARG CHAR (6) ;
DCL WEIGHT_ARG DECIMAL (3) ;
DCL GET_WEIGHT ENTRY (FIXED BINARY (15) ;
CHAR (6) , DECIMAL (3)) ;
.........
PNO_ARG = 'P6' ; /* for example */
CALL GET_WEIGHT RETCODE, PNO_ARG, WEIGHT_ARG ;
IF RETCODE = 0 THEN ... ; /* WEIGHT_ARG = retrieved value */
ELSE ... ; /* some exception occurred */
ahol:
for example = például
retrieved value = visszanyert érték
some exception occurred = valamilyen kivételes állapot jött
létre.
Beágyazott SQL verzió /ismét kihagyva a szükséges BEGIN és
END DECLARE SECTION utasitásokat/:
DCL SQLCODE FIXED BINARY (15) ;
DCL PNO CHAR (6) ;
DCL WEIGHT DECIMAL (3) ;
......
PNO = 'P6' ; /* for example */
EXEC SQL SELECT P.WEIGHT
INTO :WEIGHT
FROM P
WHERE P.PNO = :PNO ;
IF SQLCODE = 0 THEN ...; /* WEIGHT = retrieved value */
ELSE ...; /* some exception occured */
ahol:
for example = például
retrieved value = visszanyert érték
some exception occurred = valamilyen kivételes állapot jött
létre.
sql.doc Page: 23
3.3 ADAT VÉDELEM, INTEGRITAS ÉS TRANZAKCIO FELDOLGOZAS
Adat védelem
1. Az SQL szabvány tartalmazza egy meghatalmazás azonosi-
tó fogalmát, mely informális módon ugy tekinthetö, mint az
a név, amellyel valamilyen felhasználó a rendszer számára is-
mert. Altalában a "user" /felhasználó/ kifejezést fogjuk
használni a "authorization identifier" /meghatalmazást azono-
sitó/ helyett a rövidség kedvéért; azonban jegyezzük meg,
hogy a szabvány nem tartalmaz semmilyen ehhez hasonló formális
"user" /felhasználó/ fogalmat. Minden sémának van egy hozzá-
tartozó meghatalmazás azonositója; a meghatalmazás azonositó
által kijelölt felhasználó a "owner" /tulajdonosa/ az ebben
a sémában létrehozott minden táblának és nézetnek. A környe-
zetben nem lehet két olyan séma, melynek azonos a meghatalmazás
azonositójuk.
2. Egy adott tárgyon /objektumon/ egy adott müvelet vég-
rehajtásához a felhasználónak rendelkeznie kell a szükséges
privilégiummal a müvelet és a tárgy ezen kombinációjához.
Azok a tárgyak, amelyekre az ilyen privilégiumok érvényesek
az alap táblázatok és nézetek; a megfelelö müveletek a
SELECT, INSERT, UPDATE, /megadott oszlopok/ és DELETE.Semmi-
lyen speciális privilégiumra nincs szükség egy séma vagy
alap tábla létrehozásához. SELECT privilégiumokra van
szükség /minden hivatkozott táblázatban/ egy nézet létreho-
zásához vagy egy cursor definiálásához.
3. Egy alap tábla tulajdonosa rendelkezik az összes
privilégiummal ezen alap táblán. Egy nézet tulajdonosa rendel-
kezik ezen a nézeten az összes olyan privilégiummal, melynek
"make sense" / van értelme /:
- Ha a nézet aktualizálható / lásd a 8. fejezetet / és a
tulajdonos rendelkezik az alapul szolgáló táblán az
INSERT és/vagy UPDATE és/vagy DELETE privilégiumokkal,
akkor a tulajdonos a nézeten ugyanezekkel a privilégiumokkal
rendelkezik.
- Egyebként a tulajdonos a nézeten csak a SELECT privilégiummal
rendelkezik.
4. Egy tárgy tulajdonosa az ezen tárgyra /objektumra/
vonatkozó privilégiumokat megadhatja más felhasználóknak a
GRANT müvelet segitségével /a sémában van megadva/. Ezenkivül
ha az A felhasználó megad valamilyen P privilégiumot a B fel-
használónak, akkor az A felhasználónak megvan az a választási
lehetösége, hogy a P privilégiumot a B felhasználónak a
"with the grant opcion" /a grant opcióval/ adja meg /a GRANT
müveletben a WITH GRANT OPTION /GRANT opcióval/ klauzulán
keresztül/. A GRANT opcióval egy privilégium megadása azt
jelenti, hogy az a személy, aki a privilégiumot megkapja
ugyancsak átadhatja ugyanezt a privilégiumot - a GRANT op-
cióval vagy anélkül - valamilyen további felhasználónak.
Egyik felhasználó sem adhat át olyan privilégiumot, mellyel
nem rendelkezik.
sql.doc Page: 24
5. Minden modulnak van egy hozzátartozó meghatalmazás
azonositója /vagyis felhasználója/ is. Az ezen meghatalmazás
azonositó által reprezentált felhasználónak rendelkeznie
kell az ebben a modulban lévö összes SQL utasitáshoz tartozó
minden szükséges privilégiummal. Megjegyezzük, hogy egyetlen
modul /esetleg még egyetlen SQL utasitás is/ több sémára is
hivatkozhat.
6. A táblákat /alap táblák és nézetek/ U.T. alaku két-
részes név azonositja, ahol "U" egy felhasználó neve /megha-
talmazás azonositó/ és "T" egy egyszerü /vagyis nem minösitett/
azonositó. A különbözö sémákban definiált tábláknak azonos
nem minösitett nevük lehet; igy például az U1.T. és U2.T nevek
/ahol U1 és U2 két különbözö felhasználó név/ két különbözö
táblát azonosit.
7. Egy SQL utasitásban egy táblára való hivatkozás opci-
onálisan kihagyhatja a név "U." részét /valójában ez a szoká-
sos eset/. Az "U." rész kihagyása ekvivalens azon séma vagy
modul meghatalmazás azonositójának megadásával, amelyben a
referencia megjelenik.
Integritás
1. Egy alap tábla definiciója opcionálisan tartalmazhat
bizonyos integritás követelményeket. Minden aktualizálási mü-
velet, mely valamilyen elöirt követelményt megszegne, vissza-
utasitásra fog kerülni; az adatbázis változatlan marad és az
SQLCODE egy implementáció definiálta negativ értékre áll be.
A szabvány a következö integritás követelményeket támogatja:
- NOT NULL: A tábla bármelyik oszlopához megadható. Egy
ilyen oszlopba null érték bevitelére irányuló minden kisérlet
figyelmen kivül fog maradni /visszautasitásra kerül/.
Ha NOT NULL nincs elöirva egy adott oszlophoz, akkor erre
az oszlopra meg van engedve, hogy null-okat tartalmazhasson.
- UNIQUE: A tábla bármely oszlopához vagy bármely oszlop
kombinációjához megadható. Minden ilyen oszlophoz vagy
minden ilyen oszlop kombinációban lévö oszlophoz a NOT
NULL-nak is megadottnak kell lennie. Visszautasitásra
fog kerülni minden olyan kisérlet, melynek során a táblá-
ba olyan sort akarnak bevinni, mely a megadott oszlopban
vagy oszlop kombinációjában ugyanolyan értéket tartalmaz,
mint valamilyen már létezö sor. Ha az UNIQUE nincs meg-
adva egy adott oszlophoz /oszlop kombinációhoz/, akkor
meg van engedve, hogy ez az oszlop /kombináció/ ismétlödö
értékeket tartalmazzon.
Megjegyzés: Az integritás követelmények jóval szélesebb
körének támogatása lenne kivánatos. Vagyis sürgösen
szükség van elsödleges és idegen kulcsok támogatá-
sára. Lásd a 11. fejezetet. Megjegyzés vége.
2. Egy aktualizálható nézet definiciója /lásd a 8.4-es al-
fejezetet/ opcionálisan tartalmazhatja a WITH CHECK OPTION
klauzulát. Egy ilyen nézetbe egy sor beszúrására vagy egy
sql.doc Page: 25
ilyen nézetben egy sor aktualizálására irányuló minden kisér-
let, mely olyan, hogy az ujonnan beszurt vagy aktualizált re-
kord nem elégiti ki a nézetet definiáló "search condition"
/keresési feltételt/ /lásd a 8. fejezetet/ visszautasitásra
fog kerülni; az adatbázis változatlan marad és beállitódik az
SQLCODE egy implementáció definiálta negativ értékre. Megje-
gyezzük, hogy ha a W nézet a V aktualizálható nézetböl szár-
maztatott aktualizálható nézet, és a WITH CHECK OPTION meg
van adva a V nézethez, a WITH CHECK OPTION automatikusan nem
lép érvénybe a W nézethez, hanem ezt explicit módon elö kell
irni, /ha kivánatos, azonban nehéz megállapitani azt a hely-
zetet, amikor nem lenne kivánatos/.
Megjegyzés: DB2-ben a CHECK opció csak akkor adható meg,
ha a nézet aktualizálható és a nézet definició nem foglal
magában al-lekérdezést. Ezt az anomáliát a szabványban
elkerülik, mivel egy al-lekérdezést magában foglaló néze-
tek nem aktualizálhatóként vannak definiálva. Azonban
a szabvány megörzött egy másik DB2 hiányosságot, neveze-
tesen azt, hogy a check opció nem örökölhetö. Tény, hogy
a check opció meglehetösen különös jellemzöje a nyelvnek;
az integritás követelmények megfelelöbb módon illenek
az alap adatokhoz mint a nézetekhez. Ennek a szem-
pontnak a további tárgyalása /és különösen a check opció
tárgyalása/ a szerzönek az An Introduction to Database
Systems: Volume 1 /adatbázis rendszerek bevezetése: I-es
kötet/ /4. kiadás, Addison-Wesley, 1985/ könyvében talál-
ható. Lásd még a jelen könyv 8.4-es alfejezetét is.
Megjegyzés vége.
Tranzakció feldolgozás
1. Egy tranzakció olyan SQL /és esetleg egyéb/ müveletek
sorozata, melyekröl garantálva van, hogy a legelemibb müvele-
tek /"atomic"/ hiba elháritási és konkurencia vezérlési cé-
lokra.
2. Ha egy program meghiv egy SQL müveletet és éppen
nincs aktiv tranzakció ehhez a programhoz, akkor automatikusan
inditásra kerül egy tranzakció. Egy SQL müveletnek ugyanazon
program által történö minden ezt követö meghivását ugyanezen
tranzakció részének tekintjük, mindaddig, amig a tranzakció
be nem fejezödik. A tranzakciók tehát nem ágyazhatók egymásba.
3. Egy tranzakció vagy COMMIT müvelet /normál, vagy sike-
res befejezés/ vagy egy ROLLBACK müvelet /egy rendellenes, vagy
sikertelen befejezés/ végrehajtásával fejezödik be. A sikeres
befejezödést "termination with commit" /befejezés a feladat
teljesitésével/ -nek nevezzük; a sikertelen befejezödést "ter-
mination with rollback" /befejezödés visszaállitásával/ -nak
nevezzük.
4. Egy adott T1 tranzakció által végrahajtott adatbázis
aktualizálások nem lesznek láthatóak semmilyen ettöl eltérö
T2 tranzakció számára mindaddig, amig a T1 tranzakció COMMIT-tal
/feladat végrehajtással/ be nem fejezödik.
sql.doc Page: 26
A feladat teljesitésével történö befejezödés eredményeként a
tranzakció végrehajtotta összes aktualizálás láthatóvá válik
a többi tranzakció számára; az ilyen aktualizálások garan-
táltan sohasem törölhetök /ez a "committed update"/ végrehaj-
tott aktualizálás/ definiciója/. A rollback-kal /visszaálli-
tással/ befejezés eredményeként a tranzakció által végrehaj-
tott összes aktualizálás törlésre kerül; az ilyen aktualizá-
lások sohasem lesznek láthatóak más tranzakciók számára.
5. Az egyidejü /konkurens/ tranzakciók készletének inter-
leaved végrehajtása garantáltan sorrendbe rendezhetö abban
az értelemben, hogy ugyanazt a hatást fogja végrehajtani, mint
ugyanezen tranzakciók valamilyen /nem elöirt/ soros végrehaj-
tása. A soros végrehajtás olyan végrehajtás, melyben a tranz-
akciók végrehajtása egyenként történik, minden tranzakció
befejezödik, mielött a következö tranzakció indulna.
3.4 ALAPVETÖ NYELV ELEMEK
Karakterek
A legprimitivebb nyelv elemek az alapul szolgáló karakter
készlet egyes karakterei. Ezeket a karaktereket használjuk
magasabb szintü /nem primitiv/ nyelv elemek felépitésére,
valamint karakter füzér adat értékek létrehozására. A karakter
készlet a nagybetükböl, A, B, .... Z, a kisbetükböl, a, b, ...
c, a számjegyekböl, 0, 1, 2, ... 9, egy uj sor markerböl, /*/
és a speciális karaktereknek nevezett egyéb karakterek kész-
letéböl áll. A speciális karaktereknek legalább a következök
mindegyikét tartalmaznia kell:
% , ( ) < > . : = + - * /
Plusz tartalmazniuk kell egy space /szóköz/ karaktert. A komp-
lett karakter készlet és ehhez a karakter készlethez az össze-
válogatási sorrend, egyaránt az implementáció által definiá-
landó.
----- ----- --------
* Az uj sor marker opcionális. Az implementáció szabadon
döntheti el a "end of line" /sor vége/ jelzését egy megkülön-
böztetett karakter segitségével történö jelöléstöl eltérö
valamilyen más módon, ha ugy dönt.
Literálok
A literálok /melyeket konstansoknak is neveznek, jollehet a
"konstans" nem hivatalos szabványos kifejezés/ kétféle tipu-
suak; karakter füzér /röviditve füzér/ és numerikus. Egy
karakter füzér literál aposztrófok közé zárt karakterek soro-
zatából áll; ilyen literálon belül magát az aposztróf karak-
tert két egymást közvetlenül követö aposztróf reprezentálja.
Példák:
'123 Main Street' 'PIG' '01234' 'honey don''t'
sql.doc Page: 27
A numerikus literálok viszont kétféle tipusuak, pontos és meg-
közelitö tipusuak. Egy pontos numerikus literál egy opcionális
elöjelü decimális számból áll, tizedes ponttal vagy anélkül.
Példák:
7.5 12.00 0.001 -4.75
Egy megközelitö numerikus literál tizedes ponttal rendelkezö
vagy tizedes pont nélküli elöjeles vagy nem elöjeles deci-
mális számból áll, melyet az E betü és egy opcionális elö-
jelü decimális integer /egész szám/ követ. Példák:
4E3 -95.7E46 +364E-5 0,7E1
Egy literált ugy tekintünk, hogy a nyilvánvaló adat tipussal,
hosszúsággal és pontossággal, vagy pontossággal és skálaté-
nyezövel /az adat tipustól függöen/ rendelkezik ugy, ahogyan
ezt a literál formátuma jelzi. Ezenkivül ugy tekintjük, hogy
a literálok a NOT NULL tulajdonsággal is rendelkeznek.
Token-ek
A token-ek lexikális egységeket reprezentálnak a nyelvben.
Egy token vagy egy határoló szimbólum vagy egy nem határoló
szimbólum. Egy határoló szimbólum vagy egy karakter füzér literál,
vagy a következö speciális szimbólumok valamelyike:
, ( ) < > . : = + - * / <> <= >=
Egy nem határoló szimbólum egy numerikus literál, azonositó
vagy kulcsszó. Az azonositó 18 karakternél nem hosszabb ka-
rakter füzér. A karakterei közül az elsönek nagybetünek kell lennie;
a többi nagybetük, számjegyek és az aláhúzás karakter /_ / bármi-
lyen kombinációja lehet. A következök mindegyike azonositó:
authorization identifiers /meghatalmazás azonositók/
unqualified table names /nem minösitett tábla nevek/
unqualified column names /nem minösitett oszlop nevek/
range variable names /tartomány változó nevek/ /vagy "cor-
relation names" /korreláció nevek/; lásd a 9.5-ös alfeje-
zetet/
cursor names /cursor nevek/
module names /modul nevek/
procedure names /eljárás nevek/
parameter names /paraméter nevek/
A kulcsszó egy név, amelynek valamilyen elöirt jelentése
van magán az SQL nyelven belül. A kulcsszavak fentartott
szavak /vagyis egyik kulcsszó sem használható azonositóként/.
sql.doc Page: 28
A kulcsszavak a következök:
ALL AND ANY AS
ASC AUTHORIZATION AVG BEGIN
BETWEEN BY CHEAR CHARACTER
CHECK CLOSE COBOL COMMIT
CONTINUE COUNT CREATE CURRENT
CURSOR DEC DECIMAL DECLARE
DELETE DESC DISTINCT DOUBLE
END ESCAPE EXEC EXISTS
FETCH FLOAT FOR FORTRAN
FOUND FROM GO GOTO
GRANT GROUP HAVING IN
INDICATOR INSERT INT INTEGER
INTO IS LANGUAGE LIKE
MAX MIN MODULE NOT
NULL NUMERIC OF ON
OPEN OPTION OR ORDER
PASCAL PLI PRECISION PRIVILEGES
PROCEDURE PUBLIC REAL ROLLBACK
SCHEMA SECTION SELECT SET
SMALLINT SOME SQL SQLCODE
SQLERROR SUM TABLE TO
UNION UNIQUE UPDATE USER
VALUES VIEW WHENEVER WHERE
WITH WORK
Minden token-t opcionálisan bármilyen számu elválasztó kö-
vethet, ahol az elválasztó egy space, egy uj sor marker, vagy
egy megjegyzés. Minden nem határoló szimbólum token-t vagy
egy elválasztónak, vagy egy határoló szimbólum token-nek kell
követnie. A megjegyzés két egymást követö kötöjelböl /--/
áll, melyet uj sor marker kivételével karakterek bármilyen
sorozata, majd pedig egy uj sor marker követ. Megjegyzés:
A következö alfejezetben bevezetett szintaktikai jelölés
általában teljes mértékben figyelmen kivül hagyja az elvá-
lasztókat.
Egyik token számára sincs megengedve, hogy bármilyen
space karaktert tartalmazzon, kivéve /természetesen/ egy ka-
rakter füzér literált, ahol a beágyazott space karakterek
meg vannak engedve, és szignifikánsak.
3.5 JELÖLÉS
Az SQL nyelv elemek szintaxisa ebben a könyvben a jól ismert
BNF jelölés egyik variánsának segitségével van megadva. A
variánsunk a következöképpen van definiálva:
- A speciális karaktereket és nagybetüs anyagot pontosan
ugy kell irni, ahogyan látható. Kisbetüs anyag olyan
szintaxis kategóriát reprezentál, mely egy másik létreho-
zási szabály tárgya /*/,
és ebböl következik ,hogy /végül is/ a felhasználó
által kiválasztott specifikus értékekkel kell helyettesiteni.
sql.doc Page: 29
----- ----- -------
* Ebben a könyvben azonban a létrehozási szabályok egy része
a legalacsonyabb részletezési szinten van, ugy hogy az a sza-
bály, amely egy azonositó felépitését definiálja, nem látható
explicit BNF stilusban, hanem egyszerüen informális módon van
leirva a szövegben.
- Függöleges vonalakat " | " használunk alternativák elvá-
lasztására.
- Szögletes zárójeleket " [ " és " ] " használunk annak jel-
zésére, hogy az ezen zárójelek közé zárt anyag opcionális;
vagyis egy vagy több /függöleges vonalakkal elválasztott/
olyan tételt tartalmazó készletböl áll, melyböl legfeljebb
egyet kell kiválasztani.
- A kapcsos zárójeleket, " " annak jelzésére használ-
juk, hogy az ezen kapcsos zárójelek közé zárt anyag több
/függöleges vonalakkal elválasztott/ olyan tételt tartalmazó
készletböl áll, melyböl pontosan egyet kell kiválasztani.
A példa kedvéért bemutatunk a "numerikus-literál" /informá-
lis módon az elözö alfejezetben van definiálva/ szintaxis
kategóriához egy létrehozási szabály készletet.
numeric-literal
::= exact-numeric-literal
| approximate-numeric-literal
exact-numeric-literal
::= [ + | - ]
approximate-numeric-literal
::= exact-numeric-literal E signed-integer
signed-integer
::= [ + | - ] integer
Az "integer" kategória nincs tovább definiálva; vagyis ez
egy "terminális kategória" ezen egyszerü példa szempontjából.
Közbevetöleg megjegyezzük, hogy jóllehet a példában látható
létrehozási szabályok tartalmaznak különbözö beágyazott spa-
ce-ket olvashatósági okok miatt, egy numerikus literál token-
-nek /lásd a 3.4-es alfejezetet/ nem szabad tartalmaznia
semmilyen space-t.
Mindegyik BNF jelölésünk lényegében ugyanaz volt,
amit az SQL szabvány dokumentációjában is használtak.
Azonban bevezetünk két további, saját egyszerüsitö konvenciót
a következöképpen:
- Ha "xyz" egy szintaxis kategória, akkor "xyz-commalist"
olyan szintaxis kategória, mely egy vagy több "xyz"-t
tartalmazó listából áll, melyben minden szomszédos "xyz"
párt egy vesszö választ el egymástól.
- Ha "xyz" egy szintaxis kategória, akkor "xyz-list" olyan
szintaxis kategória, mely egy vagy több "xyz"-t tartal-
mazó listából áll, melyben minden szomszédos "xyz" párt
legalább egy elválasztó /általában egy space/ választ el.
sql.doc Page: 30
Ennek a két szabálynak az a "nettó" hatása, hogy csök-
kenti a szükséges létrehozási szabályok össz hosszuságát és/
vagy számát. Az alábbiakban megadunk egy példát ezek haszná-
latának bemutatására /a "sémához" tartozó elsö néhány létre-
hozási szabály a 4. fejezetböl való/:
schema
::= CREATE SCHEMA
AUTHORIZATION user
[ schema-element-list ]
schema-element
::= base-table-definition
| view-definition
| grant-operation
base-table-definition
::= CREATE TABLE base-table
(base-table-element-commalist)
base-table-element
::= column-definition
| unique-constraint-definition
és igy tovább.
Megjegyzés: Világos áttekinthetöség és szabatossági okok
miatt szándékosan nem mindig ugyanazokat a neveket hasz-
náljuk a szintaxis kategóriákhoz, mint amit az SQL szab-
vány. Az SQL szabvány kifejezései nem mindig különösen sze-
rencsések. Például a szabvány a "tábla definició" /table de-
finition/ nevet arra használja, hogy arra utaljon, amelyet
mi az elözöekben "base table" /alap tábla definiciónak/ ne-
veztünk, mely el akarja rejteni azt a /fontos/ tényt, hogy
egy nézet is definiált tábla és ebböl következik, hogy egy
"view definition" /nézet definició/-nak mindössze egy spe-
ciális "table definition" /tábla definició/ esetnek kell
lennie. Ezt a legutolsó gondolatmenetet kissé tovább foly-
tatva: az SQL tulajdonképpen ambivalens a "table" /tábla/
kifejezés jelentése szempontjából; esetenként vagy egy alap
táblát vagy egy nézetet jelent, illetve esetenként specifi-
kusan alap táblát jelent. Ebben a könyvben a "table" /tábla/
kifejezést ugy használjuk, hogy minden fajta táblát jelent
és "base table" /alap tábla/-t használunk, amikor specifikusan
egy alap táblára gondolunk.
Megjegyzés vége.
sql.doc Page: 31
4
-------- ----- ------ -------- ----- ------ -
Adat definició:
A séma definiáló nyelv
4.1 SZINTAXIS
Ebben a fejezetben részletesen megvizsgáljuk az adatbázis
definiálást. Emlékezzünk vissza a 2. fejezetböl, hogy egy
adatbázist a séma definiáló nyelv segitségével létrehozott
egy vagy több séma definiál. Ennek a nyelvnek a szintaxisa
a következö:
schema
::= CREATE SCHEMA
AUTHORIZATION user
[schema-element-list]
schema-element
::= base-table-definition
| view-definition
| grant-operation
base-table-definition
::= CREATE TABLE base-table
(base-table-element-commalist)
base-table-element
::= column-definition
| unique-constraint-definition
column-definition
::= column data-type [NOT NULL [UNIQUE]]
unique-constraint-definition
::= UNIQUE (column-commalist)
view definition
::= CREATE VIEW view [(column-commalist)]
AS query-specification
[WITH CHECK OPTION
grant operation
::= GRANT privileges ON table TO grantee-commalist
[WITH GRANT OPTION]
privileges
::= ALL [PRIVILEGES] | operation-commalist
operation
::= SELECT | INSERT | DELETE
| UPDATE [(column-commalist)]
grantee
::= PUBLIC | user
sql.doc Page: 32
Amint a szintaxis jelzi, egy séma egy CREATE SCHEMA
klauzulából, egy AUTHORIZATION klauzulából és nulla vagy több
CREATE TABLE müveletböl és/vagy CREATE VIEW müveletböl és/vagy
GRANT müveletböl áll. Az AUTHORIZATION klauzula azonositja
az ebben a sémában létrehozott valamennyi alap tábla és/vagy
nézet tulajdonosát, valamint az ebben a sémában levö valamennyi
GRANT müvelet által megadott valamennyi privilégium adományo-
zóját is. A nézetek tárgyalását a 8. fejezetre halasztjuk.
Az alap táblákat és privilégiumokat a jelen fejezet 4.2-es
és 4.3-as alfejezeteiben tárgyaljuk.
Megjegyzés: Az "CREATE SCHEMA" kifejezés kissé zavaró.
Konzisztensebb lehettem volna, ha a müveletet /például/
"CREATE DATABASE"-nek /adatbázis létrehozásnak/ /a
CREATE TABLE-vel és CREATE VIEW-vel analóg módon/ nevezem.
Egyébként miért ne lehetne /például/ CREATE TABLE DEFI-
NITION /tábla definició létrehozás/ és CREATE VIEW DEFI-
NITION /nézet definició létrehozás/ ? Ugyanilyen okból
a "schema definition language" /séma definiáló nyelvnek/
valójáben egyszerüen csak "schema language" /séma nyelv-
nek/ kell lennie /a modul nyelvvel/ analóg módon.
Megjegyzés vége.
Emlékeztetjük az olvasót arra, hogy a séma definiáló mü-
veletek nem részei a modul nyelvnek és nem hivhatók meg egy
hagyományos alkalmazói programból.
4.2 ALAP TABLAK
Most tárgyaljuk részletesen a CREATE TABLE müveletet. CREATE
TABLE-t használunk új /üres/ alap táblák létrehozására. A
szintaxis
CREATE TABLE base-table (base-table-element-commalist)
ahol "base-table" /alap tábla/ a nem minösitett név az újonnan
létrehozott alap táblához /*/ és minden egyes alap tábla elem
vagy egy oszlop definició, vagy egy UNIQUE követelmény defi-
nició. Egy új alap tábla teljesen minösitett neve U.T, ahol
U az a meghatalmazás azonositó, amely a CREATE TABLE müvele-
tet tartalmazó séma AUTHORIZATION klauzulájában van megadva
és T az ebben a müveletben elöirt azonositó.
___________________
* valójában a név minösitett lehet, de ha ilyen, akkor a
minösitönek a séma AUTHORIZATION /meghatalmazás/ klauzulában
megadott meghatalmazás azonositónak kell lennie.
Egy oszlop definició viszont a következö alakot veszi
fel
column data-type [ NOT NULL [UNIQUE]]
ahol "column" /oszlop/ a kérdéses oszlophoz tartozó nem minö-
sitett név, "data type" / adat tipus/ az oszlop adat tipusát
sql.doc Page: 33
adja meg, a NOT NULL és UNIQUE pedig a 3. fejezetben /3.3-as al-
fejezet/ leirtak szerintiek. Az oszlopra az SQL adat manipu-
lációs müveletekben a T.C névvel lehet hivatkozni, ahol T annak
az alap táblának a minösitett, vagy nem minösitett neve, ame-
lyik oszlopot tartalmazza, és C az oszlop definicióban meg-
adott azonositó. /*/
___________________
* Erre R.C névvel is lehet hivatkozni, ahol R egy olyan tar-
tomány változó /vagy "correlation variable" /korreláció neve/,
amelyik kiterjed /ranges/ a T egészére /lásd 9.5-ös alfejeze-
tet/.
Egy UNIQUE követelmény definició a következö alakot ölti:
UNIQUE (column-commalist)
ahol minden "column" /oszlop/ a létrehozandó alap tábla egyik
oszlopának a nem minösitett neve. Egy UNIQUE követelmény
definiciójában megemlitett minden oszlopra elöirt NOT NULL-nak
kell lennie. Ismét elmondjuk, hogy nézze meg a 3.3-as alfeje-
zetben a további leirást. A következö oszlop definició
column-X data-type-X NOT NULL UNIQUE
az alábbi specifikáció röviditése
column-X data-type-X NOT NULL
..........
UNIQUE (column-x)
Lásd a 2. fejezet 2.3-as ábráját, melyben néhány példát adunk
meg a CREATE TABLE-re.
Adat tipusok
A szabványos SQL a következö adat tipusokat támogatja:
CHARACTER [(length)]
NUMERIC [(precision [ , scale])]
DECIMAL [(precision [ , scale])]
INTEGER
SMALLINT
FLOAT [(precision)]
REAL
DOUBLE PRECISION
Megjegyzések:
1. A CHARACTER, DECIMAL és INTEGER CHAR-ra, DEC-re ill.
INT-re rövidithetö. A SMALLINT rövidités nem oldható fel SMALL-
INTEGER-re. Jegyezze meg azt is, hogy nincs SINGLE PRECISION.
sql.doc Page: 34
2. A "length" /hosszúság/, "precision" /pontosság/ és
"scale" /skálatényezö/ mindegyike elöjel nélküli decimális
integer /"length" és "precision" esetében nagyobb mint nulla/.
Egy adott NUMERIC vagy DECIMAL oszlop esetén a "precision"
értékének nagyobbnak mint, vagy egyenlönek kell lennie a
"scale" értékével. A "length"-hez, "scale"-hez és "precision"-
hoz az alap értékek 1, 0 illetve implementáció definiálta ér-
ték.
3. Az INTEGER-nek és SMALLINT-nek p1 illetve p2 imple-
mentáció definiálta pontossága van /mindkét esetben nulla
scale-vel/, úgy, hogy p1>=p2.
4. A tényleges pontosság és skálatényezö /scale/ a NUMERIC-
hoz a megadott "precision" és "scale". A DECIMAL tényleges pon-
tosságának nagyobbnak mint, vagy egyenlönek kell lennie a meg-
adott "precision"-nal a tényleges scale-nek a megadott "scale"-
nek kell lennie.
5. A FLOAT tényleges pontosságának nagyobbnak mint, vagy
egyenlönek kell lennie a megadott "precision"-nal. A REAL és a
DOUBLE PRECISION p1 illetve p2 implementáció definiálta pon-
tosságúak, úgy, hogy p1>p2.
Megjegyzés: A megadott adat tipusok csak az alapvetöen
fix hosszúságú karakter füzérek, és a fix és lebegöpontos
decimális számok. Az adat tipusoknak mindössze ezen né-
hányra korlátozásának az oka feltételezhetöen az volt,
hogy csak ezek az adat tipusok azok, amelyek közösek
minden fö host nyelvhez, /*/ de sajnos a bizottság nem látta
alkalmasnak, hogy más általánosan szükséges tipusokat is
bevigyen, ilyenek a dátumok, idöpontok, pénz értékek,
bináris számok, bit füzérek, logikai értékek, változó
karakter füzérek, stb. Ami a bevitt /figyelembe vett/ spe-
cifikus tipusokat illeti, ezek legalábbis kissé zavarónak
látszanak. Megjegyzés vége.
___________________
* Ez a kijelentés túlegyszerüsités. Az egyetlen adat tipus,
amely valóban közös minden host nyelv esetén, valószinüleg
a fix hosszúságú karakter füzérek. Igy például ha egy SQL
tábla tartalmaz egy DECIMAL/5.3/-ként definiált oszlopot,
akkor ez az oszlop minden probléma nélkül elérhetö egy PL/I
programból, mivel a PL/I egy pontosan analóg adat tipust tar-
talmaz. FORTRAN programból is elérhetö, de itt lehetnek prob-
lémák is, mivel a FORTRAN nem tartalmaz egy pontosan analóg
adat tipust; igy ezen DECIMAL/5,3/ értékeket át kell majd
alakitani /például/ REAL értékekre, esetleges átalakitási
hibákkal.
sql.doc Page: 35
4.3. PRIVILÉGIUMOK
Ha T egy alap tábla vagy egy aktualizálható nézet, a T-n érvé-
nyes módon végrehajtható müveletek a SELECT, INSERT, UPDATE,
/megadott oszlopokon/ és DELETE. Ha T egy nem aktualizálható
nézet, az egyetlen müvelet, ami T-n érvényesen végrehajtható a
SELECT. Ha T egy tábla és O egy olyan müvelet, ami érvényes
módon végrehajtható egy T-n, akkor az U1 felhasználó rendel-
kezik azzal a privilégiummal, hogy végrehajtsa az O-t a T-n,
akkor, és csak is akkor, ha vagy /a/ U1 a T tulajdonosa,
vagy /b/ az U1-nek explicit módon megadta ezt a privilégiumot
más U2 felhasználó, ahol U2 rendelkezik ezzel a privilégium-
mal "with the grant option"-nal /a grant opcióval/ /lásd
lejjebb/. Az U felhasználó végrehajthatja az O müveletet a T
táblán, akkor, és csak is akkor, ha az U rendelkezik azzal a
privilégiummal, hogy végrehajtsa az O-t a T-n.
Semmilyen speciális privilégiumokra nincs szükség egy
séma vagy egy alap tábla létrehozásához. A SELECT privilégi-
umra van szükség /minden hivatkozott táblán/ egy nézet létre-
hozásához.
A privilégiumok explicit módon vannak megadva /engedé-
lyezve /az alábbi szintaxisú GRANT müvelet segitségével:
GRANT privilegies ON table TO grantee-commalist
[WITH GRANT OPTION]
ahol:
/a/ "privileges" /privilégiumok/ vagy ALL [PRIVILEGES] vagy
specifikus müveletek egy commalist-je. /SELECT és/vagy
INSERT és/vagy UPDATE és/vagy DELETE - esetleg nem minö-
sitett oszlop nevek zárójelek közé zárt commmalist-jével,
UPDATE esetén/;
/b/ Az ON klauzula tárgya egy minösitett vagy nem minösitett
tábla név /mely egy alap táblát vagy egy nézetet azonosit/
/c/ Minden "grantee" /engedélyes vagy egy meghatalmazás azo-
nositó, vagy a PUBLIC /*/ speciális kulcsszó.
_____ _______ ______ _______
* A szabvány ténylegesen engedélyesek /grantee/ listáját ad
meg, nem pedig commalist-et, a TO klauzula tárgyaként. Ez a
kis ellentmondás látszólag egyszerü figyelmetlenség a bizottság
részéröl, és mihelyt lehetséges korrigálni fogják.
Néhány példát a 2.6-os alfejezetben a 2.14-es ábrában adunk meg.
UPDATE esetében az oszlop nevek zárójelek közé helyezett
commalist-jének kihagyása egyenértékü egy olyam commalist be-
vitelével, ami a tábla összes oszlopát megadja. ALL a táblában
a /grant opcióval rendelkezö, vagy enélküli/ engedélyezö birto-
kában lévö összes privilégium röviditése. A PUBLIC minden
felhasználót /vagyis minden meghatalmazás azonositót/ jelentö
rövidités.
Megjegyzés: Ha a P privilégium engedélyezve van a PUBLIC számá-
ra, akkor az U felhasználó automatikusan élvezi a P privilégi-
umot még abban az esetben is, ha az U felhasználó a rendszer
számára nem volt ismert az engedély megadásának idején.
sql.doc Page: 36
A GRANT müveletet kiadó felhasználónak /vagyis a tar-
talmazó sémához az AUTHORIZATION klauzula által azonositott
felhasználónak/ vagy /a/ azon tábla tulajdonosának kell lennie,
amelyen a privilégiumok meg vannak adva /vagyis ennek a táblának
ugyanazon sémában létrehozottnak kell lennie/, vagy /b/ meg
kellett kapnia az engedélyt ezen privilégiumok használatára
valamilyen más felhasználótól "with the grant option"-nal /a
grant opcióval/ /lásd lejjebb/. Egyik felhasználó sem engedé-
lyezhet olyan privilégiumot, amely nincs a birtokában.
A grant opció
Ha az A felhasználó számára meg van engedve, hogy engedélyezzen
/grant/ valamilyen P privilégiumot a B felhasználó számára,
akkor /definició szerint/ az A felhasználó számára meg van en-
gedve, hogy engedélyezze ezt a P privilégiumot a B felhaszná-
lónak "with the grant option"-nal /a grant opcióval/ /a GRANT
müveletben a WITH GRANT OPTION klauzula segitségével/. A grant
opcióval egy privilégium engedélyezése azt jelenti, hogy a pri-
vilégiumot átvevö is engedélyezheti /megadhatja/ ugyanezt a
privilégiumot - a grant opcióval vagy anélkül - valamilyen
további felhasználónak /és igy tovább rekurziv módon/.
USER
A USER foglalt szó, ami rendszer változónak /system variable/
/vagy nulla argumentumú beépitett függvénynek/ tekinthetö.
A USER értéke egy karakter füzér, amely azt a meghatalmazás
azonositót reprezentálja, amely azon modul AUTHORIZATION klau-
zulájában van elöirva, ami a USER hivatkozást tartalmazó SQL
utasitásban van. Vizsgáljuk meg a következö példát.
Séma:
CREATE SCHEMA
AUTHORIZATION TED
...
CREATE VIEW MY_PARTS AS
SELECT * FROM P WHERE P.PNO IN
(SELECT SP.PNO FROM SP
WHERE SP.SNO = USER)
...
GRANT ALL ON MY_PARTS TO PUBLIC
Modul:
MODULE M2
AUTHORIZATION S2
...
SELECT *
FROM MY_PARTS ;
Amikor a SELECT müvelet végrehajtásra kerül az M2-es modul-
ban, vissza fogja nyerni azon alkatrészekhez tartozó
alkatrész sorokat, amelyeket az S2-es szállitó szállitott.
A gyakorlatban a USER-t nagyon valószinü, hogy a
GRANT-oknak a PUBLIC számára engedélyezésével kapcsolatban
használják, mint ahogy a példa is sugallja.
sql.doc Page: 37
5
__________ ______ ____ _____ _______ ______ _____________
Adat manipuláció:
A modul nyelv
5.1 SZINTAXIS
Az SQL adatmanipuláló utasitások a host nyelvtöl független mó-
don vannak megadva olyan modulok és eljárások segitségével,
amelyek a modul nyelven iródtak. Ennek a nyelvnek a szintaxisa
a következö:
Modul definició:
::= MODULE [module]
LANGUAGE
AUTHORIZATION user
[cursor-definition-list]
procedure-definition-list
Cursor definició:
::= ....... Lásd a 6. fejezetet.
Eljárás definició:
::= PROCEDURE procedure
parameter-definition-list ;
manipulative-statement ;
Paraméter definició:
::= parameter data-type | SQLCODE
Manipulativ utasitás:
::= close-statement
|commit-statement
|delete-statement-positioned
|delete-statement-searched
|fetch-statement
|insert-statement
|open-statement
|rollback-statement
|select-statement
|update-statement-positioned
|update-statement-searched
Amint a szintaxis jelzi egy modul egy MODULE klauzulá-
ból /opcionálisan specifikálva egy modul nevet/, egy LANGUAGE
klauzulából, mely azt a host nyelvet adja meg, amelyböl a modul
eljárásait meg fogják hivni, egy AUTHORIZATION klauzulából,
nulla vagy több cursor definicióból és egy vagy több eljárásból
áll. Annak a felhasználónak, akinek a meghatalmazás azonositója
az AUTHORIZATION klauzulában meg van adva, birtokolnia kell az
összes szükséges privilégiumot a modulban lévö eljárásokban meg-
adott összes manipulativ utasitáshoz. A cursor definiciók a 6.
fejezetben vannak elmagyarázva; az eljárásokat a következö al-
fejezetben tárgyaljuk.
Egy adott alkalmazáshoz legfeljebb egy SQL modul tartoz-
hat. A két modul közötti kapcsolat /asszociáció/ létrehozásához
a mechanizmus nem meghatározott maradt.
sql.doc Page: 38
5.2 ELJARARASOK. PARAMÉTEREK ÉS MANIPULATIV UTASITASOK
Egy eljárás egy PROCEDURE klauzulából /mely megad egy nevet
az eljáráshoz/ paraméter definiciók listájából /melyek közül
pontosan egynek meg kell adnia az SQLCODE speciális paramétert/
és egyetlen adat manipuláló utasitásból áll. Az eljárás nevek-
nek egyedieknek kell lenniük az öket tartalmazó modulon belül.
Paraméterek
Egy eljárásban minden /SQLCODE-tól eltérö/ paraméter definició
egy paraméter névböl és egy adat tipusból áll. Paramétereket
használunk a következök reprezentálására:
/a/ "Targets" /célok/ /vagyis olyan host program változók,
melyekbe skalár értékeket kell visszanyerni/. Ebben a mi-
nöségében egy paraméter csak INTO klauzula operandusaként
jelenhet meg FETCH vagy SELECT utasitásban.
/b/ A host programból átadott skalár értékek. Ebben a minö-
ségében egy paraméter egy SQL adat manipuláló utasitás-
ban bárhol megjelenhet, ahol literál megjelenhet - vagyis
a következök bármelyikén belül elemként /pontosabban meg-
fogalmazva a következök bármelyikén belül egy aritmeti-
kai kifejezésen belüli elemként, ha a kérdéses paraméter
numerikus/;
- SELECT klauzula /egy visszanyerendö értéket reprezentá-
landó minden kifejezésben, mely tartalmaz ilyen klauzu-
lát /például lekérdezés kifejezésben - lásd a 9. fejeze-
tet;
- WHERE klauzula /egy összehasonlitandó értéket reprezentá-
landó/ SELECT, UPDATE vagy DELETE utasitásban, illetve
cursor definicióban;
- SET klauzula UPDATE utasitásban /egy adatbázis aktualizálá-
sához használandó értéket reprezentálandó/;
- VALUES klauzula INSERT utasitásban /a beszúrandó értéket
reprezentálandó/
Megjegyzés: Bizonyos okok miatt a szabvány nem enged
meg müveleti /operational/ kifejezéseket ezen négy eset
közül az utolsóban. Például, ha X egy numerikus paraméter,
akkor az X kifejezés meg van engedve VALUES klauzulában,
de az X + 1 kifejezés nincs megengedve.
Ha a P eljárás tartalmaz egy S adat manipuláló utasitást,
és S utasitás tartalmaz egy hivatkozást /referenciát/ C osz-
lopra, és a C nem minösitett név ugyanaz, mint a P-ben defini-
ált valamelyik paraméter neve, akkor a C-re hivatkozásnak
minösitettnek kell lennie. Például:
PROCEDURE GET_PART
SQLCODE
PNO .... ;
SELECT * FROM P WHERE P.PNO = PNO ;
sql.doc Page: 39
Itt "P.PNO" egy hivatkozás/referencia/ a P tábla PNO osz-
lopára,a "PNO"/nem ninösitett/ egy hivatkozás a PNO pa-
raméterre.
SQLCODE
Az SQLCODE paraméternek megfelelö argumentumot használjuk
visszatérési kod /mondjuk r /vételére,mely azt jelzi,hogy
mi történt a manipulativ utasitás/mondjuk S/ végrehajtása-
kor. Az r értékeit a következökben definiáljuk:
1.Ha S sikeresen végrehajtodott, akkor:
/a/ Ha S a következök valamelyike volt:
- olyan FETCH,melyhez nem volt következö sor
-olyan SELECT vagy INSERT...SELECT,melyhez nem találta-
tott sor
-searched/keresett/ UPDATE ,melyhez nem tartozott aktua-
lizalando sor
-searched/keresett/ DELETE,melyhez nem tartozott torlen-
dö sor
akkor r értéke +100-ra állitodik.
/b/ Egyébként r értéke 0-ra állitodik.
2.Ha S végrehajtása nem volt sikeres,akkor r egy imp-
lementácio definiálta értékre állitodik/és az adatbázis
változatlan marad/
Paraméter adat tipusok
Egy paraméter adat tipus megadásának/elöirásának/ célja az
implementáció tájékoztatása arról az adat tipusról, amelyet
a megfelelö argumentumhoz várhat a host nyelvböl.Teát az
elöirhato adat tipusok tartománya a kérdéses host nyelv által
támogatott adat tipusok tartományátol függ; nem minden adat
tipus adható meg minden host nyelvhez.A következö táblázat
jelzi ,hogy melyek érvényesek mely hostokhoz.Megjegyzés:
Ebben a táblázatban az SQLCODE arra a host argumentumra
vonatkozik,amely az SQLCODE paraméternek megfelel;az ebben
az oszlopban láthato adat tipusok host adat tipusok.Az
egyeb paraméterek oszlopban leirt adat tipusok az SQL
szabványban definiált adat tipusok.
-------- ----- ------ ----- ----- -----------------
SQLCODE egyeb paraméterek
-------- ----- ------ ----- ----- ----------------
COBOL COMP PIC S9 /pc/ CHARACTER vagy NUMERIC
FORTRAN INTEGER CHARACTER vagy INTEGER
vagy REAL vagy DOUBLE
PRECISION
Pascal INTEGER CHARACTER vagy INTEGER
vagy REAL
PL1 FIXED BIN /pp/ CHARACTER vagy DECIMAL
vagy FLOAT
-------- ----- ------ ----- ----- -----------------
Megjegyzes: a pc és pp értékeknek 4-nél illetve 15-nél na-
gyobb vagy ezzel egyenlö értéknek kell lenniük.
sql.doc Page: 40
Manipulativ utasitások
Az SQL adat manipulácios utasitások három kategoriába sorol-
hatok:
1.Cursor müveletek:
OPEN
FETCH
UPDATE...CURRENT/pozicionált UPDATE/
DELETE...CURRENT/pozicionált DELETE/
CLOSE
2.Nem cursor müveletek:
SELECT
INSERT
UPDATE/keresett UPDATE/
DELETE/keresett DELETE/
3.Tranzakcio befejezési müveletek:
COMMIT
ROLLBACK
A cursor müveleteket és nem cursor müveleteket a 6. ill.
7. fejezetben tárgyaljuk. A COMMIT-ot és ROLLBACK-ot a jelen
fejezet végén, az 5.4-es alfejezetben tárgyaljuk /megfelelöbb
hely hiányában/.
5.3 INDIKATOR PARAMETEREK
A null értékek speciális kezelést igényelnek a modulnyelvben
/mint ahogyan ténylegesen majdnem mindenhol/.Vizsgáljuk meg
a következö eljáráspéldát, mely tartalmaz egy SELECT utasi-
tast:
PROCEDURE GET_WEIGHT
SQLCODE
PNO_PARAM CHAR(6)
WEIGHT_PARAM DECIMAL(3);
SELECT P.WEIGHT
INTO WEIGHT_PARAM
FROM P
WHERE P.PNO =PNO_PARAM ;
Feltételezzük, hogy lehetöség van arra,hogy a WEIGHT/suly/
értéke null legyen valamilyen alkatrészhez /mely tulajdon-
képpen valos eset, mivel NOT NULL nem volt elöirva a WEIGHT
oszlophoz a 2.3 -as ábra sémájában/.A fent láthato SELECT
utasitás sikertelen lesz,ha a kiválasztott WEIGHT null;
az SQLCODE negativ értékre fog állni és a WEIGHT_PARAM
célparaméter egy implementácio definiálta állapotban fog
maradni.Altalában, hogy egy visszanyerendö érték null
legyen,a programozonak meg kell adnia egy indikátor pa-
ramétert a normál cél paraméteren kivül ehhez az értékhez
ugy ,ahogyan most bemutatjuk.
sql.doc Page: 41
PROCEDURE GET_WEIGHT
SQLCODE
PNO_PARAM CHAR(6)
WEIGHT_PARAM DECIMAL(3)
WEIGHT_INDIC DECIMAL(5);
SELECT P.WEIGHT
INTO WEIGHT_PARAM INDICATOR WEIGHT_INDIC
FROM P
WHERE P.PNO=PNO_PARAM;
Ha a visszanyerendö érték null és meg volt adva indikátor
paraméter, akkor ez az indikátor paraméter -1-re/minusz
egyre/fog beállni;ha a visszanyerendö érték nem null,az
indikátor paraméter nem nullára fog beállni. /*/
_____ _______ ______ ______
*Egy kissé túlegyszerüsités. Ha a visszanyerendö érték
nem null és n1 karakter füzér hosszuságu és a cél para-
méter adat tipusa CHARACTER/n2/ és ha n1 nagyobb mint
n2,akkor az indikátor paraméter n1-re áll be.
Az indikátor paraméterek a bemutatott modon vannak megadva
-vagyis a megfelelö szokásos cél paramétert követöen és
ettöl a szokásos paramétertöl az INDICATOR kulcsszoval
elválasztva./pontos számoknak kell lenniük/a pontos adat
tipust az implementácio definiálja.
A Példa bemutatja egy indikátor paraméter használatát
cél paraméterrel együtt.Indikátor paraméterek szokásos
paraméterekkel /vagyis olyan paraméterekkel, melyeket
egyszerüen értékek megadására használunk/ is használ-
hatok.Például az alábbi utasitás
UPDATE P
SET WEIGHT=WEIGHT_PARAM INDICATOR WEIGHT_INDIC
WHERE P.CITY='London'
minden londoni alkatrészhez a súlyt null értéküre fogja
állitani,ha a WEIGHT_INDIC értéke negativ/bármilyen nega-
tiv érték,nem csak minusz egy/.Természetesen ugyanazt fog-
ja tenni az alábbi utasitás is
UPDATE P
SET WEIGHT=NULL
WHERE P.CITY='London'
Megjegyzes:indikátor paraméterek WHERE kauzulában is
használhatok,de valoszinüleg nem szabad öket itt hasz-
nálni.
Példaul még ha a WEIGHT_INDIC értéke negativ is,a
küvetkezö utasitás nem fog visszanyerni alkatrész
számokat olyan alkatrészekhez ,ahol a suly értéke
null./Feladat az olvaso számára:mi az amit tenni fog?/
sql.doc Page: 42
SELECT P.PNO
INTO PNO_PARAM
FROM P
WHERE P.WEIGHT=WEIGHT_PARAM INDICATOR WEIGHT_INDIC
Az alkatrész számok visszanyerésének helyes módja ,ott
ahol a súly értéke null, a következö:
SELECT P.PNO
INTO PNO_PARAM
FROM P
WHERE P.WEIGHT IS NULL
/lásd a 9.fejezetet/
5.4 COMMIT ES ROLLBACK
COMMIT
A COMMIT müvelet az alábbi alakú
COMMIT WORK
Befejezi az aktuális tranzakciót /normál befejezés/.
A tranzakció által végrehajtott minden aktualizálás
megtörténik.Minden megnyitott cursor lezárodik.
ROLLBACK
A ROLLBACK muvelet a kovetkezö alaku:
ROLLBACK WORK
Az aktuális tranzakcio befejezödik./rendellenes befejezés/.
A tranzakcio által végrehajtott minden aktualizálás tör-
lödik.Minden megnyitott cursor lezárodik.
sql.doc Page: 43
6
-------- ----- ------ ----- ----- -----------------
Adat manipulácio
Cursor müveletek
6.1 BEVEZETES
Az adatbázishoz a cursoron alapulo hozzáférés általános is-
mereteit a 2.fejezet 2.4-es alfejezetében magyaráztuk el;
nézze át ezt az alfejezetet,ha szüksége van arra,hogy az
általános ismeretekre felfrissitse emlékezetét.Ebben a fe-
jezetben részletesebben vizsgáljuk meg a cursor müvelete-
ket.Ezek a müveletek a következök/az 5.2-es alfejezetböl
megismételve/:
OPEN
FETCH
UPDATE...CURRENT/pozicionált UPDATE/
DELETE...CURRENT/pozicionált DELETE/
CLOSE
A 6.2-es alfejezet elmagyarázza,hogy pontosan mi is
egy cursor és mi az,ami szerepet játszik egy cursor defi-
niálásában. A 6.3-as fejezet ezt követöen részletesen tár-
gyalja az öt cursor müveletet.Megjegyzés:oktatási okok mi-
att számos egyszerüsitö feltételezést teszünk ebben a
fejezetben mindenhol,nevezetesen a következöket:
- elöször is feltételezzük,hogy minden tábla alaptábla;
a nézetekre érvényes speciális szempontok ismertetését
a 8.fejezetre halasztjuk
- másodszor feltételezzük,hogy a felhasználó rendelkezik
az összes olyan privilégiummal, melyre szükség van a
kérdéses müveletek végrehajtásához
- harmadszor,/nagyrészt/ figyelmen kivül hagyjuk a hibák
lehetöségét;vagyis figyelmen kivül hagyjuk azt a lehe-
töséget, hogy bármilyen integritási elöirás megszegés
bekövetkezhet;vagyis feltételezzük,hogy semmilyen ki-
sérlet nem történik null érték bevitelére, olyan osz-
lopba, melyhez null-ok nincsenek megengedve, vagy olyan
sor bevitelére, ami megszegi egy oszlop egyedi jellegére
vonatkozo követelményt,vagy egy oszlopba olyan érték
bevitelére, melynek az adat tipusa nem megfelelö
- végül nem teszünk kisérletet arra,hogy elmagyarázzuk
nagy általánosságban a lekérdezés kifejezéseket /lásd
a következö alfejezetben a cursor definiálás cimü leirást/
ezt a magyarázatot a 9. fejezetre halasztjuk
sql.doc Page: 44
6.2 CURSOROK
Egy cursor lényegében egyfajta pointer,mely sorok rendezett
gyüjteményén futtathato végig;amely gyüjteményben a sorok
mindegyikére sorban rámutat és igy a sorok számára egyenkénti
cimezhetöséget biztosit.Ha a C cursor az R sorra mutat,azt
mondjuk,hogy az R sorra van pozicionálva.Az R sor ilyenkor
aktualizálható vagy törölhetö az UPDATE és DELETE müveletek
pozicionált alakján keresztül/UPDATE/DELETE...WHERE CURRENT
OF C/.Más szavakkal fogalmazva a pozicionált UPDATE vagy
DELETE esetén a cursornak on /aktiv/ állapotban kell lennie.
/Ez a megjegyzés természetesen feltételezi, hogy elöször is
az aktualizálások meg legyenek engedve a cursoron keresztül;
lásd késöbb a jelen fejezetben/.
Minden cursorhoz tartozik egy lekérdezés/query/,mely a cur-
sort definiáló müvelet részeként van megadva.A lekérdezés
paraméteresithetö.Például:
DECLARE X CURSOR
FOR SELECT SP.SNO,SP.QTY
FROM SP
WHERE SP.PNO=PNO_PARAM
ORDER BY SP.SNO
Ez a DECLARE definiál egy X nevü cursort a hozzátartozo
lekérdezéssel együtt úgy, ahogyan ezt a "SELECT...PNO_PARAM"
/ahol PNO_PARAM egy paraméter/ kifejezés definiálja.Ennek
a lekérdezésnek a végrehajtása ekkor még nem történik meg;
a DECLARE CURSOR tisztán deklarativ müvelet.A lekérdezés
tényleges végrehajtása akkor történik,amikor az X cursort
megnyitják/lásd a 6.3 -as fejezetet/;ha a lekérdezés pa-
raméteresitve van,az ezen paramétereknek megfelelö argu-
mentumokat abban az eljárásban kell megadni,amelyik az
OPEN-t végrehajtja.A lekérdezés végrehajtásábol származó
sorok gyüjteménye az OPEN uán kapcsolatban van a cursorral
és ez igy is marad mindaddig,amig a cursor ujra le nem
zárodik/lásd a 6.3-as fejezetet/.
Ezenkivül a sorok ezen gyüjteménye "rendezett"./lásd az
ORDER BY leirását a jelen alfejezet végén/.
Ezért tehát miközben nyitott egy cursor sorok bizonyos
rendezett gyüjteményét jelöli ki, valamint egy bizonyos
specifikus poziciót is kijelöl ezen rendezéshez viszonyit-
va.A lehetséges poziciók a következök:
- valamilyen specifikus soron/on/-/on állapot/
- valamilyen specifikus sor elött/before/-/before állapot/
- az utolso sor után/after/-/after last állapot/
Az OPEN a cursort az elsö sor elé helyezi.A FETCH a
cursort a következö sorra,vagy ha nincs következö sor az
utolso sor utáni helyre helyezi.Ha a cursor valamelyik
soron van vagy valamelyik sor elött van és ez a sor
törlödik a cursor a következö sor elé vagy ha nincs
következö sor az utolso sor után helyezödik át.
Megjegyezzük,hogy a cursor az elsö sor elött vagy
az utolso sor után lehet elhelyezve,még abban a speci-
sql.doc Page: 45
ális esetben is,amikor a sorok gyüjteménye üres.
Megjegyzés:ez a szakasz a szabvány által elöirt
helyváltoztatásokkal/pozició áthelyezés/ foglalkozik.
Lehetségesek mások is ,vagy egyáltalán nem emliti a
szabvány vagy legjobb esetben implementácio definiálta
állapotként hagyja. Megjegyzés vége.
Minden cursor lezárt /zárt/ állapotban van a tranzakcio
elején és zárt állapotban/ha nyitva van/ kényszeritödik a
tranzakcio befejezésekor.Azonban a tranzakcio inditás
és tranzakcio befejezés között ugyanaz a cursor számos
alkalommal megnyithato és lezárhato/estleg külömbözö
alkalmakkor eltérö paraméter értékekkel és ezért külömbözö
kapcsolatba hozott sorgyüjteményekkel/.
Cursor definiálása
Emlékezzünk vissza az 5. fejezetre,ahol a cursorok egy
modul specifikácio részeként vannak definiálva/bármilyen
eljárás elött,mely ezen cursorokat használhatja/.Egy adott
modulban minden egyes cursor definiciohoz pontosan egy
eljárásnak kell tartoznia ebben a modulban,melynek a
feladata a kérdéses cursor OPEN-je/megnyitása/.Egy cursor
definialásának szintaxisa:
DECLARE cursor CURSOR FOR query-expression
/order-by-clause/
Már megadtunk egy példát a jelen alfejezethez.A
query-expression részleteit lásd a 9. fejezetben;ebben
a fejezetben általánosságban feltételezni fogjuk, hogy
ez egyszerüen egy SELECT /lekérdezés/ anélkül,hogy
kisérletet tennénk arra,hogy formálisan definiáljuk ezt
a kifejezést/,plusz egy opcionális ORDER BY klauzula.
A lekérdezés kifejezés célja azon sorok gyüjteményének
/együttesének/definiálása,amelyek elérhetöek lesznek
a cursoron keresztül,amikor a cursor meg van nyitva.A
sorok ezen gyüjteménye a cursoron keresztül aktualizál-
ható lesz/vagyis úgymond a cursor aktualizalható lesz/
the cursor will be updatable/,hogy egy pontatlan,de
általánosan elterjedt kifejezést használjunk/,akkor
és csakis akkor ,ha az alábbi a/,b/,c/ pontok közül
mind a három érvényes:
a/ A lekérdezés kifejezés nem tartalmaz UNION-t,más
szavakkal ez lényegében egy lekérdezés specifikácio
/query specification//lásd a 9.2 fejezetet/;
b/ Ez a lekérdezés specifikácio egy aktualizálhato né-
zetet definiálna,ha egy nézet definicio környezetében
jelenne meg/lásd a 8.4-es alfejezetet/;
c/ A cursor definicio nem tartalmaz ORDER BY-t.
Amikor a cursor megnyitásra kerül /és nem elötte/
a SELECT /lekérdezés/ kifejezés kiértékelödik és ál-
talában egy többsoros táblát eredményez.Az ORDER BY
sql.doc Page: 46
klauzula elöir egy rendezést a létrejött tábla sora-
ihoz;ha nincs megadva ilyen klauzula ,a sorok rende-
zését az implementácio definiálja.Az alábbiakban meg-
adunk egy példát egy eljárásra amely egy cursort nyit
meg:/lásd továbbá a 6.3-as alfejezetben/:
PROCEDURE OPENX
SQLCODE
PNO_PARAM CHAR(6);
OPEN X ;
Jegyezze meg,hogy egy adott cursor definiciojában
szereplö minden paraméternek definiáltnak kell lennie
abban az eljárásban, ami ezt a cursort megnyitja.
Az ORDER BY klauzula
Az ORDER BY klauzula a következöképpen van definiálva:
order-by-clause
::= ORDER BY ordering-specification-commalist
ordering-specification
::= (integer | column reference ) ( ASC | DESC)
Az oszlop referencia egyszerüen egy minösitett vagy
nem minösitett oszlop név,az ORDER BY klauzulában a ren-
dezési elöirások balról jobbra sorrendje megegyezik a
nagyobbtól kisebb felé rendezéssel,a szukásos konvenciok-
kal összhangban.Rendszerint minden ilyen specifikácio
/megadás/ oszlop névböl, opcionális minösitöböl és
ASC vagy DESC / ASC növekvö sorrendet és DESC csökkenö
sorrendet jelent;ASC az alapértelmezés/opcionális spe-
cifikáciojábol áll.Más változatként egy rendezési elö-
irás elöjel nélküli integerböl is állhat,mint a követ-
kezö példában:
DECLARE Y CURSOR
FOR SELECT SP.PNO.AVG (SP.QTY)
FROM SP
GROUP BY SP.PNO
ORDER BY 2
Az integer az eredmény táblában az oszlop sorrend
szerinti/balról jobbra/ helyére utal. Ez a jellemzö le-
hetövé teszi az eredmény tábla rendezését olyan eredmény
oszlop alapján,amely egy egyszerü megnevezett oszloptol
eltérö valami másbol származik,és ebböl következöen nincs
saját neve.A példában a "2" az átlagok oszlopára utal.
Megjegyzés:a rendezési elöirásoknak integereknek,nem
pedig neveknek kell lenniük,ha a cursor definicio UNION-t
tartalmaz /lásd a 9. fejezetet/.
Megjegyezzük, hogy /mint ahogy már jeleztük/ minden egyes
rendezési elöirásnak azonositania kell az eredmény tábla
/ result table/ egy oszlopát. Igy például az itt következö
sql.doc Page: 47
*** ILLEGAL *** /nincs megengedve/:
DECLARE Z CURSOR
FOR SELECT S.SNO
FROM S
ORDER BY S.CITY
6.3 CURSORON ALAPULO MANIPULACIOS
OPEN
Az OPEN utasitás a következö alakú
OPEN cursor
ahol "cursor" azonosit egy cursort /mondjuk C-t/. A C cur-
sornak zárt állapotban kell lennie. A C definicio-
ban lévö lekérdezés kifejezés kiértékelödik, aktuális érté-
keket használva az ezen lekérdezés kifejezésben hivatkozott
minden paraméterhez, a sorok gyüjteményének elöállitására.
Ez a gyüjtemény /készlet/ rendezett a 6.2-es alfejezet vé-
gén leirtak szerint. A C cursor nyitott állapotu lett
és ezen rendezett gyüjtemény /halmaz elsö sora
elé mutat (van pozicionálva).
Példa:
OPEN X
FETCH
A FETCH utasitás a következö alakú
FETCH cursor INTO target-commalist
ahol "cursor" azonosit egy cursort /mondjuk C-t/, és minden
"target" /célnak/ az alábbi alaku
parameter [ [ INDICATOR ] parameter ]
/vagyis egy cél paraméterböl áll egy opcionálisan hozzá-
tartozo indikátor paraméterrel együtt - lásd az 5.3-as
alfejezetet/. A cél commalist-nek pontosan egy célt kell
tartalmaznia a C cursor definiciojában a SELECT klauzulá-
ban lévö minden kifejezéshez. A célok commalist-jében az
i-edik bejegyzés által azonositott cél a C cursor defini-
ciójában a SELECT klauzulában az i-edik kifejezésnek felel
meg.
A C cursornak nyitottnak kell lennie. Ha
nincs köcetkezö sor az éppen a C cursorhoz tartozó sorok
rendezett gyüjteményében /ezen rendezésben a C aktuális
poziciojához viszonyitva/ semmilyen adat visszanyerés nem törté-
nik; egyébként a C cursor a következö sorra pozicionálodik,
ebböl a sorbol az értékek visszanyerödnek és a célokhoz (paraméterek)
értékadások történnek az INTO kauzulában lévö elöirások-
kal összhangban.
Jegyezze meg, hogy a FETCH logikailag egy "fetch next"
sql.doc Page: 48
/következö betöltése/ müvelet. Azt is jegyezze meg, hogy
"fetch next" az egyetlen cursor elmozditási müvelet; nem le-
hetséges a cursornak /például/ "három pozicioval elöre" vagy
"két pozicioval hátra" vagy "közvetlen az n-edik sorhoz",
stb. mozgatása /de nézze át a 12. fejezetet/.
Példa:
FETCH X INTO SNO_PARAM, QTY_PARAM INDICATOR QTY_INDIC
UPDATE /pozicionált/
A pozicionált UPDATE utasitás a következö alaku
UPDATE table
SET assignment-commalist
WHERE CURRENT OF cursor
ahol "table" egy táblát /mondjuk T/ azonosit és "cursor" egy
cursort /mondjuk C-t/ azonosit és minden értékadás
column =
alakú. Minden ilyen értékadás baloldalán a "column"-nak /osz-
lopnak/ a T tábla egy oszlopa nem minösitett nevének kell len-
nie. A C cursornak nyitottnak, "aktualizálható"-nak kell lennie,
és a T táblázat egyik sorára kell pozicionálódnia. A SET klauzu-
lában minden egyes értékadáshoz a skalár kifejezés kiszámitásá-
nak eredménye, vagy nulla érték, ha NULL van elöirva rendelödik
hozzá a jelzett oszlophoz. A skalár kifejezésben a T tábla
oszlopaira történö hivatkozások a cursor poziciója által ki-
jelölt sor megfelelö oszlopában az eredeti /az UPDATE végre-
hajtása elötti/ értéket jelentik.
Megjegyzés: A "scalar expression" /skalár kifejezés/
szintaxisát a 9. fejezetben /9.3-as alfejezet/ adjuk meg.
A 3. fejezetben leirtak szerint ennek általános célja vala-
milyen skalár érték kijelölése. A most tárgyalt speciális
összefüggésben, az ilyen kifejezésnek nem szabad tartalmaz-
nia semmilyen hivatkozást a beépitett függvények /COUNT,
SUM, AVG stb./ egyikére sem.
Példa:
UPDATE SP
SET QTY = SP.QTY + INCR_PARAM
WHERE CURRENT OF X
Megjegyzés: a szabvány nem adja meg, mi történik, ha a
pozicionált UPDATE megváltoztatja az aktualizált sor
helyzetét a cursorhoz tartozo rendezéshez viszonyitva.
A példában például mi történik, ha SP sorokat történe-
tesen növekvö QTY értékek szerint kell rendezni? Meg-
jegyzés vége.
sql.doc Page: 49
DELETE /pozicionált/
A pozicionált DELETE utasitás a következö alakú
DELETE
FROM table
WHERE CURRENT OF cursor
ahol "table" azonosit egy táblát /mondjuk T/ és "cursor"
azonosit egy cursort /mondjuk C/. A C cursornak nyi-
tottnak kell lennie, "aktualizálhatonak" kell lennie és a
T tábla egyik sorára kell pozicionálodnia. Ez a sor törlödik.
Példa:
DELETE
FROM SP
WHERE CURRENT OF X
Az X cursor ezután közvetlenül az éppen törölt sort követö sor
elött fog elhelyezkedni, vagy az utolso sor után, ha nem
létezik ilyen közvetlenül követö sor.
CLOSE
A CLOSE utasitásnak az alábbi alakja van
CLOSE cursor
ahol "cursor" egy cursort /mondjuk C/ azonosit. A C cursort
/amelynek nyitottnak kell lennie/ zárt állapotba
helyezi.
Példa:
CLOSE X
6.4 EGY GLOBALIS PÉLDA
A fejezetet egy képzeletbeli, de átfogó példával /6.1-es ábra/
fejezzük be, amely bemutatja, hogy az ebben a fejezetben /és
a korábbi fejezetekben bevezetett elgondolások közül számos
elgondolás hogyan illeszkedik egymáshoz. A host program
/mely PL/I-ben van irva/ négy input értéket fogad: alkatrész-
számot /GIVENPNO/, város nevet /GIVENCIT/, állapot növek-
ményt /GIVENNINC/ és állapot szintet /GIVENLVL/. A program
letapogatja /átvizsgálja/ az összes olyan alkatrész szálli-
tóját, melyet a GIVENPNO azonosit. Minden ilyen szállitóhoz,
ha a szálitóhoz tartozó város GIVENCIT, az állapotot meg-
növeli a GIVENINC-vel; egyébként ha az állapot kisebb, mint
GIVENLVEL, törli a szállitót, az ehhez a szállitóhoz tartozó
összes szállitmánnyal együtt. Minden esetben listázza a
szállitó információit a nyomtatón, annak jelzésével, hogy
a kérdéses szállitót hogyan kezelte a program.
1. megjegyzés: Mindenhol figyelmen kivül hagytuk azt a
lehetöséget, hogy valamilyen visszanyerendö érték null le-
sql.doc Page: 50
het. Ezt az egyszerüsitést tisztán a példa méretének a csök-
kentésére vezettük be.
2. megjegyzés: A bemutatott utasitások közül néhányat
eddig még nem tárgyaltunk részletesen. Vagyis az UPDATE és
DELETE utasitások "keresett" változatok, nem pedig "pozici-
onált" változatok. Az ilyen utasitások általános leirása a
2. fejezetben található; a részleteket a 7. fejezet adja meg.
3. megjegyzés: Figyelje meg, hogy az aktuális S sor
aktualizálásához/törléséhez az UPDATE és DELETE utasitások-
nak /lásd az UPDATE_PROC és a DELETE_S_PROC eljárásokat/
a keresett változatnak kell lenniük, nem pedig a pozicionált
változatnak, jóllehet tulajdonképpen a Z cursor pontosan azon
a soron helyezkedik el, amelyet aktualizálni/törölni óhajtunk.
Ennek az az oka, hogy a Z cursor "nem aktualizálható"; vagyis
a Z cursor definiciója olyan, hogy megtiltja a Z-n keresztüli
aktualizálásokat /mivel ez tartalmaz egy al-lekérdezést/.
Lásd a 6.2 fejezetet.
4. megjegyzés: bbbbbbb-t használunk hét blankból álló fü-
zér reprezentálására. /6.1-es ábra, az eljárás kód 15. sora/,
6.1. ábra. Globális /átfogó/ példa
/A program megjegyzéseknek csak a forditása látható, a forditó
megjegyzése/
PLIEX: PROC OPTIONS (MAIN) ;
/* program input */
DCL GIVENPNO CHAR(6);
DCL GIVENCIT CHAR(15);
DCL GIVENINC DECIMAL(3);
DCL GIVENLVL DECIMAL(3);
/* célok a "FETCH SUPPLIER"-hez */
DCL SNO CHAR(5);
DCL SNAME CHAR(20);
DCL STATUS DECIMAL(3);
DCL CITY CHAR(15);
/* housekeeping változók */
DCL DISP CHAR(7)
DCL MORE_SUPPLIERS BIT (1);
/* SQL visszatérési kód változó */
DCL RETCODE FIXED BINARY(15);
/* SQL belépési pont deklarációk, alfabetikus sorrendben */
DCL CLOSE_PROC ENTRY (FIXED BINARY(15));
DCL COMMIT_PROC ENTRY (FIXED BINARY(15));
DCL DELETE_S_PROC ENTRY (FIXED BINARY(15), CHAR(5));
DCL DELETE_SP_PROC ENTRY (FIXED BINARY(15), CHAR(5));
DCL FETCH_PROC ENTRY (FIXED BINARY(15), CHAR(5);
CHAR(20),
DECIMAL(3),
CHAR(15));
DCL OPEN_PROC ENTRY (FIXED BINARY(15), CHAR(6));
DCL ROLLBACK_PROC ENTRY (FIXED BINARY(15), ;
DCL UPDATE_PROC ENTRY (FIXED BINARY(15), CHAR(5),
DECIMAL(3));
/* adatbázis kivételes állapot kezelö */
ON CONDITION (DBEXCEPTION)
BEGIN ;
sql.doc Page: 51
PUT SKIP LIST (RETCODE) ;
CALL ROLLBACK_PROC (RETCODE) ;
PUT SKIP LIST (RETCODE) ;
GO TO QUIT ;
END ;
/* fö program logika */
GET LIST (GIVENPNO, GIVENCIT, GIVENINC, GIVENLVL) ;
CALL OPEN_PROC (RETCODE, GIVENPNO) ;
IF NOT (RETCODE = 0)
THEN SIGNAL CONDITION (DBEXCEPTION) ;
MORE_SUPPLIERS = '1'B ;
DO WHILE (MORE_SUPPLIERS) ;
CALL FETCH_PROC (RETCODE, SNO, SNAME, STATUS, CITY) ;
SELECT ; /* PL/I SELECT, nem pedig SQL SELECT */
WHEN (RETCODE = 100)
MORE_SUPPLIERS = '0'B ;
WHEN NOT (RETCODE = 100 | RETCODE = 0)
SIGNAL CONDITION ( DBEXCEPTION );
WHEN (RETCODE = 0)
DO ;
DISP = 'bbbbbbb' ;
IF CITY = GIVENCIT
THEN
DO ;
CALL UPDATE_PROC (RETCODE,SNO, GIVENINC) ;
IF NOT (RETCODE = 0)
THEN SIGNAL CONDITION (DBEXCEPTION );
DISP = 'UPDATED' ;
END ;
ELSE
IF STATUS < GIVENLVL
THEN
DO ;
CALL DELETE_SP_PROC (RETCODE, SNO);
IF NOT (RETCODE = 0 | RETCODE = 100)
THEN SIGNAL CONDITION (DBEXCEPTION );
CALL DELETE_S_PROC (RETCODE, SNO) ;
IF NOT ( RETCODE = 0 )
THEN SIGNAL CONDITION (DBEXCEPTION);
DISP = 'DELETED' ;
END ;
PUT SKIP LIST
(SNO, SNAME, STATUS, CITY, DISP);
END ; /* WHEN RETCODE = 0 ... */
END ; /* PL/I SELECT */
END ; /* DO WHILE */
CALL CLOSE_PROC (RETCODE);
CALL COMMIT_PROC (RETCODE);
QUIT: RETURN ;
END ; /* PLIEX */
MODULE SQLEXMOD LANGUAGE PLI AUTHORIZATION CJDATE
DECLARE Z CURSOR FOR
SELECT S.NO, S.NAME, S.STATUS, S.CITY
FROM S
WHERE S.SNO IN
sql.doc Page: 52
(SELECT SP.SNO
FORM SP
WHERE SP.PNO = PNO) -- PNO egy paraméter
PROCEDURE CLOSE_PROC
SQLCODE ;
CLOSE Z ;
PROCEDURE COMMIT_PROC
SQLCODE ;
COMMIT WORK ;
PROCEDURE DELETE_S_PROC
SQLCODE
SNO CHAR(5);
DELETE FROM S WHERE S.SNO = SNO ; -- "keresett DELETE"
PROCEDURE DELETE_SP_PROC
SQLCODE
SNO CHAR(5);
DELETE FROM SP WHERE SP.SNO = SNO -- "keresett DELETE"
PROCEDURE FETCH_PROC
SQLCODE
SNO CHAR(5)
SNAME CHAR(20)
STATUS DECIMAL(3)
CITY CHAR(20);
FETCH Z INTO SNO, SNAME, STATUS, CITY ;
PROCEDURE OPEN_PROC
SQLCODE
PNO CHAR(6);
OPEN Z ;
PROCEDURE ROLLBACK_PROC
SQLCODE ;
ROLLBACK WORK ;
PROCEDURE UPDATE_PROC
SQLCODE
SNO CHAR(5)
GIVENINC DECIMAL(3);
UPDATE S
SET STATUS = S.STATUS + GIVENINC
WHERE S.SNO = SNO ; -- "keresett UPDATE"
sql.doc Page: 53
7
-------- ----- ------ -------- ----- ------ ----
Adat manipuláció:
Nem cursor müveletek
7.1 BEVEZETÉS
A nem cursor manipulativ müveletek a következök:
SELECT
INSERT
UPDATE /keresett/
DELETE /keresett/
Ugyanúgy, mint a 6. fejezetben, számos feltételezést
teszünk /lényegében ugyanazokat, mint abban a fejezetben/ az
elöadás mód egyszerüsitése érdekében:
- Minden tábla alap tábla
- A felhasználó rendelkezik az összes szükséges privilé-
giummal
- Nem fordulnak elö hibák.
A lekérdezés kifejezések és az azzal kapcsolatos dolgok magya-
rázatát továbbra is a 9. fejezetre halasztjuk.
7.2. SELECT
Elöször is néhány figyelmeztetö szó azoknak az olvasoknak
célozva, akik esetleg már valamennyire ismerik az SQL nyel-
vet: a nem cursoros SELECT müvelet a szabványos SQL-ben nem a
teljesen általános /SET szintü/ SELECT müvelet, amelyet már
valószinüleg ismernek. Ehelyett ez az amit esetenként "szingli"
SELECT-nek nevezünk, vagyis olyan SELECT, ami legfeljebb
egy sort nyer vissza. Például:
SELECT P.WEIGHT, P.COLOR
INTO WEIGHT_PARAM, COLOR_PARAM
FROM P
WHERE P.PNO = 'P4'
Hiba, ha a tábla, mely a SELECT-FROM-WHERE kiértékeléséböl
származik, egynél több sort tartalmaz. Az alábbiakban meg-
adunk további érvényes példákat:
SELECT *
INTO SNO_PARAM, SNAME_PARAM, STATUS_PARAM, CITY_PARAM
FROM S
WHERE S.SNO = 'S1'
SELECT AVG (SP.QTY)
INTO AVG_QTY_PARAM
FROM SP
SELECT MAX (SP.QTY) - MIN (SP.QTY)
INTO ARITH_PARAM
FROM SP
sql.doc Page: 54
WHERE SP.PNO = 'P4'
Az általános szintaxis:
SELECT [ALL | DISCINT] selection
INTO target-commalist table-expression
ahol:
/a/ Ha sem DISTINCT sem pedig ALL nincs megadva, alapértel-
mezés szerint ALL használata történik.
/b/ Legyen T! a megadott tábla kifejezés kiértékeléséböl
/kiszámitásából származó tábla; legyen T2 az a tábla,
amelyik a T1-hez megadott "selection" /kiválasztás/
kiértékelésével a T1-böl származik; és legyen T3 az a
tábla, amelyik a T2-böl származik /ha DISTINCT
meg van adva/ a redundáns ismétlödö sorok kihagyásával,
vagy egyébként egy olyan tábla, amely azonos T2-vel.
A T3 táblának legfeljebb egy sort szabad tartalmaznia.
/c/ Ha T3-as tábla tartalmaz egy sort, visszanyeri ezt a
sort. Ha T3-as tábla nem tartalmaz sort, "not found"
/nem található/ kivételes állapot jön létre /SQLCODE
plusz 100-ra állitódik. Ha a T3-as táblázat egynél több
sort tartalmaz, hiba keletkezik /SQLCODE negativ érték-
re áll/.
/d/ A "selection" /kiválasztás/ vagy skalár kifejezések
commalist-je /mindegyik általában, de nem szükségképpen,
a T egy vagy több oszlopát tartalmazza/, vagy egyetlen
csillag /"*"/. A csillag olyan commalist röviditése,
mely a T1 tábla minden oszlopát megadja ezen táblán belül
balról jobbra sorrendben. /Más szavakkal ebben az eset-
ben a T2-es tábla azonos T1-es táblával/.
/e/ Az INTO klauzula pontosan ugyanaz, mint FETCH esetén
/lásd a 6.3-as alfejezetet/.
/f/ A tábla kifejezés egy FROM klauzulából és egy opcioná-
lis WHERE klauzulából áll. Megjegyzés: általában egy
táblakifejezés GROUP BY klauzulát és/vagy HAVING klau-
zulát is tartalmazhat /lásd a 9.5-ös alfejezetet/, de ebben
a speciális környezetben ezek a klauzulák nincsenek
megengedve.
Megjegyzések:
1. Az SQL szabvány a "table expression" /tábla kife-
jezés/-t használja arra, hogy a következö alaku kons-
trukcióra hivatkozzon
FROM ...
[WHERE ...]
[GROUP BY]
[HAVING ...]
Azonban félrevezetö dolog tábla kifejezésnek nevezni
ezt a konstrukciót, mivel ez azt sugallja, hogy egy
ilyen kifejezés az egyetlen konstrukció a nyelvben,
amely tábla értéket reprezentál. Tulajdonképpen minden
lekérdezés tábla értékü /ez a tény a relációs
modell jól ismert lezárási /closure/ tulajdonságából
következik és nagyon fontos. Vagyis egy "selest-expres-
sion" /SELECT kifejezés/ tábla értékü. /*/ Egy SELECT-
sql.doc Page: 55
expression egyszerüen speciális esete egy lekérdezés
kifejezésnek; egy SELECT klauzulából áll, melyet tábla
kifejezés /ezen kifejezés fenti - kifogásolt - értelmé-
ben/ követ. Más szavakkal megfogalmazva, a teljes
SELECT utasitás alapvetöen egyszerüen egy SELECT-expres-
sion /kifejezés/ és mint ilyen természetesen tábla ér-
tékü.
----- ----- -----
* Emlékezzen vissza a 6. fejezetböl arra, hogy a "SELECT-
expression" /SELECT kifejezés/ nincs /és nem is lesz/ formá-
lisan definiálva. Egyszerüen csak olyan informális kifejezés-
ként használjuk, melynek a jelentését intuitiv módon nyil-
vánvalónak vesszük. Ezt a megközelitést egyszerüen azért al-
kalmazzuk, hogy elkerüljük azt, hogy a könyvben tul korán
merüljünk bele a lekérdezés kifejezések teljes bonyolultságába.
2. Jegyezze meg, hogy a "selection" vagy skalár kife-
jezések commalist-jéböl vagy egyetlen csillagból áll,
nem pedig ezek együtteséböl. Igy a következö
*** ILLEGAL *** /nincs megengedve/:
SELECT *, (SP.QTY / 12)
INTO ...
FROM SP
WHERE SP.SNO = 'S1'
AND SP.SNO = 'P1'
DB2-ben ez meg van engedve /mint ahogyan ennek igy is
kell lennie/.
3. Jegyezze meg, hogy a csillag nem lehet minösitett.
Igy például a következö *** ILLEGAL *** /nincs megen-
gedve/ :
SELECT S.*, SP.QTY
INTO ...
FROM S.SP
WHERE S.SNO = 'S1'
AND SP.SNO = 'S1'
AND SP.PNO = 'P1'
DB2-ben ez meg ven engedve /ennek igy is kell lennie/.
4. Nincs megengedve, hogy egy SELECT klauzula tartal-
mazza a DISTINCT kulcsszót egynél többször /tekintet
nélkül arra, hogy a klauzula SELECT utasitásban, vagy
bármilyen más környezetben jelenik meg/. Igy például a
következö meg van engedve :
SELECT DISTINCT SP.PNO ...
és az alábbi is meg van engedve
SELECT SP.PNO, SUM (DISTINCT SP.QTY) ...
de a következö *** ILLEGAL *** nincs megengedve:
SELECT DISTINCT SP.PNO, SUM DISTINCT SP.QTY ...
és az alábbi sem:
SELECT SUM (DISTINCT SP.QTY), AVG (DISTINCT SP.QTY)...
Megjegyzés vége.
sql.doc Page: 56
7.3 INSERT
Az INSERT utasitást egy táblához uj sorok hozzáadására hasz-
náljuk. Az alábbiakban két példát adunk meg: az elsö egyetlen
sort szur be /insert/, a második több sort szur be. A máso-
dik példához feltételezzük, hogy van egy további TEMP nevü
táblánk, SNO és CITY oszlopokkal /ahol a TEMP.SNO és TEMP.CITY
oszlopok adat tipusai kompatibilisek az S.SNO illetve S.CITY
oszlopok adat tipusaival/.
INSERT
INTO S (SNO, CITY, SNAME)
VALUES (SNO_PARAM, NULL, SNAME_PARAM)
INSERT
INTO TEMP (SNO, CITY)
SELECT S.SNO, S.CITY
FROM S
WHERE S.STATUS > STATUS_PARAM
Az általános szintaxis:
INSERT INTO table[(column-commalist)] source
ahol "table" /tábla/ azonositja a cél táblát, a zárójelek
közé zárt azonositók azonositják ezen tábla oszlopai közül
valamelyiket, vagy mindegyiket /a nem minösitett oszlop ne-
veikkel/ és a "source"-t /forrást/ az alábbiakban magyarázzuk
el. Az oszlopnevek zárojelek közé helyezett "commalist"-
jének kihagyása egyenértékü a cél tábla minden oszlopa meg-
adásával, a táblán belüli balról jobbra sorrendben.
Egy INSERT utasitásban a "source" vagy egy lekérdezés
specifikáció /nem pontosan megfogalmazva, egy SELECT kifeje-
zés; a részleteket lásd a 9, fejezetben/, vagy a következö
alaku VALUES klauzula
VALUES (insert-atom-commalist)
ahol viszont az egyes "insert atom"-ok értéke vagy egy expli-
cit null érték /melyet a NULL kulcsszó reprezentál/, vagy egy pa-
raméter /opcionális indikátor paraméterrel/. /*/
----- ----- ------
* EZ az USER "system variable" /rendszer változó/ is lehet
/Lásd a 4.3 alfejezetet/.
Magyarázat:
1. Ha egy INSERT utasitás oszlop nevek olyan explicit
commalist-jét tartalmazza, mely egy vagy több oszlopot ki-
hagy a T cél táblából, akkor bármely sor, melyet ez az utasi-
tás visz be a T-be, egy null értéket fog tartalmazni minden ilyen
kihagyott oszlop helyen.
2. Ha az INSERT utasitás tartalmaz egy VALUES klauzulát,
akkor egyetlen sor kerül beszurásra a cél táblába. A VALUES
klauzulában az i-edik "atom" azon i-edik bejgyzés által azo-
sql.doc Page: 57
nositott oszlop helyre tevödik el, amely az INTO klauzulá-
ban lévö oszlop nevek commalist-jében van /explicit vagy im-
plicit módon/.
3. Ha az INSERT utasitás tartalmaz egy lekérdezés speci-
fikációt, akkor a cél táblába /általában/ több sort szur be.
A lekérdezési elöirás /specifkáció/ kiértékelésre kerül az
R közbensö eredmény tábla létrehozására. Az R minden sora
viszont ugy kezelödik, mintha az ebben a sorban lévö skalár ér-
tékek "atomokként" lennének megadva az INSERT utasitás egy so-
ros verziójában egy VALUES klauzulában.
Megjegyzés: Felhivjuk az olvasó figyelmét két megszigo-
ritásra /mindkettö az IBM SQL-böl származó maradvány/:
1. Elöször figyelje meg, hogy /mint ahogyan az 5.2-es
alfejezetben megjelenitettük/ az olyan müveleti kifeje-
zések, mint például PARAM + 1 nincsenek megengedve VALUES
klauzulában.
2. Ha az INSERT utasitás tartalmaz egy lekérdezés spe-
cifikációt, az INSERT T cél táblájára nem szabad hivat-
kozni semmilyen FROM klauzulában ezen lekérdezés specifi-
káción belül. Igy például a következö *** ILLEGAL ***
/nem megengedett/ :
INSERT
INTO T
SELECT *
FROM T
/Még akkor is, ha a T tábla megengedi az ismétlödö sorokat/.
Megjegyzés vége.
7.4 KERESETT UPDATE
A keresett UPDATE utasitást használjuk sorok aktualizálására
egy táblában cursor használata nélkül. Az aktualizalas több
soros /általában/; vagyis az utasitás egyetlen müveletben
nulla, egy, kettö ... vagy bármilyen számu sort aktualizál.
Az alábbiakban megadunk egy példát /a 2. fejezetböl vett példa
egy variációja/:
UPDATE S
SET STATUS = 2 * S.STATUS
WHERE S.CITY = CITY_PARAM
Az általános szintaxis:
UPDATE table
SET assigment-commalist
[WHERE search-condition]
ahol "table" a cél táblát azonositja, az értékadások comma-
listje pontosan ugyanolyan, mint a pozicionált UPDATE esetén
/lásd az 6.3-as alfejezetet/ és a "search condition" /keresési
feltétel/ azonositja a cél tábla azon sorait, amelyeket aktu-
alizálni kell. /A keresési feltételeket részletesen a 9. fe-
sql.doc Page: 58
jezetben tárgyaljuk./ A WHERE klauzula kihagyása azt jelenti,
hogy az UPDATE-t a céltábla minden sorához alkalmazni kell.
Az UPDATE konceptuonális végrehajtása ugy történik, mint
ha egy rejtett cursort /mondjuk H/ használnánk az aktualizá-
landó sorokon történö végigfuttatásra és egy megfelelö pozicionált
UPDATE ... WHERE CURRENT OF H-t alkalmaznánk egymást követöen
minden ilyen sorhoz.
Megjegyzés: A keresett UPDATE müvelet az elözö alfejezet-
ben az INSERT alatt megemlitett két megszoritás közül
a másodikhoz hasonló megszoritástól "szenved": Ha az
UPDATE utasitás tartalmaz egy WHERE klauzulát, akkor az
UPDATE T cél táblázatára nem szabad hivatkozni a WHERE
klauzulán belüli semmilyen FROM klauzulában /az egymásba
ágyazás semmilyen szintjén - lásd a 9. fejezetet/. Igy
például a következö *** ILLEGAL *** /nem megengedett/:
UPDATE S
SET CITY = CITY_PARAM
WHERE S.STATUS <
(SELECT AVG (S.STATUS)
FROM S)
Ez a megszigoritás az IBM SQL-böl származó további marad-
vány. Megjegyzés vége.
7.5 KERESETT DELETE
A keresett DELETE utasitást használjuk sorok törlésére egy
táblában cursor használata nélkül. A törlés több soros /álta-
lában/; vagyis az utasitás nulla, egy, kettö ... vagy bármi-
lyen számu sort töröl egyetlen müveletben. Az alábbiakban meg-
adunk egy példát /a 2. fejezetböl vett példa egy variációja/:
DELETE
FROM P
WHERE P.WEIGHT > WEIGHT_PARAM
Az általános szintaxis:
DELETE
FROM table
[WHERE search-condition]
ahol "table" a cél táblát azonositja és "search condition" /ke-
resési feltétel/ azonositja a cél tábla azon sorait, amelyeket
törölni kell. /A keresési feltételeket részletesen a 9. feje-
zetben tárgyaljuk./ A WHERE klauzula kihagyása azt jelenti,
hogy a DELETE-t a cél tábla minden sorára alkalmazni kell.
A DELETE konceptuálisan úgy kerül végrehajtásra, mint ha
egy rejtett cursort /mondjuk H/ használnánk a törlendö sorokon
történö végigfuttatásra és egy megfelelö pozicionált DELETE ...
CURRENT OF H-t alkalmaznánk egymást követöen minden ilyen sor-
hoz.
sql.doc Page: 59
Megjegyzés: A keresett DELETE az elözö alfejezetben az
UPDATE alatt megemlitett megszigoritáshoz hasonló megszi-
goritástól szenved: ha a DELETE utasitás tartalmaz egy
WHERE klauzulát, akkor a DELETE T cél táblájára nem sza-
bad hivatkozni ezen WHERE klauzulán belül semelyik
FROM klauzulában /semilyen beágyazási szinten - lásd
a 9. fejezetet/. Igy például a következö *** ILLEGAL ***
/nincs megengedve/:
DELETE
FROM S
WHERE S.STATUS <
(SELECT AVG (S.STATUS)
FROM S)
Ismét érvényes, hogy ez a megszigoritás az IBM SQL-böl
származó maradvány. Megjegyzés vége.
sql.doc Page: 60
8
-------- ----- ------ ----- ----- --------- ----- -------
N é z e t e k
8.1 BEVEZETÉS
A 6. és 7. fejezetekben az egyszerüség kedvéért mindenhol
szándékosan feltételeztük, hogy minden tábla alap tábla.
Most figyelmünket azokra a speciális szempontokra irányit-
juk, amelyek a nézetekre /vagy "viewed tables" /nézet táblák-
ra, hogy a hivatalos szabvány kifejezéseit használjuk/, ér-
vényesek. Emlékezzünk vissza a 2. fejezetböl, hogy egy nézet
egy virtuálistábla - vagyis olyan tábla, ami nem létezik
saját jogán, de a felhasználó számára ugy látszik, mintha
létezne. /Ezzel ellentétben egy alap tábla valós tábla, abban
az értelemben, hogy egy ilyen tábla minden sorához ténylege-
sen tartozik ezen sor valamilyen tárolt megfelelöje a fizikai
tárolóban./
A nézeteket nem támogatják saját, fizikailag külön,
megkülönböztethetö módon tárolt adataik. Mindaz ami bekö-
vetkezik, amikor egy nézetet definiálnak csupán az, hogy a né-
zetnek más táblák kifejezéseivel történö definicióját a
rendszer valamilyen módon megjegyzi /ténylegesen a definiciónak a
rendszer katalógusba történö tárolásával - de természetesen egy ka-
talógus fogalma az SQL szabvány hatályán kivül van/. Megadunk
erre egy példát:
CREATE VIEW GOODSUPPS (SNO, STATUS, CITY)
AS SELECT S.SNO, S.STATUS, S.CITY
FROM S
WHERE S.STATUS > 15
Figyelje meg a hasonlóságot egy cursor definiálásával: egy
cursor definiálásához hasonlóan egy nézet definició is tar-
talmaz egy SELECT kifejezést, mely definiál bizonyos érvé-
nyességi kört; /*/ és ugyanúgy mint a cursor definició esetén
a SELECT kifejezés kiértékelése nem történik meg a definiá-
lás idején. Azonban a felhasználó számára olyan, mintha
valóban létezne egy tábla az adatbázisban a megadott névvel.
A példában olyan, mintha valóban volna egy GOODSUPPS nevü
tábla a 8.1-es ábra nem árnyékolt részein /csak ezeken a ré-
szeken/ látható sorokkal és oszlopokkal.
----- ----- --------------
* Azonban jegyezze meg, hogy a nézet definiciók egy sémán
belül jelennek meg, ugyanakkor a cursor definiciók modulon
belül jelennek meg. Ennek következtében egy nézet definició
nem tartalmazhat semmilyen hivatkozásokat paraméterekre.
sql.doc Page: 61
8.1 ábra. GOODSUPPS az S alap tábla nézeteként /nem árnyé-
kolt részek/
--- ----- ------ ------
GOODSUPPS SNO SNAME STATUS CITY
--- ----- ------ ------
S1 Smith 20 London
S2 Jones 10 Paris
S3 Blake 30 Paris
S4 Clark 20 London
S5 Adams 30 Athens
Megadunk a GOODSUPPS-vel kapcsolatos SELECT müveletre
egy példát:
SELECT *
FROM GOODSUPPS
WHERE GOODSUPPS.CITY <> 'London'
A rendszer le fogja forditani ezt a SELECT-et az alapul
szolgáló alap táblában, /vagy alap táblákban, többes számban,
lásd a 8.2-es alfejezetet/ egy ekvivalens müveletre.
A forditás ugy történik, hogy a felhasználó által kiadott SELECT-et
"összefésülik" a katalógusban megörzött SELECT-vel; lényegé-
ben helyettesitve a nézetre hivatkozásokat a nézet definici-
ójával. Ebben a példában eredményként létrejövö müvelet:
SELECT S.SNO, S.STATUS, S.CITY
FROM S
WHERE S.CITY <> 'London'
AND S.STATUS > 15
Megjegyzés: Ebben a példában /ismét GOODSUPPS nézet/ a
SELECT több soros és ebböl következik, hogy nem hajtható
végre egy SELECT utasitásként, legalábbis a szabvány elöirása
szerint nem. Ehelyett komponensként kell bevinni le-
kérdezés kifejezésen vagy lekérdezés specifikáción, vagy
más bonyolultabb nyelv konstrukción belül /például egy cursor
definicióján belül/. A részleteket lásd a 9. fejezetben.
Azonban az egyszerüség kedvéért kényelmes dolog feltételezni,
hogy több soros SELECT-ek közvetlenül végrehajthatók és okta-
tási okok miatt ezt a feltételezést fogjuk megtenni a jelen
fejezet hátralevö részének nagy részében.
A most bemutatott forditási folyamat az aktualizálási mü-
veletekre is érvényes. Például a következö müvelet
UPDATE GOODSUPPS
SET CITY = 'New York'
WHERE S.STATUS.CITY = 'Paris'
az alábbira van leforditva
UPDATE S
SET CITY = 'New York'
WHERE S.CITY = 'Paris'
sql.doc Page: 62
AND S.STATUS > 15
Az INSERT és DELETE müveletek kezelése ugyanilyen általá-
nos módon történik. Például az alábbi INSERT müvelet
INSERT
INTO GOODSUPPS (SNO, STATUS, CITY)
VALUES ('S6',25, 'Madrid')
a következöre forditódik le:
INSERT
INTO S (SNO, STATUS, CITY)
VALUES ('S6', 25, 'Madrid')
/tehát jegyezze meg, hogy az SNAME null értéküre lesz állitva a be-
szurt sorban/. Ehhez hasonlóan a DELETE müvelet
DELETE
FROM GOODSUPPS
WHERE GOODSUPPS.CITY = 'New York'
leforditódik az alábbira:
DELETE
FROM S
WHERE S.CITY = 'New York'
AND S.STATUS > 15
Magyarázat: Szigorúan megvizsgálva a jelen alfejezet magya-
rázatait, melyek arra vonatkoznak, hogy egy V nézetre hi-
vatkozásokat ugy dolgozzák fel, hogy /konceptuálisan/ he-
lyettesitik ezeket egy V definiciójával, kissé spekulativ-
nak kell tekinteni. A hivatalos SQL szabvány valójában
egyáltalán nem adja meg, hogy a nézetek hogyan vannak fel-
dolgozva! Az egyetlen útmutatás, amit a szabvány megad,
egy szabály ami közli, hogy egy V nézet értéke "az a tábla,
ami akkor jön létre, ha a [ V definiciója ] végrehajtás-
ra kerülne" egy olyan kijelentéssel együtt mely kimondja,
hogy tekintet nélkül arra, hogy a V materializálva van-e
vagy sem, ezt az implementáció definiálja. Azonban a né-
zetekre vonatkozó számos korlátozások közül sok /lásd a
8.3-as és 8.4-es alfejezeteket/ világosan annak valószinü-
ségéböl származik, hogy a nézeteken müveleteket való-
jában a fent leirt összefésülési /merging/ folyamat imp-
lementálja. Magyarázat vége.
8.2 NÉZET DEFINICIO
A CREATE VIEW általános szintaxisa:
CREATE VIEW view [(column-commalist)]
AS query-specification
[WITH CHECK OPTION]
sql.doc Page: 63
ahol "view" /nézet/ az ujonnan létrehozott nézet nem minösitett
neve /*/, az azonositók opcionális commalist-jében az azonosi-
tók a nézet oszlopainak nem minösitett nevei, a lekérdezési
specifikáció egy olyan SELECT kifejezés, amely a nézet érvé-
nyességi körét definiálja /nem szigoruan megfogalmazva - a
részleteket lásd a 9. fejezetben/ és a WITH CHECK OPTION klau-
zulát a 8.4-es alfejezetben magyarázzuk el. Lásd az alábbi
elsö példában annak tárgyalását, hogy az oszlopnevek comma-
list-je mikor hagyható ki. A nézet teljesen minösitett neve
U.V, ahol U annak a sémának az AUTHORIZATION klauzulájában meg-
adott meghatalmazás azonositó, amelyik a CREATE VIEW müveletet
tartalmazza és a V ebben a müveletben /"view"-ként/ megadott
azonositó.
----- ----- --------
* Ténylegesen a név minösitett lehet, de ha minösitett, akkor
a minösitönek a séma AUTHORIZATION klauzulában megadott megha-
talmazás azonositónak kell lennie.
A CREATE VIEW-ben a lekérdezés specifikáció nem tartalmaz-
hat semmilyen paraméter hivatkozásokat.
Az alábbiakban megadunk néhány példát a CREATE VIEW-re.
1. CREATE VIEW REDPARTS (PNO, PNAME, WT, CITY)
AS SELECT P.PNO, P.PNAME, P.WEIGHT, P.CITY
FROM P
WHERE P.COLOR = ' Red'
Ennek az utasitásnak a hatása a REDPERTS nevü uj nézet létre-
hozása, négy oszlopppal, amelyek PNO, PNAME, WT, és CITY, az
alapul szolgáló tábla négy oszlopának, a PNO-nak
PNAME-nak, WEIGHT-nak illetve CITY-nek megfelelöen. A példa
kedvéért explicit módon megadtuk az ujonnan létrehozott nézet
oszlopainak neveit jóllehet a neveknek van egy nyilvánvaló
készlete /PNO, PNAME, WEIGHT, CITY/, mely az alapul szolgáló
táblázatból örökölhetö. Altalában az oszlop explicit megadá-
sára csak akkor van szükség, ha valami másból származik, mint
a FROM tábla /táblák/ /egyikének/ egyszerü oszlopából és/vagy
a kép oszlopok közül kettö egyébként azonos nevü lenne. Meg-
jegyezzük, hogy ezen utolsó két esetben explicit neveket kell
megadni minden nézet oszlophoz, még akkor is, ha ezen oszlo-
pok közül néhánynak nyilvánvaló örökölt neve van.
2. CREATE VIEW LREDPARTS
AS SELECT REDPARTS.PNO, REDPARTS.WT
FROM REDPARTS
WHERE REDPARTS.CITY = 'London'
Tökéletesen lehetséges egy nézet definiálása más nézetek kife-
jezéseivel, mint ahogyan ez a példa mutatja. Az LREDPARTS-hez
az oszlopnevek PNO és WT /az REDPARTS-ból örökölve/.
3. CREATE VIEW CITYPARTS (SCITY,PCITY)
AS SELECT S.CITY, P.CITY
FROM S,SP P
WHERE S.SNO = SP.SNO
sql.doc Page: 64
AND SP.PNO = P.PNO
Ennek a nézetnek az a jelentése, hogy egy város név pár
/X,Y/ fog megjelenni a nézetben, akkor és csakis akkor, ha egy
szállitó, melynek telephelye x városban van, olyan alkatrészt
szállit, amelyet y városban tárol. Például az S1 szállitó P1
alkatrészt szállit; az S1 szállitó telephelye Londonban van
és a P1 alkatrészt Londonban tárolja; és igy a /London,London/
pár jelenik meg a nézetben. Jegyezze meg, hogy ennek a nézet-
nek a definiciója tartalmaz egy összekapcsolást /valójában
"három utas" összekapcsolás/ ugy hogy az egy olyan nézetre
példa, amely több alapul szolgáló táblázatból származik. Azt is
jegyezze meg, hogy a nézet oszlopaihoz tartozo örökölt nevek
közül mindkettö CITY és ebböl az következik, hogy explicit
módon uj oszlopneveket kell megadni az alábbiakban láthatóak
szerint
4. CREATE VIEW PQ (PNO, TOTQTY)
AS SELECT SP.PNO, SUM(SP.QTY)
FROM SP
GROUP BY SP.PNO
Ebben a példában nincs olyan név, amely a "teljes mennyiség"
oszlophoz örökölhetö, mivel ez az oszlop egy beépitett függ-
vényböl származik; ebböl következik, hogy /ismét/ explicit
módon uj oszlop neveket kell megadni a bemutatottak szerint.
Azt is figyelje meg, hogy jóllehet ez a nézet egyetlen, alapul
szolgáló alap táblából származik, nem csak egyszerüen sor és
oszlop részhalmaza ennek az alap táblának /a korábban bemuta-
tott REDPARTS és GOODSUPPS nézetekkel ellentétben/. Ehelyett
ezen alapul szolgáló tábla egyfajta statisztikai összefoglalá-
sának és tömöritésének tekinthetö.
8.3 VISSZANYERESI MUVELETEK
Körvonalban már elmagyaraztuk /a 8.1-es alfejezetben/, hogy
egy nézetlen visszanyerési müveletek hogyan vannak leforditva
az alapul szolgáló alap táblán /táblákon/ ekvivalens müveletekre.
Sok esetben ez a forditási eljárás /folyamat/ teljesen nyil-
vánvaló /egyenes úton halad/ és tökéletesen jól müködik,
anélkül, hogy bármilyen meglepetést okozna a felhasználónak.
Esetenként azonban meglepetések keletkezhetnek. Vagyis prob-
lémák merülhetnek fel azzal kapcsolatban, amit "csoportosi-
tott nézeteknek" nevezünk. A PQ nézet /az elözö alfejezet-
böl a 4-es példa/ példa egy csoportositott nézetre. Altalá-
ban minden olyan nézet, melynek definiciója közvetlenül tar-
talmaz egy GROUP BY klauzulát /vagy HAVING klauzulát - lásd
a 9. fejezetet/ egy csoportositott nézet. Egy csoportositott
nézet nézetét /vagyis olyan nézetet, melynek a definicioja
közvetlenül tartalmaz egy csoportositott nézetre hivatkozó
FROM klauzulát/ is csoportositott nézetnek tekintjük - és
igy tovább, bármilyen számú szintig.
A csoportositott nézetekre különbözö megszigoritások
vonatkoznak. Elöször is, egy FROM klauzula számára, mely
sql.doc Page: 65
hivatkozást tartalmaz csoportositott nézetre /akármilyen
összefüggésben/ nincs megengedve, hogy bármilyen más táblára
hivatkozzon; más szavakkal egy csoportositott nézet nem kap-
csolható semmilyen más táblához. Ezenkivül egy csoportositott
nézetre hivatkozó FROM klauzula számára nincs megengedve,
hogy egy ehhez tartozó WHERE klauzulát, GROUP BY klauzulát,
vagy HAVING klauzulát tartalmazzon. A következö leirás az
ilyen megszoritások mögötti okfejtés vázlatos ismertetését
reprezentálja. Vegyük szemügyre a következö példát.
Nézet definició /megengedett/:
CREATE VIEW PQ (PNO, TOTQTY)
AS SELECT SP.PNO, SUM (SP.QTY)
FROM SP
GROUP BY SP.PNO
/a 8.2-es alfejezetböl a 4-es példa ismétlése/.
Megkisérelt lekérdezés /*** ILLEGAL ***/ /nem megengedett/:
SELECT PQ.PNO
FROM PQ
WHERE PQ.TOTQTY > 500
Ha a 8.1-es alfejezetben leirt egyszerü forditási eljárást
alkalmazzuk ennek a kifejezésnek azzal a nézet definicióval
egyesitésére /kombinálására/, amelyre a rendszer emlékezik,
valami olyant kapunk, ami hasonlit a következöhöz:
SELECT SP.PNO
FROM SP
WHERE SUM (SP.QTY) > 500
GROUP BY SP.PNO
És ez nem érvényes SELECT kifejezés. Nincs megengedve, hogy
egy WHERE klauzulában lévö prédikátumok olyan beépitett függ-
vényekre hivatkozzanak, mint például a SUM. Az amire az
eredeti kifejezést át kell alakitani, valami olyasmi, ami a
következö sorokban látható:
SELECT SP.PNO
FROM SP
GROUP BY SP.PNO
HAVING SUM (SP.QTY) > 500
Azonban az SQL nem képes arra, hogy végrehajtson ilyen fordi-
tást.
Az alábbiakban megadunk egy másik példát olyan helyzetre,
amelyben a forditás nem müködik /ismét a PQ "statisztikai
összefoglaló" nézetet használva/. A megkisérelt lekérdezés:
SELECT AVG (PQ.TOTQTY)
FROM PQ
sql.doc Page: 66
"Leforditott" alak:
SELECT AVG (SUM (SP.QTY))
FROM SP
GROUP BY SP.PNO
Ez ismét nem megengedett. Az SQL nem engedi meg, hogy a be-
épitett függvények igy legyenek egymásba ágyazva.
Magyarázat: A megadott példák nem meritik ki a lehetö-
ségeket. Hasonló kellemetlen meglepetések fordulhatnak
elö, ha a nézet definició tartalmaz DISTINCT-et, vagy
olyan oszlopot, amely egy müveleti kifejezésböl /például
A + B/ származik, vagy pedig olyan oszlopot, amely egy
beépitett függvényböl /még GROUP BY nélkül is/ származik.
Ezenkivül nem könnyü pontosan jellemezni az ilyen "meg-
lepetések" teljes halmazát. A legjobb, ami egy általános
irányelv segitségével megfogalmazhatónak látszik: az ere-
deti lekérdezés leforditott alakjának mindig megengedett
SQL SELECT-kifejezésnek kell lenni. A nézetek teljes terü-
lete /különösen a visszanyerési szempont/ az SQL nyelv
"legkomiszabb" részeinek egyike. Magyarázat vége.
8.4 AKTUALIZALASI MÜVELETEK
Egy adott nézet lehet, hogy aktualizálható, de lehet, hogy nem.
Ezt a kijelentést a 8.1 illetve 8.2 alfejezetböl vett két nézet,
a GOODSUPPS és CTYPAIRS segitségével mutatjuk be. A kényelmes
kezelés mód érdekében megismételjük ezek definicióit az alábbi-
akban:
CREATE VIEW GOODSUPPS (SNO, STATUS, CITY)
AS SELECT S.SNO, STATUS, S.CITY
FROM S
WHERE S.STATUS > 15
CREATE VIEW CITYPAIRS (SCITY, PCITY)
AS SELECT S.CITY, P.CITY
FROM S, SP, P
WHERE S.SNO = SP.SNO
AND SP.PNO = P.PNO
Ezen két nézet közül a GOODSUPPS logikailag aktualizál-
ható, miközben a CITYPAIRS logikailag nem aktualizálható.
Tanulságos dolog megvizsgálnunk, hogy miért van ez igy. A
GOODSUPPS esetében:
/a/ Beszúrhatunk /INSERT/ egy új sort a képbe - mondjuk a
/S6,40,Rome/ sort - a megfelelö sornak /S6,NULL,40,Rome/
tényleges beszúrásával az alapul szolgáló alap táblába.
/b/ Törölhetünk /DELETE/ egy meglévö sort a nézetböl - mond-
juk a /S1,20,London/ - az alapul szolgáló alap táblából
a megfelelö sor /S1,Smith,20,London/ tényleges törlésével.
/c/ Aktualizálhatunk /UPDATE/ a nézeten egy meglévö értéket
- mondjuk az S1 szállitóhoz tartozó CITY értéket /neve-
sql.doc Page: 67
zetesen London-t/ megváltoztatjuk Rome-ra - úgy, hogy
az alapul szolgáló alap táblában ténylegesen végrehajtjuk
a változtatást a megfelelö értékre.
Most vizsgáljuk meg a CITYPAIRS nézetet. Mint ahogyan a
8.2-es alfejezetben elmagyaráztuk, ebben a nézetben a sorok
közül az egyik /London,London/ sor. Tételezzük fel, hogy le-
hetséges ennek a sornak a DELETE-je /törlése/. Mit kellene
egy ilyen DELETE-nek jelölnie? - Vagyis az alapul szolgáló ada-
tokon milyen aktualizálásoknak /DELETE-k vagy mások/ kellene
egy ilyen DELETE-nek megegyeznie? Az egyetlen lehetséges vá-
lasznak annak kell lennie, hogy "nem tudjuk"; egyszerüen nincs
mód /általában/, hogy eljuthassunk lefelé egészen az alapul
szolgáló alap táblákhoz és itt végrehajthassuk az aktualizá-
lások megfelelö halmazát. Tulajdonképpen még nem is létezik
ilyen "megfelelö aktualizálás halmaz"; nincs olyan aktuali-
zálás halmaz /készlet/, mely az alapul szolgáló adatokra al-
kalmazható /általában/, melynek pontosan az lenne a hatása,
hogy eltávolitaná a megadott sort a nézetböl, miközben minden
mást változatlanul hagyna a nézetben. Más szavakkal megfogal-
mazva, az eredeti DELETE a lényegéböl adódóan nem támogatható
müvelet. Hasonló érvelések tehetök meg annak bemutatására,
hogy /általában/ az INSERT és UPDATE müveletek ugyancsak
a lényegükböl adódóan nem támogathatók ezen a nézeten.
Igy látjuk, hogy néhány nézet a jellemzöiböl adódóan
aktualizálható, ugyanakkor mások a jellemzöikböl adódóan nem.
Figyelje meg itt a "jellemzöiböl adódó" /inherently/ szót.
Nemcsak egyszerüen az a probléma, hogy néhány rendszer képes
arra, hogy támogasson bizonyos aktualizálásokat, mig mások
nem képesek erre. Nincs olyan rendszer, amelyik konzisztens
módon támogathat aktualizálásokat segitség nélkül egy néze-
ten, mint például a CITYPAIRS /"segitség nélkül" alatt " vala-
milyen emberi felhasználótól érkezö segitség nélküli" esetet
értünk/.
Annak további leirását, hogy melyek azok a nézetek, ame-
lyek elméletileg aktualizálhatók és melyek, amelyek nem, az
olvasónak a szerzö Relational Database: Selected Writings
/relációs adatbázis: válogatott irások/ /Addison-Wesley
1986/ könyvében kell megnéznie. Azonban itt nem foglalkozunk
túl sokat azzal, hogy mi az ami elméletileg lehetséges, hanem
inkább azzal, hogy mi az amit az SQL meg fog engedni /ami na-
gyon különbözö dolog/. SQL-ben egy nézet aktualizálható, akkor
és csakis akkor, ha a következö feltételek /a/-/f/, mindegyike
ki van elégitve a nézet definicióban /vagyis a nézetet defi-
niáló SELECT kifejezésben/:
/a/ Nem tartalmazza a DISTINCT kulcsszót.
/b/ A SELECT klauzulában minden tétel az alapul szolgáló tábla
egy oszlopára történö egyszerü hivatkozásból áll /vagyis
nem konstans, nem olyan müveleti kifejezés, mint például
C + 1, és nem hivatkozás egy olyan beépitett függvényre,
mint például az AVG/.
/c/ A FROM klauzula pontosan egyetlen táblát azonosit és ez
a tábla viszont aktualizálható.
/d/ A WHERE klauzula nem tartalmaz al-lekéredezést.
/e/ Nincs GROUP BY klauzula.
sql.doc Page: 68
/f/ Nincs HAVING klauzula.
Végül /hogy a nyilvánvaló dolgot is megemlitsük/: az
INSERT, UPDATE és DELETE müveletek egy SQL nézetre csak
akkor alkalmazhatók, ha ez a nézet aktualizálható a fent def-
iniáltak szerint.
Magyarázat: Ezek a korlátozások nagyon nagy megszo-
ritások. Ezen kivül néhány esetben logikailag is szük-
ségtelenek. A DB2 SQL kissé kevésbé korlátozó hatású
/jóllehet nem nagy a különbség/; DB2-ben a fenti /b/
és /d/ szabályok kissé lazithatók, a következöképpen.
/b/ DB2-ben, ha a nézet egy oszlopa egy beépitett függvény-
böl származik, akkor a nézet nem aktualizálható. Ha
konstansból vagy olyan müveleti kifejezésböl származik,
mint például C + 1, akkor az INSERT müveletek nincsenek
megengedve és az UPDATE müveletek sincsenek megengedve
ebben az oszlopban. Azonban a DELETE müveletek meg vannak
engedve és az UPDATE müveletek is meg vannak engedve más
oszlopokon.
/d/ DB2-ben, ha a WHERE klauzula tartalmaz egy al-lekérde-
zést és ebben az al-lekérdezésben a FROM klauzula arra
az alap táblára hivatkozik, amelyben a nézet definiálva
van, akkor a nézet nem aktualizálható.
Az alap probléma /mind a szabványos SQL-vel, mint a
DB2-vel/ az, hogy a nyelv nagyon ad hoc állapotú: tele
van orthogonalitás /=normalizáltság(itt)/ hiány esetekkel
és nem veszi figyelembe a relációs modellböl az elsöd-
leges és idegen kulcs alapvetö szemantikai elképzelése-
it. Lásd a 12. fejezetben az "orthogonalitás" kifejezés
magyarázatát. Magyarázat vége.
A Check opció
Végül még egyszer visszatérünk a GOODSUPPS nézetre azért,
hogy megtárgyaljunk egy utolsó kérdést. Mint ahogyan ennek
az alfejezetnek az elején már elmagyaráztuk, ez a nézet ak-
tualizálható. Azonban vizsgáljuk meg a következö UPDATE-t:
UPDATE GOODSUPPS
SET STATUS = 0
WHERE GOODSUPPS.SNO = 'S1'
Elfogadható ez az UPDATE ? Ha igen, az lesz a hatása,
hogy eltávolitja az S1 szállitót a nézetböl, mivel az S1 sor
a továbbiakban már nem fogja kielégiteni a /"S.STATUS > 15"/
nézet definiáló feltételt. Ehhez hasonlóan az alábbi INSERT
müvelet
INSERT
INTO GOODSUPPS (SNO, STATUS, CITY)
VALUES ('S8', 7, 'Stockholm')
/ha elfogadásra kerül/ létre fog hozni egy új szállitó sort,
de ez a sor azonnal el fog tünni a nézetböl. A check opció
sql.doc Page: 69
/a 8.2-es fejezetben van megemlitve/ van kijelölve arra, hogy
az ilyen helyzetekkel foglalkozzon. Ha az alábbi klauzula
WITH CHECK OPTION
szerepel egy nézet definiciójában, akkor ezen nézethez kiadott
minden INSERT-et és UPDATE-t ellenörizni fog annak biztositá-
sára, hogy az újonnan INSERTed /beszúrt/ vagy UPDATEd /aktua-
lizált/ sor valóban kielégiti-e a nézet - definiáló feltételt.
Ha nem elégiti ki, akkor a müvelet visszautasitódik.
A check opció csak akkor adható meg, ha a nézet aktuali-
zálható.
Magyarázatok:
1. DB2-ben a check opció csak akkor adható meg, ha a
nézet aktualizálható és a definiciója nem tartalmaz
al-lekérdezést. Ha a nézet olyan, hogy UPDATE-k csak bi-
zonyos oszlopokon vannak megengedve /és INSERT-ek egyál-
talán nincsenek megengedve/, akkor a check opció csak
ezeken az oszlopokon UPDATE-kre érvényes.
2. Jegyezzük meg, hogy /mint ahogy a 3.3-as alfejezet-
ben is emlitettük, a check opció nem örökölhetö. Vagyis,
ha V nézet definiciója tartalmaz WITH CHECK OPTION-t és
W nézet a V nézet segitségével van definiálva, akkor a
W nézeten keresztüli V nézet aktualizálásokat nem ellen-
örzi a V nézet check opciójával. A dolgok ilyen állása
az IBM SQL-böl származó további "maradvány". Jobb lenne,
ha olyan check opció lenne, amelyet a V nézetböl automa-
tikusan örökölne az összes olyan W aktualizálható nézet,
melyek V nézet kifejezéseivel vannak definiálva.
3. Tulajdonképpen a check opció valamifajta általá-
nos anomália. Különös dolog, hogy létezik egy ilyen
opció nézetekhez, de nem létezik alap táblákhoz. Megje-
gyezzük, hogy egy "check opció alap táblákhoz" hatás
elérhetö egy olyan nézet definiálásával, amely azonos
a kérdéses alap táblával. Például:
CREATE VIEW V
AS SELECT *
FROM P
WHERE P.WEIGHT > 0
WITH CHECK OPTION
Ha P.WEIGHT oszlopon minden INSERT és P táblán minden
INSERT végrehajtása ténylegesen V nézeten keresztül tör-
ténik, akkor az SQL valójában az "alkatrész súlyoknak
nullánál nagyobbnak kell lenniük" alap tábla követelményt
lépteti érvénybe.
Magyarázat vége.
sql.doc Page: 70
9
-------- ----- ------ -------- ----- ------
Altalános nyelvkonstrukciók
9.1 LEKÉRDEZÉS KIFEJEZÉSEK
Ebben a fejezetben /végül is/ elmagyarázunk számos fontos
SQL konstrukciót, ilyen például a "keresési feltétel",amely-
re nagyon sokszor hivatkoztunk az elözö fejezetben, de
eddig még nem volt megfelelöen definiálva. A kérdéses
konstrukciók számos különbözö kontextusban jelennek meg a
nyelven belül. A "lekérdezés kifejezés" konstrukcióval kezd-
jük, mivel sokféle szempontból tekintve ez a konstrukció te-
kinthetö annak a konstrukciónak, amelyik a szintaxis fa tete-
jén van. Bemutatjuk a BNF definicióját:
query-expression
::= query-term
|query-expression UNION [ ALL ] query-term
query-term
::= query-specification| (query-expression)
A "lekérdezés kifejezés" konstrukció csak cursor defini-
ción belül jelenik meg /Azonban jegyezze meg, hogy UNION nincs
megengedve SELECT utasitásban vagy INSERT ... SELECT-ben, vagy
nézet definicióban./ /lásd a 6. fejezetet/. Amint a nyelvtan
jelzi, egy lekérdezés kifejezés alapvetöen egyszerüen egy le-
kérdezés specifikáció, vagy két vagy több olyan lekérdezés
specifikáció /megadás/ együttese, melyeket UNION-ok kapcsolnak
össze - ha eltekintünk attól, hogy a nyelvtan az UNION-t tisztán
bináris müveletnek tekinti, ugy, hogy /például/ a három lekérde-
zés specifikációt - x, y és z - tartalmazó lekérdezés kifejezést
x UNION (y UNION z)-ként, vagy (x UNION y) UNION z-ként kell
irni, nem pedig egyszerüen x UNION y UNION z-ként. A látszó-
lag felesleges zárójelekre szükség van, mivel fennáll az a
lehetöség, hogy az UNION-ok közül egy vagy több tartalmazhat
ALL-t /lásd lejjebb/; például az x UNION ALL (y UNION z) és
(x UNION ALL y) UNION z kifejezések nem ekvivalensek.
Magyarázat: Követjük az SQL szabványt a "lekérdezés ki-
fejezés" /query expression/ és "lekérdezés specifikáció"
/query specification/ kifejezéseinek használatában, jól-
lehet nem nagyon jól irják le azokat a konstrukciókat,
amelyekre hivatkoznak. Az "UNION-kifejezés" / UNION-ex-
pression/ és "SELECT-kifejezés" /SELECT-expression/ sorok
menti kifejezések kielégitöbbek lehetnének. Magyarázat
vége.
Legyen A és B két tábla, melyek /általában/ két lekérde-
zés megadásból /specifikációból/ származnak. Pillanatnyilag
feltételezzük, hogy az alábbi lekérdezés kifejezés
A UNION [ ALL B ]
meg van engedve /lásd lejjebb/. Ekkor ennek a kifejezésnek
sql.doc Page: 71
az értéke egy tábla, mely tartalmaz egy sort minden olyan
sorhoz, amelyik benne van az A táblában, vagy B táblában,
vagy mindkét táblában. A redundáns ismétlödö sorok megörzödnek,
pontosan akkor, ha az ALL kulcsszó meg van adva. Bemutatunk
egy példát:
SELECT P.PNO FROM P WHERE P.WEIGHT > 16
UNION
SELECT SP.PNO FROM SP WHERE SP.SNO = 'S2'
Ennek a kifejezésnek az értéke a /P1, P2, P3, P6/ alkatrész
számok halmaza - vagyis az ismétlödések kimaradtak. Ha ALL
meg lett volna adva, az értéknek /P1, P2, P2, P3, P6/- nek kellett
volna lennie - vagyis az ismétlödéseket meg kellett volna
örizni. Figyelje meg a különbséget az UNION és SELECT között
az ismétlödés kihagyás szempontjából: SELECT-tel a felhasz-
náló irhatja elö az ALL-t vagy DISTINCT-et és ALL az alap-
értelmezés; UNION esetén a felhasználó csak az ALL-t adhatja
meg explicit módon /a megadás kihagyása olyan, mintha
"DISTINCT-et" adnának meg /és "DISTINCT" /ha nincs más meg-
adva/ az alapértelmezés.
Visszatérve az érvényesség kérdésére /arra, hogy mi az
ami meg van engedve/: Az alábbi lekérdezés kifejezés
A UNION [ ALL B ]
csak akkor van megengedve, ha minden i-hez, az A i-edik osz-
lopa és a B i-edik oszlopa azonos leirásúak, vagyis leirásuk
pontosan ugyanazt az adattipust és pontosan ugyanazt a hosz-
szúságot /vagy pontosság, vagy pontosság és skála tényezö, az
adott helyzetnek megfelelöen, /tartalmazza. Jegyezze meg, hogy
például CHAR(4) nem ugyanaz, mint CHAR(5) és DECIMAL(5,2) nem
ugyanaz, mint NUMERIC(5,2), vagy DECIMAL(6,2). Ezenkivül, ha
NOT NULL van bármelyik oszlopra elöirva, akkor mindkettöre
elöirva kell lennie.
Magyarázat: Ezek a nagyon szigorú korlátozások az IBM
SQL-böl származó további sajnálatos maradványt képvi-
selnek. Az UNION müveletnek a gyakorlatban a használatát
nagyon nehézkessé teszik. Magyarázat vége.
Mint ahogyan korábban már jeleztük, a "lekérdezés kife-
jezés" konstrukció csak egy cursor definicióján belül jele-
nik meg. A célja annak a lekérdezésnek a definiálása, amelyik
a cursorhoz kapcsolódik és ebböl következöen azon sorok halma-
zának a meghatározása, melyek ezen cursor-on keresztül feldol-
gozhatók, amikor a cursor meg van nyitva.
9.2 LEKÉRDEZÉS SPECIFIKACIóK
Egy lekérdezés specifikáció úgy jelenik meg, mint egy komponense
egy lekérdezés kifejezésnek. Ezenkivül az INSERT utasitás
többsoros formátumában /lásd a 7. fejezetben/ és egy nézet
definicióban /lásd 8. fejezetben/ is megjelenik. Szintak-
tikailag azonos egy SELECT utasitással, eltekintve attól,hogy a
SELECT utasitás tartalmaz INTO klauzulát. Azonban szemantikailag
eltér a SELECT utasitástól abban, hogy az értéke /általában/
sql.doc Page: 72
többsoros tábla, ugyanakkor a SELECT utasitásnak legfeljebb
egy sort kell visszaadnia /legalábbis a szabványos SQL-ben/.
A szintaxis a következö:
query specification
::= SELECT [ ALL | DISTINCT ] selection
table-expression
ahol az ALL, a DISTINCT és a "selection" /kiválasztás/ pontosan
ugyanaz, mint egy SELECT utasitásban /lásd a 7.2-es alfeje-
zetet/ és "table-expression" /tábla kifejezés/ a 9.5-ös
alfejezetben van definiálva. Megjegyzés: Mint ahogyan a
7.2-es alfejezetben elmagyaráztuk, a "selection" konstruk-
ció alapvetöen "scalar expressions" /skalár kifejezések/
commalist-je. A skalár kifejezések a 9.3-as alfejezetben
vannak definiálva.
Az alábbiakban bemutatunk egy eléggé bonyolult példát
lekérdezés specifikációra:
SELECT P.PNO 'Weight in grams =', P.WEIGHT * 454, P.COLOR
'Max shipped quantity =', MAX (SP,QTY)
FROM P, SP
WHERE P.PNO = SP.PNO
AND (P.COLOR = 'RED' OR P.COLOR = 'Blue)
AND SP.QTY > 200
GROUP BY P.PNO, P.WEIGHT, P.COLOR
HAVING SUM (SP.QTY) > 350
Ezt a példát részletesen a 9.5-ös alfejezetben tárgyaljuk.
9.3 SKALAR KIFEJEZÉSEK
Skalár kifejezések sok kontextusban megjelennek. Ezeket a
kifejezéseket egyedi skalár /vagyis karakter lánc vagy nume-
rikus/ értékek reprezentálására használjuk. Az általános
szintaxisuk a következö:
scalar-expression
::= term
|scalar-expression (+|-) term
term
::= factor
|term (*|/) factor
factor
::= (+|-) primary
primary
::= atom
|column-reference
|function-reference
|(scalar-expression)
sql.doc Page: 73
Amint a BNF mutatja, egy saklár kifejezés alapvetöen
aritmetikai kifejezés, mely "primaries" /elsödlegesek/ gyüj-
teményét tartalmazza - ahol egy elsödleges /primary/ atom,
oszlop hivatkozás vagy függvény hivatkozás. A kifejezés
tartalmazhatja a + és - prefixum /elötag/, valamint a +,-,*,
és / infixum (beékelési) operátorokat, illetve zárójeleket tar-
talmazhat a kiértékelés kivánt sorrendjének kikényszeritésére.
Megjegyzés: Az aritmetikai operátorok nem alkalmazhatók karakter-
füzér tipusú elsödlegesekre. A függvényeket a következö alfe-
jezetben tárgyaljuk. Az egyéb "elsödleges" /primary/ tárgyakat,
nevezetesen az atomokat és oszlop hivatkozásokat, az alábbiakban
irjuk le.
atom
::= parameter-reference
|literal
|USER
parameter-reference
::= parameter[[INDICATOR]parameter]
Az atom egy paraméter hivatkozás /az 5. fejezetben tárgyaltuk/
vagy literal /a 3. fejezetben tárgyaltuk/, vagy USER rendszer
változó /a 4. fejezetben tárgyaltuk/.
column-reference
::= [column-qualifier . ]column
Egy oszlop hivatkozás /column reference/ egy /esetleg minö-
sitett/ oszlop név.
Magyarázat:
1. Figyelje meg, hogy a NULL nem atom; igy például
nem lehetséges SELECT NULL /null kiválasztás/.
2. Azt is figyelje meg, hogy egy SELECT kifejezés
nem skalár kifejezés, még akkor sem, ha valójában ska-
lár értéket ad vissza. Igy például nem lehetséges
/egyetlen UPDATE utasitáson belül/ valamilyen értéket
aktualizálni /UPDATE/ olyan értékkel helyettesitve, me-
lyet az adatbázisban lévö valamilyen másik helyröl
származik.
3. Az SQL szabvány tartalmaz szabályokat egy skalár
kifejezés eredményének adat tipusához, pontosságához,
stb. /jóllehet nem a "nem nullságot" /NOT NULL/ vagy
ehhez hasonlót/. Aznban sok esetben mindaz amit a
szabály mond, az hogy "implementáció definiálta" - ez
egy sajnálatos helyzet, figyelembe véve az ilyen ügyek
kritikus szemre vételezesét bizonyos kontextusokban
/lásd a 9.1-es alfejezetben az UNION leirását/. Nem tö-
rödünk most azzal, hogy a szabályokat itt részletesen
megfogalmazzuk.
Magyarázat vége.
sql.doc Page: 74
9.4 FÜGGVÉNYEK
A szabványos SQL öt beépitett függvényböl álló készletet
ad meg: COUNT, SUM, AVG, MAX, és MIN (*). A COUNT (*) speciális
esetétöl eltekintve - lásd késöbb - ezeknek a függvényeknek
mindegyike valamilyen tábla /rendszerint származtatott tábla,
vagyis adott alap táblákból valamilyen módon létrehozott
tábla/ egyik oszlopában lévö skalár értékek gyüjteményén
/együttesén/ fejtik ki a hatásukat és eredményként egyet-
len skalár értéket hoznak létre, mely a következöképpen van
definiálva:
COUNT skalárok száma az oszlopban
SUM skalárok összege az oszlopban
AVG skalárok átlaga az oszlopban
MAX legnagyobb skalár az oszlopban
MIN legkisebb skalár az oszlopban.
Egy függvény hivatkozás a skalár kifejezés speciális esete.
----------
* Az EXISTS /lásd a 9.8-as alfejezetet/ is függvénynek te-
kinthetö; azonban az EXISTS eltér a jelen alfejezetben tár-
gyalt függvényektöl, annyiban, hogy /a/ az argumentuma más szin-
taktikai stilusban van megadva /valójában logikusabb stilus-
ban/ és /b/ igaz értéket ad vissza, nem pedig egy számot vagy
karakter füzért, az igaz értékek pedig nem SQL tipusuak.
A szintaxis a következö:
function-reference
::= COUNT(*)
|distinct-function-reference
|all-function-reference
distinct-function-reference
::=
(DISTINCT column-reference)
all-function-reference
::=
(ALL scalar-expression)
SUM és AVG esetén az argumentumnak numerikus tipusunak
kell lennie. Altalában, ahogyan ezt a nyelvtan jelzi,
az argumentumot opcionálisan megelözheti a DISTINCT kulcsszó,
annak jelzésére, hogy a redundáns ismétlödö értékeket ki kell
hagyni a függvény alkalmazása elött /a DISTINC-hez az alter-
nativa az ALL; ALL az alap értelmezés, ha semmi más nincs
megadva. COUNT esetén DISTINCT-nek is megadottnak kell lennie;
a COUNT(*) speciális függvény - DISTINCT nincs megengedve -
egy táblában az összes sor megszámlálásához van biztositva, minden-
sql.doc Page: 75
féle ismétlödés kihagyás nélkül. Ha DISTINCT meg van adva,
akkor /ismét a BNF-ben jelzettek szerint/ az argumentumnak
csak egy egyszerü oszlop referenciából szabad állnia; ha DISTINCT
nincs megadva, az argumentum olyan müveleti kifejezésböl állhat,
mint például P.WEIGHT*454. Azonban még ha a DISTINCT nincs is
megadva, az argumentum akkor sem tartalmazhat semmilyen függvény
hivatkozást - vagyis függvény hivatkozások nem lehetnek
egymásba ágyazva.
Az argumentumból minden null mindig kihagyásra kerül /ki-
iktatódik/ a függvény alkalmazása elött, tekintet nélkül arra,
hogy a DISTINCT meg van-e adva, kivéve, COUNT(*) esetében, ahol
a null-ok kezelése éppugy történik, mint a nem null értékeké.
Ha az argumentum történetesen üres halmaz, a COUNT nulla ér-
téket ad vissza; a többi függvény mindegyike null értéket
ad vissza.
Magyarázat: Mindezen különbözö speciális szabály és kor-
látozás, melyek az olyan dolgokkal kapcsolatosak, mint
például a DISTINCT és a függvény argumentum közötti kölcsön-
hatás /stb./ mégegyszer újra az IBM SQL-böl származó
maradvány. Egyébként azt is jegyezzük meg, hogy ténylege-
sen nincs értelme annak, hogy DISTINCT-et MAX-val vagy
MIN-vel adjuk meg, mivel ennek nem lehet semmilyen lo-
gikai hatása. Magyarázat vége.
Megadunk néhány példát a függvények hasznalatára. A kö-
vetkezö példák közül mindegyik szingli SELECT utasitás alap-
jául szolgálhat, vagy beágyazható valamilyen bonyolultabb
kifejezésbe, ilyen például egy lekérdezés kifejezés
/lásd a 9.1-es alfejezetet/. Megjegyzés: Ha egy függvény hi-
vatkozás megjelenik SELECT klauzulán belül és a SELECT kifeje-
zés nem tartalmaz GROUP BY klauzulát, akkor a SELECT klauzu-
lának csak függvény hivatkozásokból szabad állnia. Például,
a következö *** ILLEGAL *** /nincs megengedve/:
SELECT SP.PNO,AVG(SP.QTY)
FROM SP
1. példa: Keressük meg a szállitók össz-számát:
SELECT COUNT(*)
FROM S
Eredmény: 5 /vagyis egy tábla, mely egyetlen megnevezett
oszlopból és az 5-ös egyedüli értéket tartalmazó egyetlen
sorból áll/.
2. példa: Keressük meg azoknak a szállitóknak az össz-számát,
akik jelenleg alkatrészeket szállitanak.
SELECT COUNT ( DISTINCT SP.SNO )
FROM SP
Eredmény: 4.
sql.doc Page: 76
3. példa. Keressük meg a P2-es alkatrészhez a szállitmányok
számát.
SELECT COUNT(*)
FROM SP
WHERE SP.PNO = 'P2'
Eredmény: 4. Figyelje meg, hogy az a tábla, amelyhez a COUNT*
alkalmazva van, ebben a példában, egy származtatott tábla,
nevezetesen az a tábla, melyet az alábbi kifejezés reprezentál
SP WHERE SP.PNO = 'P2'
/az SP tábla sorainak egy részhalmaza/.
4. példa: Keressük meg a leszállitott P2 alkatrész teljes meny-
nyiségét.
SELECT SUM (SP.QTY)
FROM SP
WHERE SP.PNO = 'P2'
Eredmény: 1000.
5. példa: Keressük meg azon szállitókhoz tartozó szállitó szá-
mokat, melyek állapot értéke kisebb, mint a jelenlegi maximális állapot
érték az S táblában.
SELECT S.SNO
FROM S
WHERE S.STATUS<
(SELECT MAX (S.STATUS)
FROM S)
Eredmény: Egyoszlopos /SNO oszlop nevü/ tábla; az S1, S2 és
S4 értékeket tartalmazza.
6. példa: Keressük meg azon szállitókhoz tartozó szállitó
számokat, melyek állapota nagyobb mint, vagy egyenlö a váro-
saikhoz tartozó átlaggal.
SELECT SX.SNO
FROM S SX
WHERE SX.STATUS>=
(SELECT AVG (SY.STATUS)
FROM S SY
WHERE SY.CITY = SX.CITY)
Eredmény: Egyoszlopos /SNO oszlop nevü/ tábla, mely S1, S3,
S4, és S5 értékeket tartalmazza. Megjegyzés: Ez a példa bemutatja
mind egy függvény használatát egy "al lekérdezésben", mind
pedig a "tartomány változók" /range variables/ /SX és SY/ hasz-
nálatát. Lásd a 9.8-as illetve 9.5-ös /7-es példa/ alfejezetek-
ben ezeknek a fogalmaknak a magyarázatait.
sql.doc Page: 77
9.5 TABLA KIFEJEZÉSEK
A tábla kifejezés(*) a következö alakú kifejezés
from-clause
[where-clause]
[group-by-clause]
[having-clause]
----- ----- -----------
* Lásd a 7.2-es alfejezetben leirt megjegyzest arra, hogy a
"tábla kifejezés" /table expression/ miért nem nagyon jó
elnevezés ehhez a konstrukcióhoz.
Tábla kifejezéseket használunk SELECT utasitásokban és
lekérdezés megadásokban /valamint al-lekérdezésekben, melyek
egy lekérdezés megadás speciális esetének tekinthetök - lásd
a 9.8-as alfejezetet/. Azoknak a különbözö klauzuláknak, melyek
egy tábla kifejezést felépitenek, a következö a szintaxisuk:
from-clause
::= FROM table-reference-commalist
table-reference
::= table [range-variable]
Itt a "table" /tábla/ /egy minösitett vagy nem minösitett/
tábla név, mely vagy egy alap táblát, vagy egy nézetet azono-
sit. Lásd a 7. példában a jelen alfejezet késöbbi részében,
az opcionális "range-variable" /tartomány változó/ magyaráza-
tát.
where-clause
::= WHERE search-condition
A keresési feltételeket részletesen a következö alfejezetben
tárgyaljuk.
group-by-clause
::=GROUP BY column-reference-commalist
Mint ahogyan a 9.3-as alfejezetben elmagyaráztuk, egy oszlop
hivatkozás egyszerüen minösitett, vagy nem minösitett oszlop
név.
having-clause
::= HAVING search-condition
Ismét elmondjuk, hogy a keresési feltételeket a következö
alfejezetben tárgyaljuk.
Az alábbiakban megadunk néhány példát a tábla kifejezé-
sekre. Ezek nagyrészét további magyarázat nélkül adjuk meg;
azonban megjegyezzük, hogy a 3-7-es példák mindegyike a relá-
ciós összekapcsolási müveletet mutatja be /nézze át a 2. fe-
sql.doc Page: 78
jezetet, ha szüksége van arra, hogy felfrissitse az emlékeze-
tét az összekapcsolásokkal kapcsolatban/. Megjegyzés: azért
hogy a példákat kissé valósabbá tegyük, mindegyik elé elhe-
lyezünk egy megfelelö SELECT klauzulát /igy tulajdonképpen
átalakitjuk ezeket lekérdezés megadásokká, ahelyett hogy tisz-
tán tábla kifejezések lennének/. De világosan meg kell érteni,
hogy természetesen a SELECT klauzula nem része a tábla kife-
jezésnek.
1. példa: Keressük meg az alkatrész számokat az összes leszál-
litott alkatrészhez.
SELECT SP.PNO
FROM SP
Vagy ha az ismétlödések kihagyására van szükség:
SELECT DISTINCT SP.PNO
FROM SP
2. példa: Keressük meg azon párizsi szállitók szállitó számait,
melyek állapota >20.
SELECT S.SNO
FROM S
WHERE S.CITY = 'Paris'
AND S.STATUS >20
3. példa: Keressük meg az összes olyan szállitószám/alkatrész
szám kombinációt, amelyeknál a kérdéses szállitó és alkatrész
ugyanabban a városban található.
SELECT S.SNO, P.PNO
FROM S, P
WHERE S.CITY = P.CITY
4. példa: Keressük meg az összes olyan szállitószám/alkatrész
szám kombinációt, amelynél a szállitó városa ABC szerinti
sorrendben követi az alkatrész városát.
SELECT S.SNO, P.PNO
FROM S, P
WHERE S.CITY > P.CITY
5. példa: Keressük meg az összes olyan szállitó szám/alkatrész
szám kombinációt, amelynél a szállitó és a kérdéses alkatrész
ugyanabban a városban található, de kihagyva a 20-as állapotú
szállitókat.
SELECT S.SNO, P.PNO
FROM S, P
WHERE S.CITY = P.CITY
AND S.STATUS<>20
sql.doc Page: 79
6. példa: Keressük meg az összes olyan város név párt, ame-
lyiknél az elsö városban levö szállitó a második városban
tárolt alkatrészt szállit.
SELECT DISTINCT S.CITY, P.CITY
FROM S, SP, P
WHERE S.SNO = SP.SNO
AND SP.PNO = P.PNO
Megjegyezzük, hogy ez a példa három tábla összekapcsolását
foglalja magában.
7. példa: Keressük meg a szállitó számok minden olyan párját,
amelyeknél az érintett két szállitó ugyanabban a városban ta-
lálható.
SELECT FIRST.SNO, SECOND.SNO
FROM S FIRST, S SECOND
WHERE FIRST.CITY = SECOND.CITY
Ez a példa magában foglalja az S tábla önmagával /megegyezö
városokon keresztüli/ összekapcsolását ugy, ahogyan ezt most
elmagyarázzuk. Egy pillanatra feltételezzük, hogy az S tábla
két külön példányával rendelkezünk, az "elsö" példánnyal és
a "második" példánnyal. Ekkor a lekérdezés logikája a követ-
kezö: képesnek kell lennünk arra, hogy megvizsgaljuk a szál-
litó sorok minden lehetséges párját, egyet az S elsö példá-
nyából és egyet a másodikból, és hogy visszanyerjük a két
szállitó számot az ilyen sor párból, amikor a város értékek
egyenlöek. Ezért képesnek kell lennünk arra, hogy egyidejü-
leg hivatkozzunk két szállitó sorra. Azért, hogy különbséget
tegyünk a két hivatkozás között, bevezetünk két tartomány
változót, a FIRST-et és SECOND-ot, melyek közül mindkettö az
S tábla fölötti tartomány /"ranges over"/ a kifejezést
tartalmazó kiértékelés végrehajtásának idejére. Bármely adott
idöpontban a FIRST valamilyen sort reprezentál az S tábla
"first" /elsö/ másolatából /példányából/ és "second" valami-
lyen sort reprezentál a SECOND /második/ példányból. A le-
kérdezés eredménye ugy kapható meg, hogy meg kell vizsgálni
a FIRST/SECOND értékek összes lehetséges párját és minden
esetben ellenörizni kell a WHERE feltételt.
--- ---
SNO SNO
--- ---
S1 S1
S1 S4
S2 S2
S2 S3
S3 S2
S3 S3
S4 S1
S4 S4
S5 S5
Rendezhetjük ezt az eredményt a WHERE klauzula kiterjesz-
sql.doc Page: 80
tésével a következöképpen:
SELECT FIRST.SNO, SECOND.SNO
FROM S FIRST, S SECOND
WHERE FIRST.CITY = SECOND.CITY
AND FIRST.SNO 20
A tartomány változó itt SX és az S táblára terjed ki,
----- ----- ---------
* A példák jelen sorozatában ez igy is van. Egy másik példa
található a 9.4-es alfejezetben. /6-os példa/.
Valójában az SQL mindig megköveteli, hogy a lekérdezések
tartomány változók kifejezéseiböl legyenek összeállitva (kia-
lakitva). Ha nincs explicit módon megadva ilyen változó, ak-
kor SQL feltételezi az olyan implicit változók létezését,
melyeknek ugyanaz a nevük (neveik), mint a megfelelö táblá-
nak (tábláknak). Például az alábbi lekérdezést
SELECT T.C
FROM T
.....
az SQL úgy kezeli, minha a következöképpen lett volna kife-
jezve:
sql.doc Page: 81
SELECT T.C
FROM T T
.....
- más szavakkal "T" önmaga egy alapértelmezés szerinti tar-
tomány változónév, mely azon T nevü tartomány változót reprezen-
tálja, amely a T nevü táblára terjed ki.
Megjegyzés: Az SQL szabvány a "correlation variable" (kor-
relációs változó) kifejezést használja a hagyományosabb ki-
fejezés, a "range variable" (tartomány változó) helyett. Egy
olyan névre, mint például a fenti példában lévö SX "correla-
tion name"-ként (korrelációs névként) hivatkozik. Azonban,
ebben a könyvben általában ragaszkodni fogunk a "range variab-
le"-hez (tartomány változóhoz).
8. példa. Minden egyes leszállitott alkatrészhez keresse meg
az alkatrész számot és az ehhez az alkatrészhez tartozó tel-
jes szállitási mennyiséget.
SELECT PNO, SUM ( SP.QTY )
FROM SP
GROUP BY SP.PNO
Eredmény: --- ---
PNO
--- ---
P1 600
P2 1000
P3 400
P4 500
P5 500
P6 100
A GROUP BY operátor konceptuálisan átrendezi a FROM klau-
zula (és a WHERE klauzula, ha meg van adva) által reprezentált
táblát minimális számú particióba vagy csoportba úgy,
hogy bármely adott csoporton belül minden sor azonos értéket
tartalmazzon a GROUP BY oszlophoz. A példában az SP tábla úgy
van csoportositva, hogy egyetlen csoport tartalmazza a P1 al-
katrészhez tartozó összes sort, egy másik tartalmazza a P2 al-
katrészhez tartozó összes sort, és igy tovább. Az eredmény egy
csoportositott tábla. (A csoportositott nézetek, ezeket már
tárgyaltuk a 8.3 alfejezetben, a csoportositott tábla speciá-
lis esete.)
Ha egy csoportositott táblához SELECT klauzulát alkalmaz-
nak (mint ebben a példában), akkor ebben a "SELECT klauzulában
a "selection"-ban (kiválasztásban) minden kifejezésnek (lásd a
7.2 fejezetet) csoportonként egy értékünek kell lennie; va-
gyis ez egy hivatkozás lehet magára a GROUP BY oszlopra (vagy
egy aritmetikai kifejezés, amely tartalmazza ezt az oszlopot)
vagy literál, vagy olyan függvény lehet, mint például a SUM,
ami egy csoporton belül egy adott oszlopban lévö minden érték-
re kifejti a hatását , és ezeket az értékeket egyetlen skalár
sql.doc Page: 82
értékére redukálja.
Egy tábla az oszlopai bármilyen kombinációja szerint cso-
portositható.
9.példa. Minden leszállitott alkatrészhez keressÜk meg ezen
alkatrésznek az alkatrész számát, a leszállitott maximális meny-
nyiséget és minimális mennyiséget, kizárva az S1 szállitó ál-
tal szállitott szállitmányokat.
SELECT SP.PNO, MAX ( SP.QTY ), MIN (SP.QTY )
FROM SP
WHERE SP,SNO <> 'S1'
GROUP BY SP.PNO
--- --- ---
Eredmény : PNO
--- --- ---
P1 300 300
P2 400 200
P4 300 300
P5 400 400
Kimaradtak azok a sorok , amelyek nem elégitik ki a WHERE klau-
zulát, mielött bármilyen csoportositás történt volna.
10.példa: Keressük meg az alkatrész számokat minden olyan al-
katrészhez , melyet egynél több szállitó szállitott.
SELECT SP.PNO
FROM SP
GROUP BY SP.PNO
HAVING COUNT(*)>1
A HAVING klauzula "egy WHERE klauzula csoporthoz"; vagyis
HAVING-ot használunk csoportok kihagyására éppúgy, mint ahogy
WHERE-t használunk sorok kihagyására. Igy, ha HAVING meg van
adva, GROUP BY-nak is megadottnak kell lennie.*
Egy HAVING klauzulában a kifejezéseknek csoportonként egy ér-
téküeknek kell lenniük (a gyakorlatban ezek majdnem mindig
függvény hivatkozások, éppúgy , mint a példában.
-----
* Tulajdonképpen lehetséges ,jóllehet szokatlan,HAVING-ot megad-
ni és GROUP BY-t nem; a hatás egyszerüen az, hogy a teljes
táblázat úgy tekintödik , mintha egyetlen csoport lenne.
sql.doc Page: 83
Egy átfogó példa
----- ----- ------
A jelen alfejezetet egy átfogó példával fejezzük be, ami bemu-
tatja, hogy a fent tárgyalt jellemzök közül sok (semmi eset-
re sem az összes) hogyan használható együtt, egyetlen kifeje-
zésben. Ezen kivül egy konceptuális algoritmust (vagyis for-
mális definició vázlatot) is megadunk a tábla kifejezések ál-
talános kiértékeléséhez.
Példa: Minden vörös és kék alkatrészhez , úgy,hogy a leszálli-
tott teljes mennyiség 350-nél nagyobb legyen (kizárva a teljes
leszállitásból az olyan szállitmányokat, melyekhez a mennyiség
200-nál kisebb, vagy 200-zal egyenlö, keressük meg ezen alkat-
résznek az alkatrész számát, a súlyát grammban, a szinét és a
maximális leszállitott mennyiségét. (Ez az a példa, amelyik
a 9.2 alfejezet végén látható. A példa kedvéért feltételezzük,
hogy a súly értékek a P táblában fontokban vannak megadva).
SELECT P.PNO, 'Weight in grams = ', P.WEIGHT * 454 ,P.COLOR,
'Max shipped quantity = ' , MAX ( SP.QTY )
FROM P,SP
WHERE P.PNO = SP.PNO
AND ( P.COLOR = 'Red' OR P.COLOR = 'Blue' )
AND SP.QTY >200
GROUP BY P.PNO, P.WEIGHT, P.COLOR
HAVING SUM ( SP.QTY ) > 350
Magyarázat:Egy SELECT kifejezés klauzulái azon kifejezés
által sugallt sorrendben kerülnek alkalmazásra,amelyben irva
vannak - maga a SELECT klauzula kivételével, melynek az alkal-
mazása utoljára történik. Ezért a példában úgy képzelhetjük
el, hogy az eredmény felépitése a következöképpen történik.
1. FROM: A FROM klauzula kiértékelése olyan új táblát ad ,a-
mely a P és SP táblák "Descartes szorzata" .Megjegyzés: A
T1, T2,... (ebben a sorrendben ) táblák halmazának Descartes
szorzata egy tábla, amely az összes lehetséges t sorból áll úgy
hogy t az összeláncolásaként adódik t1 sornak a T1-töl, t2
sornak a T2-töl, stb.
2. WHERE: Az 1. lépés eredményét csökkenti az összes olyan sor
kihagyása , amely nem elégiti ki a WHERE klauzulát.A példában
azok a sorok ,melyek nem elégitik ki a következö feltételt,
P.PNO = SP.PNO AND
( P.COLOR = 'Red' OR P.COLOR = 'Blue' ) AND
SP.QTY > 200
kimaradnak.
sql.doc Page: 84
3. GROUP BY: A 2. lépés eredményét a GROUP BY klauzulában meg-
nevezett oszlop(ok) értékei szerint csoportositja. A példában
ezek az oszlopok a P.PNO , a P.WEIGHT, és a P.COLOR.
4. HAVING: Azok a csoportok, amelyek nem elégitik ki az aláb-
bi feltételt
SUM ( SP.QTY ) > 350
kimaradnak a 3. lépés eredményéböl.
5. SELECT: A 4. lépés eredményében lévö minden csoport egyet-
len eredmény sort hoz létre a következöképpen. Elöször az al-
katrész szám, súly,szin és maximális mennyiség eltávolitása
történik a csoportból. Másodszor a súly átalakitódik grammra.
Harmadszor a két literál karakterfüzér "Weight in grams ="
(súly grammban) és "Max sipped quantity = "(maximális le-
szállitott mennyiség) behelyezödik a sorba a megfelelö he-
lyeken.
Megjegyzés: Egy pillanatra menjünk vissza a GROUP BY klau-
zulához: Elméletben P.PNO-nak egyedül elegendönek kellene
lennie , mint a csoportositó oszlopnak ,ebben a példában,
mivel P.WEIGHT és P.COLOR maguk is egyértéküek alkatrész
számonként. Azonban az SQL-nek nincs tudomása erröl az
utobbi tényröl és hibaállapotot fog életbeléptetni, ha
P.WEIGHT és P.COLOR kimarad a GROUP BY klauzulából, mivel
ezek megvannak emlitve a SELECT klauzulában.Az alap prob-
léma itt az , hogy az SQL nem támogatja az elsödleges kul-
csokat .Lásd a 11. fejezet .Megjegyzés vége.
9.6 KERESÉSI FELTÉTELEK
----- ----- -------------
A WHERE és HAVING klauzulákban keresési feltételeket haszná-
lunk az ezt követö feldolgozáshoz meghatározott sorok ( vagy
sorok csoportjai , HAVING esetében ) minösitésére vagy ki-
zárására .Adott sor (vagy csoport) esetén adott keresési
feltétel kiértékelése igaz , hamis vagy ismeretlen eredményt
ad. A minösitett sorok (vagy csoportok) pontosan azok ,amelyekhez
a feltétel kiértékelése igaz értéket ad.
Egy keresési feltétel szintaxisa a következö :
search-condition
::= boolean-term
: search-condition OR boolean-term
boolean-term
::= boolean-factor
: boolean-term AND boolean-factor
sql.doc Page: 85
boolean-factor
::= [ NOT ] boolean-primary
boolean-primary
::= predicate : ( search-condition )
Igy egy keresési feltétel alapvetöen olyan predikátumok gyüj-
teménye (együttese) , melyeket az AND , OR és NOT logikai ope-
rátorok és a kiértékelés kivánt sorrendjének jelzésére záró-
jelek használatával kombináltak egymással. A predikárum vi-
szont a következök valamelyike:
- összehasonlitás predikátum
- BETWEEN predikátum
- LIKE predikátum
- null teszt
- IN predikátum
- minden vagy valami predikátum
- létezés teszt
(nem mindegyik hivatalos szabványos kifejezés). A fenti elsö
öt kategóriára nem kvantoros predikátumokként, a többi kettö-
re kvantoros predikátumokként hivatkozunk( ezek ismét nem hi-
vatalos kifejezések). A 9.7 alfejezet foglalkozik a nem kvan-
toros predikátumokkal és a 9.8 és 9.9 alfejezetek foglalkoznak
a kvantoros predikátumokkal.
9.7 NEM KVANTOROS PREDIKATUMOK
----- ----- --------- ----- ------
Összehasonlitás predikátumok
Az összehasonlitás predikátumok két különbözö formátumban je-
lennek meg: Az elsö:
scalar-expression comparison scalar-expression
ahol "comparison" (összehasonlitás) az = , <>(nem egyenlö),>
<,<= vagy >= skalár összehasonlitó operátorok valamelyike.
Ha az összehasonlitó predikátum egy WHERE klauzulában
jelenik meg ,akkor a skalár kifejezéseknek nem szabad
tartalmazniuk semmilyen fuggvény hivatkozást.
A második formátum :
scalar-expression comparison subquery
Ahol egy "subquery" (al-lekérdezés) lényegében egyszerüen egy
zárójelek közé elhelyezett lekérdezés megadás (lásd a 9.2 fe-
jezetet) azzal a kivétellel, hogy a lekérdezés megadásnak mind-
össze egyetlen oszlopos /*/ táblát kell reprezentálnia és ugyan-
akkor - ebben a speciális kontextusban - legfeljebb egy soros
sql.doc Page: 86
táblát kell reprezentálnia.
------
* Kivéve EXIST kontextusában (lásd a 9.9 alfejezetet).
Az alábbiakban megadunk egy példát ennek az összehasonlitás
predikátum formátumnak a használatára:
SELECT S.SNO
FROM S
WHERE S.CITY =
( SELECT S.CITY
FROM S
WHERE S.SNO = 'S1' )
("Azokhoz a szállitókhoz tartozó szállitó számok, melyek ugyan-
abban a városban vannak , mint az S1 szállitó"). Egy összeha-
sonlitás predikátumban egy al-lekérdezésnek (mint ahogy már
jeleztük) csak egyetlen skalár értékét szabad visszaadnia.
Ha ehelyett egyáltalán nem ad vissza értéket , a predikátum ki-
értékelés ismeretlen eredményt ad; ha több értéket ad vissza,
hiba keletkezik.
Megjegyzés: számos további korlátozás van egy összeha-
sonlitás predikátumon belül az al-lekérdezések haszná-
latára:
1. az összehasonlitás predikátumot a bemutatott módon kell
irni úgy ,hogy az al-lekérdezés az összehasonlitó operátor
után jelenjen meg , ne pedig az elött. Például a következö
***ILLEGAL*** ( NINCS MEGENGEDVE ):
SELECT S.SNO
FROM S
WHERE ( SELECT S.CITY
FROM S
WHERE S.SNO = 'S1' ) = S.CITY
2. Nincs lehetöség két al-lekérdezés összehasonlitására.
3. Jólehet, az al-lekérdezések általában tartalmazhatnak
GROUP BY és HAVING klauzulákat, ezek a klauzulák nincsenek
megengedve ebben a kontexusban.
4. A FROM klauzulának az al-lekérdezésben nem szabad
csoportositott nézetre hivatkoznia.
Jegyezze meg azt is ,hogy az "al-lekérdezés" (subquery)
nem szerencsés kifejezés ,mivel az eredmény táblának egyet-
len oszlopának kell lennie (EXIST kontexus kivételével -
lásd a 9.9 alfejezetet) ugyanakkor egy általános lekérde-
zés több oszlopos táblázatot ad vissza." column expression"
(oszlop kifejezés) jobb kifejezés lehetne. Megjegyzés vége.
sql.doc Page: 87
BETWEEN Predikátumok
EGY BETWEEN predikátum szintaxisa:
scalar-expression [NOT] BETWEEN scalar-expression
AND scalar-expression
A BETWEEN predikátum
y BETWEEN x AND z
a definició szerint szemantikailag egyenértékü az alábbival:
x <= y AND y <= z
Az alábbi BETWEEN predikátor
y NOT BETWEEN x AND z
a definició szerint szemantikailag egyenértékü a következö-
vel:
NOT(y BETWEEN x AND z)
Példa:
SELECT P.PNO
FROM P
WHERE P.WEIGHT BETWEEN 16 AND 19
LIKE predikátumok
A LIKE predikátumot minta illesztéshez szánták- vagyis egy
adott karakterfüzér tesztelésére ; annak megállapitására,hogy
összhangban van-e valamilyen elöirt mintával (mely atomkémt
van megadva, nem pedig általános skalár kifejezésként). A szin-
taxis:
column-reference [NOT] LIKE atom [ESCAPE atom]
A "column reference"-nek ( oszlop referenciának) karakterfüzér
tipusú oszlopot kell azonositania. Megadunk erre egy példát:
SELECT P.PNO, P.PNAME
FROM P
WHERE P.PNAME LIKE 'C%'
(azoknak az alkatrészeknek az alkatrész számai és nevei ,ame-
lyek nevei C betüvel kezdödnek")
Eredmény: --- -----
PNO PNAME
--- -----
P5 Cam
sql.doc Page: 88
P6 Cog
A LIKE-t követö atomnak egy karakterfüzért kell reprezentál-
nia. Feltéve, hogy nincs megadva ESCAPE klauzula, ezen ka-
rakterfüzéren belüli karakterek értelmezése a következöképpen
történik.
- Az aláhúzás karakter (_)jelentése: valamilyen egyedülálló
karakter.
- A százalék karakter (%) jelentése: valamilyen n karakter-
böl álló sorozat (ahol n lehet nulla).
- Minden más karakter önmagát jelenti.
Ezért a példában a SELECT-kifejezés (expression ) a P táblá-
ból azokat a sorokat fogja visszaadni, melyeknél a PNAME érték
P nagybetüvel kezdödik és melyek nulla vagy több karakter bár-
milyen sorozatát tartalmazzák ezen C-t követöen.Megadunk erre
néhány további példát:
ADRESS LIKE '%BERKELEY%' - A kiértékelése igaz értéket fog
adni, ha az ADRESS belsejében
barhol megjelenik a "Berkeley"
karakterfüzér.
SNO LIKE 'S__' - A kiértékelése igaz értéket fog
adni, ha SNO pontosan három ka-
rakter hosszú és az elsö karak-
ter "S".
PNAME LIKE '%C__' - A kiértékelése igaz értéket fog
adni, ha PNAME négy karakter
vagy ennél több karakter
hosszúságú és a harmadik karakter
"C".
STRING LIKE '\__%' - A kiértékelése igaz eredményt fog
adni ,ha a STRING egy aláhúzás
ESCAPE '\' karakterrel kezdödik (lásd lej-
jebb)
Ebben a utolsó példában az "\" forditott ferde törtvonal
karakter escape karakterként volt megadva, ami azt jelenti,
hogy az "_"és "%" karakterek számára megadott speciális ér-
telmezés letiltható, ha ezt kivánják,úgy , hogy el kell helyez-
ni az ilyen karakterek elé egy forditott ferde törtvonal ka-
raktert. Egy ESCAPE klauzulában az atomnak egyetlen karaktert
kell reprezentálnia.
Végül , a LIKE predikátum
x NOT LIKE y [ESCAPE z]
a definició szerint szemantikailag egyenértékü a következövel:
sql.doc Page: 89
NOT (x like y [ESCAPE z] )
Null tesztjei
Emlékezzünk vissza a 3.fejezetböl arra ,hogy legalábbis a
WHERE és HAVING céljaira, semmit sem tekintünk úgy ,hogy
null-al egyenlö - még magát a null-t sem. Ehhez hasonlúan,
semmit sem tekintünk úgy, hogy null-nál kisebb vagy null-nál
nagyobb, vagy...,stb. Más szavakkal megfogalmazva,amikor egy
null összehasonlitódik valamilyen értékkel, egy összehason-
litás predikátum kiértékelésében, akkor az eredmény sohasem
igaz (még akkor is igy van, ha ez a másik érték szintén null)
;hanem ehelyett az eredmény minden esetben az ismeretlen igaz-
ság érték. A három igazság érték közötti kölcsonhatást a kö-
vetkezö igazság táblázatok definiálják (a 3. fejezetböl meg-
ismételve):
NOT: AND :T :? :F OR :T :? :F
....:.... .....:..:..:.. ....:.....:..
T : F T :T :? :F T :T :T :T
? : ? ? :? :? :F ? :T :? :?
F : T F :F :F :F F :T :? :F
A következö alakú speciális predikátum:
column-reference IS NULL
van biztositva null-ok jelenlétének teszteléséhez. Például:
SELECT S.SNO
FROM S
WHERE S.STATUS IS NULL
Megjegyezzük , hogy az "S.STATUS = NULL" szintaxis nem meg-
engedett,mivel (mint ahogyan már elmagyaráztuk) semmi sem ,
még maga a null sem ,tekinthetö úgy ,hogy egyenlö legyen a
null-lal, a WHERE vagy HAVING céljaihoz.
Az alabbi predikátum
x IS NOT NULL
definició szerint szemantikailag ekvivalens a következövel.
NOT ( x IS NULL )
IN PREDIKATUMOK
Az összehasonlitás predikatumokhoz hasonlóan az IN predikátu-
mok is két különbözö formátumban jelennek meg . Az elsö való-
jában egyszerüen a röviditése az összehasonlitó predikátumok
valamilyen kombinációjának.
sql.doc Page: 90
scalar-expression [NOT] IN (atom-commalist )
A commalist-nek legalább két atomot kell tartalmaznia.mega-
dunk egy példát egy ilyen predikátum használatára (elsö for-
mátum) :
SELECT P.PNO
FROM P
WHERE P.WEIGHT IN (12,16,17)
Az alábbi IN predikátum
x IN ( a,b ...,z )
a definiciú szerint ekvivalens a következövel:
x = a OR x = b OR ...OR x = z
Az IN predikátum második formátuma :
scalar-expression [NOT] IN subquery
Ez a formátum (a NOT nélkül) úgy van definiálva, hogy sze-
mantikailag azonos az alábbival:
scalar-expression = ANY subquery
(lásd a 9.8 alfejezetet). Azonban ,az IN esetleg intuitiv mó-
don könnyebben érthetö, mint = ANY. Megadunk egy példát IN hasz-
nálatára al-lekérdezéssel:
SELECT S.SNAME
FROM S
WHERE S.SNO IN
( SELECT SP.SNO
FROM SP
WHERE SP.PNO = 'P2'
("Azoknak a szállitóknak a nevei, akik P2 alkatrészt szállita-
nak").Ennek a formátumnak további tárgyalását lásd a következö
alfejezetben.
Végül , az alábbi IN predikátum
x NOT IN rhs
("ahol "rhs" vagy atomok zárójelek közé tett commalist-je, vagy
egy al-lekérdezés") a definició szerint szemantikailag egyenér-
tékü a következövel:
NOT (x IN rhs )
sql.doc Page: 91
9.8 AL-LEKÉRDEZÉSEK
----- ----- ---------
Az al-lekérdezés szintaxisa :
(SELECT [ALL : DISTINCT ] selection table-expression )
ahol a"table-expression"-nak (tábla kifejezésnek ) egy
oszlopos táblát kell reprezentálnia (kivéve EXISTS kontexusá-
ban- lásd a 9.9 alfejezetet ). Egy al-lekérdezés szemantikája
azonos a lekérdezés specifikáció szemantikájával (lásd a
9.2 alfejezetet) az egy-oszlop korlátozás kivételével jegyez-
ze meg, hogy a határoló zárójelek az al-lekérdezések szintaxisa
részének tekintendök.Al-lekérdezéseket használunk:
- Összehasonlitás predikátumokban( lásd a 9.7 alfejezetet)
- IN predikátumokban( lásd a 9.7 alfejezetet )
- Minden vagy valami predikátumokban (lásd a 9.9 alfejezetet)
- létezés tesztekben (lásd a 9.9 alfejezetet )
Al-lekérdezéssel az IN használatára egy egyszerü példa a
9.7 alfejezet végén szerepelt .Most megadunk egy bonyolultabb
példát , amely egy al-lekérdezésnek egy másikba ágyazását mu-
tatja be.
1.Példa: Keressük meg azon szállitóknak a szállitó neveit, a-
kik legalább egy vörös alkatrészt szállitanak.
SELECT S.SNAME
FROM S
WHERE S.SNO IN
( SELECT SP.SNO
FROM SP
WHERE SP.PNO IN
( SELECT P.PNO
FROM P
WHERE P.COLOR = 'Red' ) )
Az érdekesség miatt , megadjuk ezt a példát úgy , hogy ki-
hagyjuk az összes explicit tábla név minösitöt :
SELECT SNAME
FROM S
WHERE SNO IN
( SELECT SNO
FROM SP
WHERE PNO IN
( SELECT PNO
FROM P
WHERE COLOR = 'Red' ) )
Ebben a "megfogalmazásban" minden nem minösitett oszlopne-
vet implicit módon minösit egy táblanév (vagy tartomány válto-
zó név) a "legközelebbi" alkalmazható FROM klauzulából. (Az
sql.doc Page: 92
implicit minösitök meghatározási módjának további részletei
megismerésére az olvasónak a hivatalos szabványos dokumentá-
ciót kell átnéznie. A gyakorlatban explicit minösitést javaso-
lunk , ha esetleg bármilyen kétely felmerülne).
2. példa : Keressük meg azoknak a szállitóknak a szállitó neveit ,
akik P2 alkatrészt szállitanak.
SELECT S.SNAME
FROM S
WHERE 'P2' IN
( SELECT SP.PNO
FROM SP
WHERE SP.SNO = S.SNO )
Ez a példa abban tér el az elözö példáktól , hogy a belsö al-le-
kérdezés nem értékelhetö ki egyszer , s mindenkorra a külsö le-
kérdezés kiértékelése elött , mivel ez a belsö al-lekérdezés
függ egy változótól , nevezetesen az S.SNO-tól , melynek az ér-
téke változik , amint a rendszzer az S tábla különbözö sorait
vizsgálja. Konceptuálisan ezért a kiértékelés a következökép-
pen megy végbe :
(a) A rendszer megvizsgálja az S tábla elsö sorát ; feltételez-
zük , hogy ez az S1-hez tartozó sor. Az S.SNO változónak
igy a jelenlegi értéke S1 , ezért a rendszer kiértékeli a
belsö al-lekérdezést
( SELECT SP.PNO
FROM SP
WHERE SP.SNO = 'S1' )
azért , hogy megkapja a (P1,P2,P3,P4,P5,P6) halmazt. Most
befejezheti az S1-hez feldolgozását; ki fogja választani
az SNAME értéket S1-hez , nevezetesen Smith-et , akkor , és
csakis akkor , ha P2 van a halmazban (természetesen ez igy
van).
(b) Ezután a rendszer továbbhalad , megismétli az ilyen fajta
feldolgozást a következö szállitóhoz és igy tovább , mind-
addig , amig az S tábla minden sorával már foglalkozott.
Egy olyan al-lekérdezést , mint például az ebben a példában
lévö , korrelált al-lekérdezésnek nevezzük. A korrelált al-le-
kérdezés olyan al-lekérdezés , melynek az értéke valamely olyan
változótól függ , amely az értékét valamilyen külsö lekérdezés-
ben kapja meg; az ilyen al-lekérdezés tehát ismétlödöen kiérté-
kelendö (a kérdéses változó minden értékéhez egyszer) , ahelyett
hogy a kiértékelés egyszer , s mindenkorra megtörténjen. Meg-
jegyzés : Egy korrelált al-lekérdezésre másik példát már meg-
adtunk a 9.4 alfejezetben (6. példa).
3.példa : Keressük meg azoknak a szállitóknak a szállitó szá-
mait , akik legalább egy olyan alkatrészt szállitanak , mint
amelyet az S2 szállitó szállit.
sql.doc Page: 93
SELECT DISTINCT SPX.SNO
FROM SP SPX
WHERE SPX.PNO IN
( SELECT SPY.PNO
FROM SP.SPY
WHERE SPY.SNO = 'S2' )
Ez a példa két külön hivatkozást tartalmaz az SP táblára ,
azért a kettö közül legalább az egyiknek explicit tartomány-
változó név segitségével történö hivatkozásban kell lennie
(lásd a 9.5 alfejezetben , a 7. példában a tartományváltozók
leirását ). A szabatos megfogalmazás érdekében , explicit tar-
tományváltozókat (SPX és SPY ) használtunk mindkét hivatkozás-
hoz.
9.9. KVANTOROS PREDIKATOROK
Minden vagy valami predikátumok
A minden vagy valami predikátumnak a következö az általános for-
mátuma
scalar-expression quantified-comparison subquery
ahol egy "quantified comparison" (kvantoros összehasonlitás)
az =,<>,<,>,<=,>=, normál skalár összehasonlitók bármelyike,
de csak egy , melyet az ALL vagy ANY (vagy SOME; a SOME tulajdon-
képpen ugyanaz , mint az ANY , de másképpen kifejezve) kulcs-
szavak közül egyet követ. Minden vagy valami ALL-or-ANY) pre-
dikátum kiértékelése igaz értéket ad , ha a megfelelö össze-
hasonlitás predikátum , az ALL,(illetve ANY) nélkül,
scalar-expression comparasion scalar-value
kiértékelése igaz értéket ad az azon oszlopban lévö skalár ér-
tékek mindegyikéhez (illetve valamelyikéhez), melyet az al-le-
kérdezés reprezentál. Megadunk erre egy példát :
SELECT DISTINCT SP.SNO
FROM SP
WHERE SP.QTY > ALL
( SELECT SP.QTY
FROM SP
WHERE SP.SNO = 'S1' )
("azoknak a szállitóknak a szállitó számai , akik legalább
egy alkatrészt nagyobb mennyiségben szállitanak , mint minden
olyan mennyiség , melyben az S1 szállitó alkatrészt szállit")
Megjegyzés : A minden vagy valami predikátum hibára hajla-
mos (érzékeny). Az itt tárgyalt lekérdezésnek egy nagyon
természetesen angol-nyelvü megfogalmazása az "any" (vala-
mi) szót használná "every" (minden) helyett , ami könnyen
a "hibás" > ANY kvantoros összehasonlitás használatára ve-
zethet > ALL helyett. Ezen kivül a minden vagy valami pre-
sql.doc Page: 94
dikátumok teljesen szükségtelenek , mivel létezés tesztek
formájában mindenképpen mindig átfogalmazhatók (lásd az
alábbi definiciókat).
Jelölje a "$" szimbólum az =,<> , stb. skalár összehason-
litás operátorok valamelyikét , de csak egyet. Ekkor a minden
vagy valami predikátum
x $ANY ( SELECT y FROM T WHERE p )
úgy van definiálva , hogy szemantikailag egyenértékü az alábbi-
val
EXISTS (SELECT* FROM T WHERE (p) AND x $ T.y )
Ehhez hasonlóan , az alábbi minden vagy valami predikátum
x $ALL ( SELECT y FROM T WHERE p )
a definició szerint szemantikailag egyenértékü a következövel
NOT EXISTS ( SELECT* FROM T WHERE (p) AND NOT ( x $ T.y ))
Létezés tesztek
A létezés teszt a következö alakú predikátum
EXISTS subquery
A predikátum kiértékelése hamis értéket ad , ha az al-lekérdezés
kiértékelése üres halmazt eredményez , az érték egyébként igaz.
Megjegyzés : Ebben a speciális kontextusban (csak) az al-lekérde-
zés számára meg van engedve , hogy "SELECT*"-ot használjon
"SELECT value-expression " (SELECT érték-kifejezés) helyett , még
akkor is , ha az eredménynek egynél több oszlopa van. Valóban a
"SELECT*" a normál eset.
1.Példa : keressük meg azon szállitóknak a szállitó neveit , akik
legalább egy alkatrészt szállitanak.
SELECT S.SNAME
FROM S
WHERE EXISTS
( SELECT*
FROM SP
WHERE SP.SNO = S.SNO )
2.Példa. Keressük meg azoknak a szállitóknak a szállitó neveit ,
akik egy alkatrészt sem szállitanak.
SELECT S.SNAME
FROM S
WHERE NOT EXISTS
( SELECT*
FROM SP
sql.doc Page: 95
WHERE SP.SNO = S.SNO )
3.Példa: Keressük meg azoknak a szállitóknak a szállitó neveit ,
akik minden alkatrészt szállitanak.
SELECT S.SNAME
FROM S
WHERE NOT EXISTS
( SELECT*
FROM P
WHERE NOT EXISTS
( SELECT*
FROM SP
WHERE S.SNO = SP.SNO
AND SP.PNO = P.PNO ) )
4.Példa: Keressük meg azoknak a szállitóknak a szállitó szá-
mait , akik legalább egy alkatrészt nagyobb mennyiségben szál-
litanak , mint minden olyan mennyiség , melyben az S1 szálli-
tó alkatrészt szállit.
SELECT DISTINCT SPX.SNO
FROM SFX
WHERE NOT EXISTS
( SELECT*
FROM SP SPY
WHERE SPY.SNO = 'S1'
AND SPY.QTY >= SPX.QTY )
Hasonlitsa össze ezt a feladatnak a korábban látható
">ANY" megoldásával.
sql.doc Page: 96
10
-------- ----- ------ ----- ----- ----------------
Beágyazott SQL
10.1 BEVEZETÉS
Mint ahogy a 3.2 alfejezetben elmagyaráztuk , az X3H2 dokumen-
táció "mellékletek" vagy függelékek egész sorát tartalmazza ,
melyek az SQL-nek egy "beágyazott" verzióját definiálják , -va-
gyis az SQL-nek egy olyan verzióját , melyet arra terveztek ,
hogy közvetlenül beépithetö legyen host programokba (vagyis
azokba a host programokba , amelyek COBOL , FORTRAN , Pascal és
PL/I nyelven vannak irva). Jóllehet , természetesen nem része
a hivatalos szabványnak , a beágyazott SQL mégis sokféle módon
a teljes javaslat legközvetlenebbül látható aspektusát repre-
zentálja. Ebben a fejezetben részletesen megvizsgáljuk a beá-
gyazott SQL-t. A világos megfogalmazás érdekében , a leirásun-
kat PL/I-re alapozzuk , de természetesen az elgondolásoknak a
nagy része más host nyelvekre is leforditható (le van fordit-
va), úgy , hogy csak kismértékü változtatások szükségesek. A
10.2 alfejezet egy komplett beágyazott SQL - PL/I programot ad
meg; a 10.3 alfejezet ezen példa által bemutatott részletes
nyelvi szempontokat tárgyalja.
10.2 EGY TELJES PÉLDA
Beágyazott SQL utasitásokkal rendelkezö host nyelvü program -
"beágyazott SQL host program" egy egyébként standard host
programból , plusz egy "beágyazott SQL deklaráció részböl",
beágyazott cursor definició készletéböl , beágyazott kivételes
állapot deklarációk készletéböl és egy beágyazott SQL utasi-
tás készletböl áll. A 10.1. ábrában bemutatjuk a 6. fejezet-
böl (6.1. ábra) vett példának egy beágyazott SQL verzióját.
A következö fejezet részletes magyrázatait (nagyrészt) ennek
a példának a segitségével adjuk meg.
10.1. ábra. Beágyazott SQL-re példa
(A program megjegyzések csak magyar nyelven láthatók , a for-
ditó megjegyzése)
SQLEX: PROC OPTIONS (MAIN) ;
EXEC SQL BEGIN DECLARE SECTION ;
/* program input */
DCL GIVENPNO CHAR(6) ;
DCL GIVENCIT CHAR(15) ;
DCL GIVENINC DECIMAL(3) ;
DCL GIVENLVL DECIMAL(3) ;
/* célok a "FETCH SUPPLIER"-hez */
DCL SNO CHAR(5) ;
DCL SNAME CHAR(20) ;
sql.doc Page: 97
DCL STATUS DECIMAL(3) ;
DCL CITY CHAR(15) ;
/* SQL visszatérési kód változó */
DCL SQLCODE FIXED BINARY(15) ;
EXEC SQL END DECLARE SECTION ;
/* housekeeping változók */
DCL DISP CHAR(7) ;
DCL MORE_SUPPLIERS BIT(1) ;
/* kivételes állapot deklarációk */
EXEC SQL WHENEVER NOT FOUND CONTIUNE ;
EXEC SQL WHENEVER SQLERROR CONTIUNE ;
/* adatbázis kivételes állapot kezelö */
ON CONDITION ( DBEXCEPTION )
BEGIN ;
PUT SKIP LIST ( SQLCODE ) ;
EXEC SQL ROLLBACK WORK ;
PUT SKIP LIST ( SQLCODE ) ;
GO TO QUIT ;
END ;
/* cursor definició */
EXEC SQL DECLARE Z CURSOR FOR
SELECT S.SNO, S.SNAME, S.STATUS, S.CITY
FROM S
WHERE S.SNO IN
( SELECT SP.SNO
FROM SP
WHERE SP.PNO = :GIVENPNO ) ;
/* fö program logika */
GET LIST ( GIVENPNO, GIVENCIT, GIVENINC, GIVENLVL ) ;
EXEC SQL OPEN Z ;
IF NOT ( SQLCODE = 0 )
THEN SIGNAL CONDITION (DBEXCEPTION ) ;
MORE_SUPPLIERS = '1'B ;
DO WHILE ( MORE_SUPPLIERS ) ;
EXEC SQL FETCH Z INTO :SNO, :SNAME, :STATUS, :CITY ;
SELECT ; /* a PL/I SELECT, nem egy SQL SELECT */
WHEN ( SQLCODE = 100 )
MORE_SUPPLIERS = '0'B ;
WHEN NOT (SQLCODE =100 | SQLCODE = 0 )
SIGNAL CONDITION ( DBEXCEPTION ) ;
WHEN ( SQLCODE = 0 )
DO ;
DISP = 'bbbbbbb' ;
IF CITY = GIVENCIT
THEN
DO ;
EXEC SQL UPDATE S
SET STATUS = S.STATUS + :GIVENINC
WHERE S.SNO ;
IF NOT ( SQLCODE = 0 )
THEN SIGNAL CONDITION ( DBEXCEPTION ) ;
DISP = 'UPDATED' ;
END ;
ELSE
sql.doc Page: 98
IF STATUS< GIVENLVL
THEN
DO ;
EXEC SQL DELETE
FROM SP
WHERE SP.SNO = :SNO ;
IF NOT ( SQLCODE = 0 | SQLCODE = 100 )
THEN SIGNAL CONDITION ( DBEXCEPTION ) ;
EXEC SQL DELETE
FROM S
WHERE S.SNO = :SNO ;
IF NOT ( SQLCODE = 0 )
THEN SIGNAL CONDITION ( DBEXCEPTION ) ;
DISP = 'DELETED' ;
END ;
PUT SKIP LIST ;
( SNO, SNAME, STATUS, CITY, DISP ) ;
END ; /* WHEN ( SQLCODE = 0 ) ... */
END ; /* PL/I SELECT */
END ; /* DO WHILE */
EXEC SQL CLOSE Z ;
EXEC SQL COMMIT WORK ;
QUIT: RETURN ;
END ; /* SQLEX */
10.3 FELMERüLö SZEMPONTOK
1. A beágyazott SQL utasitásokat EXEC SQL elötag elözi meg
(úgy, hogy ezek könnyen megkülönböztethetök legyenek a host
nyelv utasitásaitól) és a következöképpen fejezödnek be (zá-
ródnak le):
COBOL -END-EXEC
FORTRAN -folytatás karakter hiánya (vagyis nincs expli-
cit terminátor)
PASCAL -pontosvesszö
PL/I -pontosvesszö
2. Végrehajtható SQL utasitás mindenhol megjelenhet, ahol
végrehajtható host utasitás megjelenhet. Megjegyezzük, hogy
az "Executable" (végrehajtható) minösitö, itt: DECLARE CURSOR,
nem végrehajtható utasitás, ugyanez érvényes a WHENEVER-re
(lásd késöbb), valamint a BEGIN-re és END DECLARE SECTION-ra
is.
3. Az SQL utasitások tartalmazhatnak hivatkozásokat host válto-
zókra. Az ilyen hivatkozások elé kettöspontot kell elhelyezni
azért, hogy megkülönböztethetök legyenek az SQL oszlop nevek-
töl. Nem szabad minösitetteknek vagy index-szel ellátva lenniük
és skalárokat, nem pedig tömböket vagy struktúrákat kell azo-
nositaniuk. Megjelenhetnek SQL adatmanipuláló utasitásokban
ugyanazokon a helyeken, mint ahol paraméterek jelenhetnek meg a
manipulativ utasitásokban a modul nyelvben (lásd az 5.2 alfeje-
zetet).
sql.doc Page: 99
4. Minden host változónak, melyre SQL utasitásokban hivatko-
zás fog történni, definiáltnak kell lennie a "beágyazott SQL
deklarálási részen" belül, melyet a BEGIN és END DECLARE SEC-
TION utasitások határolnak (lásd a 10.1 ábrát). Az ilyen host
változó definiciók szándékosan bizonyos egyszerü formátumokra
vannak korlátozva (például tömbök és struktúrák nincsenek meg-
engedve), az olvasónak a szabvány dokumentációjában kell meg-
néznie a részleteket. Host változónak nem szabad megjelennie
beágyazott SQL utasitásban, mielött ennek a definiálása meg-
történt volna.
5. Minden beágyazott SQL programnak tartalmaznia kell SQLCODE
(FORTRAN-ban SQLCODE) nevü host változót. Miután valamilyen SQL
utasitás végrehajtása megtörtént, a programnak egy numerikus
állapot jelzö adódik vissza az SQLCODE-ban. Lásd az 5.2 alfe-
jezetben az SQLCODE értékek részleteit.
6. A host változóknak olyan adattipussal kell rendelkezniük,
mely kompatibilis azoknak az oszlopoknak az SQL adattipusával,
amelyekkel a változókat össze kell hasonlitani, vagy amelyek-
hez vagy amelyekböl a host változókat meg kell adni. Az adatti-
pus kompatibilitás az 5.2 alfejezetben van definiálva.
7. A host változóknak és SQL oszlopoknak azonos nevük is lehet.
8. Minden SQL utasitást elvben a visszaadott SQLCODE érték
tesztjének kell követnie. A WHENEVER utasitás azért van megad-
va, hogy egyszerüsitse ezt a folyamatot. A WHENEVER utasitás-
nak a szintaxisa az alábbi:
EXEC SQL WHENEVER condition action terminator
ahol "terminator" (terminátor) a fenti 1. szakaszban elmagya-
rázott terminátor, "condition" (feltétel) vagy SQLERROR vagy
NOT FOUND és "action" (tevékenység) vagy CONTINUE vagy egy GO
TO utasitás. A WHENEVER nem végrehajtható utasitás; hanem egy
direktiva az SQL nyelv processzorhoz. "WHENEVER" feltétel GO
TO Cimke" (WHENEVER condition GO TO label) eredményeként ez
a processzor beszúr egy "IF feltétel GO TO cimke" (IF con-
dition GO TO label" utasitást minden végrehajtható SQL utasi-
tás után, amelyet megtalál. "WHENEVER feltétel CONTINUE" (WHE-
NEVER condition CONTINUE) eredményeként nem szúr be semmilyen
ilyen utasitást, ennek hallgatólagosan az a jelentése, hogy a
programozó fog beszúrni kézzel ilyen utasitásokat. A két "fel-
tétel" a következöképpen van definiálva:
NOT FOUND means SQLCODE = 100
SQLERROR means SQLCODE < 0
Minden WHENEVER utasitás, amelyet az SQL processzor megtalál,
(egy adott feltétel esetén) a programszöveg szekvenciális le-
tapogatás során, érvényteleniti az elözöt, amelyet megtalál
(mely ugyanilyen feltételt tartalmaz).
A minta programban (10.1 ábra) minden kivételes állapot
sql.doc Page: 100
tesztelés explicit módon van végrehajtva oktatási okok miatt.
9. Indikátor változók olyan módon használhatók (és igy is
kell használni ezeket), mely pontosan analóg azzal a móddal,
ahogyan a modul nyelvben az indikátor paramétereket használ-
ják (lásd az 5.3 alfejezetet). Például:
EXEC SQL SELECT P.WEIGHT
INTO :WEIGHT INDICATOR :WEIGHT_INDIC
FROM P
WHERE P.PNO = :PNO ;
sql.doc Page: 101
11
-------- ----- ------ ----- ----- --------- ----- ------
DEFINICIOS KITERJESZTESEK
11.1 BEVEZETÉS
Az X3H2 bizottság jelenleg az alap SQL szabványhoz javasolt ki-
terjesztések sorozatán dolgozik. Ebben a fejezetben és a követ-
kezöben rövid pillantást vetünk ezekre a javaslatokra. Figyel-
meztetjük az olvasót arra, hogy ebben a szakaszban ezek még csak
javaslatok; kétségtelenül számos különbözö módon meg fognak
változni, mielött elérik a hivatalos szabvány állapotot (ha
valaha is elérik). Ennek ellenére, érdemesnek látszik, hogy
eltöltsünk velük egy kis idöt ebben a könyvben, már csak azért
is, mivel valamennyire jelzik, hogy az X3H2 jelenleg hogyan
gondolkodik és ebböl következöen azt jelzik, hogy a nyelv va-
lószinüleg hogyan fejlödik a közeljövöben.
A javaslatok általános területre sorolhatók, adat defini-
ció kiterjesztések (vagyis kiterjesztések a séma nyelvhez) és
adatmanipuláló kiterjesztések (vagyis kiterjesztések a modul
nyelvhez). A jelen fejezet a definiciós kiterjesztésekkel fog-
lalkozik; a manipulativ kiterjesztéseket a 12. fejezetben tár-
gyaljuk.
Megjegyzés: Az X3H2 kiterjesztéseket javasol az SQL-nek
két új host nyelvbe, nevezetesen a C-be és az Ada-ba beágya-
zásához is. A részleteket itt nem tárgyaljuk; természetesen
nagy általánosságban ezek ugyanazok, mint amit a 10. fejezetben
tárgyaltunk.
11.2 ALAPÉRTÉKEK
Egy új (opcionális) "default clause" (alapértelmezés szerinti
klauzula) adódik egy oszlop definicióhoz a CREATE TABLE-en be-
lül a következö szintaxissal:
DEFAULT ( literal : NULL : USER )
Például :
CREATE TABLE S
( SNO CHAR(5) NOT NULL ,
SNAME CHAR(20) DEFAULT '???',
STATUS DECIMAL(3) NOT NULL DEFAULT 0,
CITY CHAR(15) DEFAULT ' ',
UNIQUE ( SNO ))
Az alapértelmezés szerinti klauzula célja annak az érték-
nek a megadása , amelyet a jelzett helyre kell bevinni , ha a
felhasználó nem ad meg értéket az INSERT-ben. "DEFAULT NULL"
azt jelenti , hogy null az alapérték.(NOT NULL-t nem szabad
alkalmazni , ha DEFAULT NULL van megadva); "DEFAULT literal"
sql.doc Page: 102
azt jelenti , hogy a megadott literál az alapérték ; "DEFAULT
USER" azt jelenti , hogy az USER értéke (lásd a 4.3. alfejezetet)
az alapérték.
Ha nincs explicit alapérték klauzula megadva , akkor :
(a) Ha NOT NULL érvényes a kérdéses oszlopra , akkor az oszlop-
nak nincs alapértéke (vagyis , egy értékre szükség van eh-
hez az oszlophoz az INSERT-ben);
(b) Ha NOT NULL nem érvényes a kérdéses oszlopra , akkor DEFAULT
NULL a feltételezés (ennek a felvétele történik).
Megjegyzés : A felhasználó definiálta alapértékek ("DEFAULT
literal") lehetövé teszik , hogy a felhasználó elkerüljön
néhány olyan nehézséget , amely az SQL tipusu null-okkal
van kapcsolatban.
11.3 CHECK KÖVETELMÉNYEK
A CREATE TABLE utasitás kibövül azért , hogy bármennyi "CHECK
klauzulát" tartalmazzon. A CHECK klauzula szintaxisa :
CHECK (search-condition)
A CHECK klauzula célja egy olyan feltétel - vagyis integ-
ritás követelmény - megadása , amelyet a táblában minden sornak
ki kell elégitenie (állandóan). Megadunk erre egy példát :
CREATE TABLE S
( SNO .... etc.)
CHECK (S.STATUS BETWEEN 10 AND 100 )
CHECK (S.CITY IN ( 'Athens','London','Madrid','Oslo',
'Paris','Rome'))
CHECK (S.CITY <> 'London' OR S.STATUS = 20 )
Ezek közül a CHECK klauzulák közül az elsö kijelenti , hogy
az S.STATUS értékeinek elöirt tartományon belül kell lenniük;
a második kijelenti , hogy az S.CITY értékeit egy elöirt listá-
ból kell kivenni ; a harmadik azt állitja , hogy ha az S.CITY
értéke London , akkor az S.STATUS értékének 20-nak kell lennie.
Ezen megszigoritások bármelyikének megszegésére irányuló ki-
sérlet (INSERT vagy UPDATE müveleten keresztül) visszautasitás-
ra fog kerülni.
CHECK klauzulában a keresési feltételnek bizonyos korlá-
tozott alakunak kell lennie , mely technikailag megszigoritás
predikátumként ismert. Egy megszigoritás predikátum olyan fel-
tétel , mely adott sorhoz csak ezen sor elszigetelt vizsgálatá-
val értékelhetö ki - nincs szükség arra , hogy bármilyen más
sor, ebböl a táblázatból vagy bármi másból , vizsgálatra
kerüljön annak meghatározására , hogy a feltétel igaz-e a vizs-
gált sorhoz. SQL meghatározásokkal ez a követelmény azt jelen-
ti , hogy a feltételnek nem szabad tartalmaznia semmilyen al-le-
kérdezést vagy függvényt és az egyetlen tábla , amelyre a felté-
telben hivatkozás lehet (explicit vagy implicit módon) a kér-
déses tábla (vagyis az a tábla , amelyik magának a CREATE TABLE
sql.doc Page: 103
utasitásnak a tárgya).
Ha egy CHECK klauzula a táblának csak egyetlen oszlopára
hivatkozik (mint a fenti elsö két példában), akkor ez opcioná-
lisan ezen oszlop definiciója részeként adható meg , a tábla
szinten megadás helyett. Például :
CREATE TABLE S
( SNO ... ,
SNAME ... ,
STATUS ... CHECK (S.STATUS BETWEEN 10 AND 100 ),
CITY ... CHECK (S.CITY IN ( 'Athens','London',
'Madrid','Oslo',
'Paris','Rome') ) )
CHECK ( S.CITY <> 'London' OR S.STATUS = 20 )
Azonban , jegyezzük meg , hogy a harmadik CHECK klauzulának is
megadottnak kell lennie tábla szinten , mivel két különbözö
oszlopra hivatkozik.
11.4 REFERENCIALIS INTEGRITAS
Megjegyzés : Ez egy fontos témakör. A referenciális integritás
fontos része a relációs modellnek , ugyanakkor sajnálatos dolog,
hogy a legtöbb meglévö relációs termék - nevezetesen a legtöbb
SQL-en alapuló termék - jelenleg nem támogatja ezt.
Elsödleges kulcsok
Egy opcionális PRIMARY KEY (elsödleges kulcs) klauzula van
hozzáadva a CREATE TABLE -hez. Például :
CREATE TABLE S
( SNO CHAR(5) NOT NULL,
SNAME CHAR(20) DEFAULT '???',
STATUS DECIMAL(3) NOT NULL DEFAULT 0,
CITY CHAR(15) DEFAULT ' ',
PRIMARY KEY ( SNO ) )
Az alábbi megadás
PRIMARY KEY ( column-commalist )
szemantikailag azonos a következö megadással
UNIQUE (column-commalist)
(lásd a 3.3. alfejezetet) , azzal a kivétellel , hogy :
(a) Egy adott CREATE TABLE utasitás legfeljebb egy PRIMARY
KEY klauzulát tartalmazhat (ezen kivül egy vagy több
UNIQUE klauzulát tartalmazhat , ha a kérdéses táblának egy
vagy több további egyedi azonositója is van ); és
(b) Az elsödleges kulcs (vagyis azoknak az oszlopoknak a kom-
binációja , amelyeket a PRIMARY KEY klauzula azonosit) spe-
ciális kezelésben részesül minden megfelelö idegen kulcs
sql.doc Page: 104
specifikációban (lásd késöbb a jelen alfejezetben).
Emlékezzünk vissza , hogy egy UNIQUE klauzulában (és ebböl kö-
vetkezik , hogy PRIMARY KEY klauzulában) megemlitett bármilyen
oszlopnak NOT NULL-ként megadottnak kell lennie.
Magyarázat: a PRIMARY KEY klauzulának opcionálisnak kell
lennie a multtal kompatibilitáshoz , de nagyon javasoljuk ,
hogy minden CREATE TABLE a gyakorlatban tartalmazzon i-
lyen klauzulát. A relációs modell szükségessé teszi az
elsödleges kulcsokat.
Megjegyzés : Ha egy elsödleges kulcs egyetlen oszlop , mint
a fenti példában , akkor ez az oszlop definició részeként
adható meg külön PRIMARY KEY klauzulán keresztüli megadás
helyett. Például :
CREATE TABLE S
( SNO CHAR(5) NOT NULL PRIMARY KEY ,
SNAME CHAR(20) DEFAULT '???',
STATUS DECIMAL(3) NOT NULL DEFAULT 0,
CITY CHAR(15) DEFAULT ' ')
Azonban , az ilyen megadás ugy van definiálva , hogy egyszerüen
a korábban látható verzió röviditése.
Idegen kulcsok
1. A relációs modellben egy idegen kulcs egy oszlop (vagy
oszlopok kombinációja) egyetlen T2 táblában , amelynek az
értékei meg kell , hogy egyezzenek valamilyen T1 táblában
lévö elsödleges kulcs értékeivel (kissé pontatlanul megfo-
galmazva).Például, a szállitók és alkatrészek adatbázisban
az SP tábla SP.SNO oszlopa egy idegen kulcs , mely megegyezik
az S tábla S.SNO elsödleges kulcsával; minden szállitó szám-
érték , amely az SP.SNO oszlopban megjelenik , az S.SNO oszlop-
ban is meg kell , hogy jelenjen (egyébként az adatbázis nem
lenne konzisztens). Ehhez hasonlóan az SP tábla SP.PNO osz-
lopa olyan idegen kulcs , ami megegyezik a P tábla P.PNO el-
södleges kulcsával ; az SP.PNO oszlopban megjelenö minden al-
katrész szám értéknek meg kell jelennie a P.PNO oszlopban is. /*/
----- ----- ---------------
* Megjegyezzük , hogy ezzel ellentétben , létezhet elsödleges kulcs
érték megegyezö idegen kulcs érték nélkül. Például , ha adva van
a szokásos szállitók és alkatrészek minta adatok - lásd a 2.1
ábrát - az 55-ös szállitó jelenleg nem szállit semmilyen alkat-
részt és ebböl következik , hogy az 55 érték megjelenik az S.SNO
oszlopban , de nem jelenik meg az SP.SNO oszlopban.
2. Egyébként , az "idegen kulcs" (foreign key) fenti nem pon-
tos definiálásunkban a T1 és T2 jelü két táblának nem kell
szükségképpen különbözönek lennie. Vagyis egy tábla tartal-
mazhat olyan idegen kulcsot , melynek értékeire szükség van
sql.doc Page: 105
ugyanazon tábla elsödleges kulcsa értékeivel illesztéshez.
Erre egy példa az alábbi tábla lehet
CHILDOF ( CHILD , MOTHER )
ahol minden egyes MOTHER (ANYA) , ugyanakkor valamilyen más
MOTHER (ANYA) CHILD (GYERMEKE) is (stb) . Itt CHILD az elsöd-
leges kulcs és MOTHER egy idegen kulcs , amelyik a CHILD-et
illeszti , (vagyis adott sorban lévö MOTHER értéknek egyen-
lönek kell lennie valamilyen más sorban lévö CHILD érték-
kel.
A mostani példa csak egy speciális esete egy általánosabb
helyzetnek , nevezetesen annak a helyzetnek , amelyben T1 , T2
T3,...,Tn táblák ciklikusak , ugy , hogy T1 tartalmaz egy i-
degen kulcsot , mely a T2-re hivatkozik , T2 tartalmaz egy ide-
gen kulcsot , mely T3-ra hivatkozik ,..., és Tn tartalmaz egy
idegen kulcsot , mely a T1-re hivatkozik.
3. A CHILDOF példa is arra szolgál , hogy további szempontot
mutasson be - nevezetesen azt , hogy az idegen kulcsok számára
(az elsödleges kulcsoktól eltéröen) esetenként meg kell enged-
ni , hogy null-okat elfogadhassanak. A most vizsgált esetben
feltételezhetöen lesz legalább egy sor a CHILDOF táblában ,
melyhez a MOTHER ismeretlen.
4. Adott idegen kulcs érték az ezt tartalmazó sorból (sorok-
ból) arra a sorra hivatkozást reprezentál , amelyik az illesz-
kedö elsödleges kulcs értéket tartalmazza. Ezért annak bizto-
sitásának problémáját , hogy valójában minden idegen kulcs ér-
ték illeszkedjen (megegyezzen) a megfelelö elsödleges kulcs
értékéhez (értékével) a referenciális integritás problémájaként
ismerjük. A jelenlegi SQL szabványban (és a legtöbb meglévö
relációs termékben ) a referenciális integritást a felhasználó-
nak kell fenntartania (vagyis specifikus alkalmazási kóddal).
Nyilvánvaló , hogy kivánatosabb volna , ha képesek lennénk arra ,
hogy deklarativ módon referenciális követelményeket adjunk meg
az adatdefinició részeként és ezeket a rendszerrel tartatnánk
fenn (öriztetnénk) a felhasználó helyett. Mindig is ez volt
a relációs modell szándéka és ez a szándéka az alábbiakban
leirt , javasolt idegen kulcs kiterjesztésnek.
5. Egy adott CREATE TABLE utasitás tetszöleges számu FOREIGN
KEY klauzulát tartalmazhat. Például :
CREATE TABLE SP
( SNO CHAR(5) NOT NULL,
PNO CHAR(6) NOT NULL,
QTY DECIMAL(5) NOT NULL DEFAULT 0 )
PRIMARY KEY ( SNO , PNO ) )
FOREIGN KEY ( SNO ) REFERENCES S
FOREIGN KEY ( PNO ) REFERENCES P
A két FOREIGN KEY klauzula közül az elsö kifejezi , hogy
az SP.SNO oszlop az S tábla elsödleges kulcsával illeszkedö
sql.doc Page: 106
idegen kulcs (jegyezze meg , hogy az S táblának tartalmaznia
kell egy elsödleges kulcsot ehhez a FOREIGN KEY megadáshoz
ahhoz , hogy megengedett legyen ). A második FOREIGN KEY klau-
zula ezzel analóg.
1. Megjegyzés : Itt az történik , hogy a két idegen kulcs kö-
zül mindkettö a "tartalmazó" tábla elsödleges kulcsának
komponense. Azonban általában bármelyik oszlop vagy osz-
lopok bármilyen kombinációja idegen kulcs lehet. Például
az S tábla CITY oszlopa idegen kulcs lehet , ha az adatbá-
zis tartalmazott városokat reprezentáló másik táblát.
2. Megjegyzés : Ha egy idegen kulcs egyetlen oszlop , mint
a fenti mindkét példában a REFERENCES megadás bevihetö az
oszlopdefinicióba , ahelyett , hogy külön FOREIGN KEY klau-
zula részévé kelljen tenni. Például :
CREATE TABLE SP
( SNO CHAR(5) NOT NULL REFERENCES S,
PNO CHAR(6) NOT NULL REFERENCES P,
QTY DECIMAL(5) NOT NULL DEFAULT 0 )
PRIMARY KEY (SNO, PNO ) )
Azonban , az ilyen megadások egyszerüen csak a korábban látha-
tó megadások röviditéseként vannak definiálva.
7. Legyen T2.FK idegen kulcs és legyen T1.PK az illeszkedö
(megegyezö) elsödleges kulcs .Az egyszerüség kedvéért felté-
telezzük , hogy T1.PK egyetlen oszlop , és ebböl következik , hogy
T2.FK is egyetlen oszlop. /*/
----- ----- -------------
* Ezt a feltételezést csupán azért tesszük meg , hogy egyszerüsit-
sük a bemutatást. Több oszlopos idegen kulcsokra általánositás
unalmas , fárasztó feladat , de eléggé nyilvánvaló (jóllehet az
X3H2 ugy tünik , hogy néhány szükségtelen bonyolitást vezet be).
A részleteket itt kihagyjuk.
A T2.FK és T1.PK közötti referenciális követelmény ki van e-
légitve , akkor és csakis akkor , ha a T2 tábla minden t2 sora
olyan , hogy vagy t2.FK null (ha nullok meg vannak engedve
T2.FK-hoz), vagy létezik olyan t1 sor T1-ben , hogy t1.PK
egyenlö t2.FK-val.
8. A T2.FK és T1.PK között referenciális követelmény megör-
zése érdekében a rendszernek vagy (a) vissza kell utasitania
minden müveletet , amely ezt megtenné vagy (b) végre kell haj-
tania valamilyen megfelelö kompenzáló tevékenységet. Azok a
müveletek , amelyek potenciálisan megsérthetik a követelményt ,
az alábbiak :
- Egy INSERT a T2 táblában vagy UPDATE a T2.FK oszlopban
olyan (nem null) értéket vihet be a T2.FK-hoz , amely nem
létezik T1.PK értékeként.
sql.doc Page: 107
- Egy DELETE a T1 táblán vagy update a T1.PK oszlopon
"lógó hivatkozásokat" hagyhatna a T2 táblában (vagyis ,
olyan sorokat a T2 táblában , amelyek nem hivatkoznak sem-
milyen sorra a T1-ben.
Az elsö esetben a müvelet egyszerüen visszautasitódik. A
második esetben a végrehajtott tevékenység attól a törlési sza-
bálytól vagy aktualizálasi szabálytól (amelyik alkalmazható)
függ , amelyet akkor adtak meg , amikor az idegen kulcs definiá-
lásra került. Altalában minden FOREIGN KEY klauzula tartalmaz
mind törlési szabályt , mind aktualizálási szabályt :
FOREIGN KEY (column ) REFERENCES table
[ON DELETE ( RESTRICT : CASCADE : SET NULL : SET DEFAULT )]
[ON UPDATE ( RESTRICT : CASCADE : SET NULL : SET DEFAULT )]
Vizsgáljuk meg elöször a törlési szabályt. RESTRICT (amely
az alpértelmezés) , azt jelenti , hogy a T1 egyik sorának tör-
lési kisérlete sikertelen lesz , ha bármilyen megegyezö (illesz-
kedö ) sor létezik T2-ben . A többi három megadás azt jelenti ,
hogy a T1 sor törlését megelözi egy kompenzálási tevékenység
a következöképpen.
- CASCADE azt jelenti , hogy a T2-ben lévö megegyezö sorok is
törlésre kerülnek
- SET NULL azt jelenti , hogy a T2.FK értékek , a T2-ben a
megegyezö sorokban , nullára állitódnak (ebben az esetben
T2.FK-hoz nem szabad NOT NULL-nak megadottnak lennie).
- SET DEFAULT azt jelenti , hogy T2.FK értékei , T2-ben a
megegyezö sorokban ,az alkalmazható alapértékre állitód-
nak (a T2.FK-nak rendelkeznie kell alapértékkel ebben az
esetben ; ezen kivül már léteznie kell T1 olyan sorának ,
amelyik ezt az alapértéket a T1.PK értékeként tartalmazza).
Egyébként megjegyezzük , hogy annak a felhasználónak , aki
az eredeti törlési kérést kiadja , nem kell rendelkeznie expli-
cit DELETE privilégiummal (vagy UPDATE privilégiummal , az adott
helyzettöl függöen) a hivatkozási táblázatban azért , hogy a
fenti kompenzálási tevékenységek végrehajtásra kerüljenek.
Az aktualizálási szabály értelmezése analóg : RESTRICT (a-
mely az alapértelmezés) azt jelenti , hogy az a kisérlet , amely-
nek során a T1 valamelyik sorában lévö T1.PK értéket aktuali-
zálni próbálják , sikertelen lesz , ha bármilyen illeszkedö
(megegyezö) sor létezik T2-ben ; a többi három megadás azt je-
lenti , hogy T1.PK-ban az aktualizálást megelözi kompenzáló te-
vékenység a következöképpen :
- CASCADE azt jelenti , hogy T2.FK értéke , T2-ben az illesz-
kedö (megegyezö) sorokban , megfelelö módon aktualizálódik.
- SET NULL azt jelenti , hogy T2.FK értékei , T2-ben a megfe-
lelö (illeszkedö) sorokban , null-ra állnak (ebben az eset-
ben T2.FK-hoz nem szabad NOT NULL-t megadni).
- SET DEFAULT azt jelenti , hogy T2.FK értékei T2-ben a meg-
sql.doc Page: 108
felelö (illeszkedö) sorokban , az alkalmazható alapértékek-
re állnak (ebben az esetben T2.FK-nak tartalmaznia kell
egy alapértéket ; ezen kivül már léteznie kell T1 olyan so-
rának , amelyik tartalmazza ezt az alapértéket a T1.PK ér-
tékeként).
Ismét elmondjuk , hogy annak a felhasználónak , aki az ere-
deti aktualizálási kérést kiadja , nem kell explicit UPDATE
privilégiummal rendelkeznie a hivatkozó táblában azért , hogy
a fenti kompenzálási tevékenységeket végréhajthassa.
Megjegyzések :
1. Kivánatos lehet "other" (egyéb) opció támogatása az
ON DELETE és ON UPDATE klauzulákban. A RESTRICT-CASCADES-
SET NULL - SET DEFAULT opciók nem szükségképpen terjednek
ki minden lehetöségre.
2. Az X3H2 javaslat jelenlegi verziója valójában lehetö-
vé teszi , hogy a hivatkozott táblázatban bármilyen UNIQUE
oszlopra vagy oszlop kombinációra idegen kulcs hivatkoz-
hasson , nem szükségképpen csak elsödleges kulcs. A
FOREIGN KEY klauzula név szerint adhatja meg a hivatkozott
oszlopot (oszlopokat). Ha nem ez történik , alapértelmezés
szerint a hivatkozott tábla elsödleges kulcsának használa-
ta történik (ez a normál eset ; lásd a fenti példákat).
A jelen könyv irójának véleménye szerint az a képesség ,
hogy olyan egyedi azonositóra hivatkozás történjen , ame-
lyik nem az elsödleges kulcs , jó példa a "hamis általá-
nosságra": A többlet szabadságfok ténylegesen nem biztosit
semmilyen többlet funkcionalitást , egyszerüen csak nagyobb
bonyolultsághoz vezet.
A REFERENCES privilégium
Annak elöirására , hogy a T2 tábla T2.FK oszlopa egy idegen
kulcs , mely a T1 tábla T1.PK oszlopára hivatkozik a T2 tábla
létrehozójának rendelkeznie kell a REFERENCES privilégiummal
a T1.PK oszlopban. A T1 tábla létrehozója automatikusan bir-
tokolja a REFERENCES privilégiumot a T1 tábla minden oszlopá-
ban és megadhatja ezt a privilégiumot (oszlopról oszlopra a-
lapon , ha ugy kivánja) , más felhasználóknak.
Magyarázat : A fentiekböl következöen ugy tünik , hogy T1
és T2 két tábla , melyeknek különbözö U1 és U2 tulajdono-
saik vannak , ezek közül egyszerre mindkettö nem tartalmazhat
a másikra hivatkozó idegen kulcsot (mivel T1 nem hozható
létre mindaddig , amig U1 birtokolja a REFERENCES privilégi-
umot a T2-ben és U1-nek nem adhatja meg ezt a privilégiumot
az U2 , mindaddig , amig az U2 létre nem hozta T2-t és U2
nem hozhatje létre T2-t , mindaddig , amig T2 birtokolja a
references privilégiumot T1-en , stb .., stb.) Ez nem lát-
szik nagyon kivánatos korlátozásnak.
sql.doc Page: 109
12
-------- ----- ------ ----- ----- --------- ----- ------
Manipulativ kiterjesztések
12.1 ORTOGONALITAS TOVABBFEJLESZTÉSEK
A szabványos SQL nem nagyon ortogonális nyelv. A jelen könyv
korábbi részében leirt részletes kritikák közül sok lényegé-
ben ezen általános (és nagyon széleskörü) panasz specifikus
esetei. Az ortogonalitás függetlenséget jelent : egy nyelv or-
togonális , ha független fogalmak függetlenek maradnak és nem
keverednek egymással zürzavaros módokon. Az ortogonalitás hiá-
nyára egy példát (sok közül egyet ) az SQL-ben az a szabály ad,
amelyiknek az az értelme , hogy beépitett függvényhez tartozó
argumentum nem lehet másik függvény hivatkozás (a további tár-
gyalást lásd az A. függelékben).
Az ortogonalitás kivánatos , mivel minél keésbé ortogoná-
lis egy nyelv , annál bonyolultabb és (paradox módon , de ezzel
egyidejüleg) annál kevésbé hatékony."Az ortogonális konstruk-
ció maximalizálja a kifejezöképességet , miközben elkerüli a
veszedelmes felesleges dolgokat" (A.van Wijngaarden és munka-
társai , eds., Revised Report on the Algorithmic Language Algol
68, (Módositott jelentés algol 68-as algoritmikus nyelvröl )
Springer-Verlag, 1976-os kiadványból). Az SQL , a jelenleg de-
finiált állapotban , rendkivül fogyatékos ebböl a szempontból.
Ezt a tényt felismerve az X3H2 bizottság jelenleg kisérletet
tesz a korlátozások közül néhány eltávolitására a hivatalos
szabványból. A jelen alfejezetben fölvázoljuk az ebben az i-
rányban tett fö javaslatokat.
1. A lekérdezés kifejezések - vagyis a "query specifications"
(lekérdezés specifikációk) UNION-jai (lásd a 9.1. alfejezetet)
- már nincsenek arra korlátozva , hogy csak cursor definició
kontextusában jelenhetnek meg. Ehelyett , most már a következö
kontextusokban is meg vannak engedve (amely lényegében azt
jelenti , hogy az UNION most meg van engedve ezekben a kontextu-
sokban):
(a) CREATE VIEW-en belül (a nézet érvényességi körének defi-
niálásához);
(b) Al-lekérdezésben (vagyis egy al-lekérdezés nemcsak egy-
szerüen lekérdezési kifejezés zárójelek közé zárva - ki-
véve , hogy az al-lekérdezés kiértékelésének eredménye még
mindig egy oszlopos tábla kell, hogy legyen , kivéve , ha
ez egy EXISTS argumentum;
(c) INSERT-en belül (több soros formátum) a beszurandó sorok
definiálására;
(d) FROM klauzulán belül.
Ezek közül az utolsó bizonyos további magyarázatot igé-
nyel. A FROM klauzula altalános szintaxisa még mindig :
sql.doc Page: 110
FROM table-reference-commalist
de a "table reference" (tábla hivatkozás) most ki van terjeszt-
ve a következöképpen :
table-reference
::= table [[AS] range-variable]
:( query-expression )[AS] range-variable
Az "AS" csak zavart okoz mindkét esetben . Az elsö alak lé-
nyegében ugyanaz , mint a mai szabványos SQL-ben ; a második be-
vezeti azt az elgondolást , hogy, ahelyett , hogy a FROM operan-
dusait megnevezett táblákra korlátoznánk , tábla értékü kife-
jezések lehetnek. Például :
SELECT MAX ( X.CITY )
FROM ( SELECT S.CITY FROM S
UNION
SELECT P.CITY FROM P )
Azonban , jegyezzük meg , hogy UNION még mindig nincs meg-
engedve SELECT utasitásban (vagyis szingli SELECT-ben).
Magyarázat: Ez a kiterjesztés, jóllehet kivánatos olyan
mértékben, ahogyan ismertettük, még mindig nem ismeri el
azt az alapvetö szempontot, hogy egy tábla nevet csak egy
általános tábla (vagy lekérdezés) kifejezés speciális
esetének szabad tekinteni. Magyarázat vége.
A "query specification" (lekérdezés megadás) szintaktikai
kategóriának most csak lekérdezés kifejezés komponenseként van
jelentése (lényegében egy lekérdezés megadás egyszerüen olyan
lekérdezés kifejezés, mely nem tartalmaz semmilyen UNION-t.)
2. DISTINCT-et tartalmazó függvényhez az argumentum már nincs
arra korlátozva, hogy oszlop referencia legyen, hanem ehelyett
bármilyen skalár kifejezés lehet.
3. Elvetették a csoportositott nézetekre vonatkozó korlátozá-
sokat (például egy FROM klauzula, amely hivatkozást tartalmaz
csoportositott nézetekre, nem tartalmazhat semmilyen más tábla
hivatkozásokat). Tulajdonképpen a "grouped view" (csoportosi-
tott nézet) kifejezést teljes mértékben elvetették.
4. Most lehetöség van nevek bevitelére SELECT klauzulában lé-
vö származtatott oszlopokhoz, mint például a következökben:
SELECT P.PNO, ( P.WEIGHT 454 ) AS GMWT
FROM P
ORDER BY GMWT
Itt az "AS" nem zavaró - erre szükség van. A bevitt névre hi -
vatkozni lehet az ORDER BY-ban (minta példában), de nem le-
het hivatkozni semmilyen más klauzulában (WHERE, stb.).
sql.doc Page: 111
12.2. CSúSZTATó CURSOROK
Emlékezzünk vissza a 6. fejezetböl, hogy a szabványos SQL-ben
az egyetlen cursor elmozditási müvelet a FETCH (jelentése
"fetch next" (következö fetch-je)). A csúsztató cursor a
standard cursornak egy kiterjesztett verziója, olyan verzió,
melyben támogatva vannak más cursor elmozditási müveletek.
Egy cursort csúsztató cursorként a cursor definicióban a
CURSOR kulcsszót közvetlenül megelözö SCROLL kulcsszó megje-
lenése definiálja. Például:
DECLARE X SCROLL CURSOR
FOR SELECT ... etc
A FETCH utasitás ki van bövitve úgy, hogy tartalmazzon
egy "fetch orientation" (fetch orientáció) megadást a követke-
zöképpen:
FETCH [fetch-orientation] cursor INTO target-commalist
ahol "fetch orientation" a következök valamelyike:
NEXT
PRIOR
FIRST
LAST
ABSOLUTE scalar-expression
RELATIVE scalar-expression
(NEXT az alapértelmezés és az egyetlen megengedett opció, ha
a cursor nem csúsztató cursor). NEXT (KÖVETKEZÖ), PRIOR (ELÖZÖ),
FIRST (ELSÖ) és LAST (UTOLSó) önmagát magyarázzák. Az utolsó
két esetben, legyen n a skalár kifejezés (amelynek exakt nume-
rikus tipusúnak kell lennie kiértékelésének (kiszámitásának)
eredménye; ennek nem szabad nullának lennie. ABSOLUTE n elmoz-
ditja a cursort az n. sorhoz (a végétöl visszafelé számolva,
ha n negativ). RELATIVE n elmozditja a cursort az n-edik sor-
ra az aktuális helytöl kezdve (ismét visszafelé számitva, ha
n negativ).
sql.doc Page: 112
A. Függelék
Minta feladatok gyüjteménye
A.1 BEVEZETÉS
Ebben a fejezetben minta feladatok "testbed"-jét adjuk meg azok-
nak az olvasóknak, akik ki óhajtják próbálni képességeiket néhány
szabványos SQL kód megirásában. A feladatok (nagyrészt) a szerzö-
nek a Guide to DB2 (A DB2 bevezetése) (Addison-Wesley, 1984) cimü
könyvéböl vett feladatokon alapulnak. Ezek nagy része a "szállitók-
alkatrészek-projectek" adatbázist tartalmazza (lásd az A.1 ábrát).
Az adatbázis információkat tartalmaz a szállitókról (suppliers, S),
alkatrészekröl (parts, P) és projectekröl (projects, J). A szálli-
tókat, alkatrészeket és projecteket egyedi módon azonositja a szál-
litó szám (SNO), alkatrész szám (PNO), illetve project szám (JNO).
Egy SPJ (szállitmány) sornak az a jelentése, hogy a megadott szál-
litó leszállitja a megadott alkatrészt a megadott projecthez a mega-
dott mennyiségben (és az (SNO-PNO-JNO kombináció egyedi módon azono-
sit egy ilyen sort).
A.2 ADAT DEFINICIó
A.2.1 Irjunk egy alkalmas sémát (vagyis CREATE TABLE utasitások hal-
mazát) a szállitók-alkatrészek projectek adatbázishoz.
A.2.2 Hozzunk létre egy nézetet, mely a (csak) Londonban megvalósuló
projectekhez tartalmaz project információkat.
A.2.3 Definiáljuk a szállitók - és - alkatrészek adatbázisának SP
tábláját a szállitók-alkatrészek-projectek adatbázis SPJ táblá-
ja nézeteként.
sql.doc Page: 113
A.1 ábra A szállitók - alkatrészek - projectek adatbázis
S --- ----- ------ ------ SPJ --- --- --- ---
SNO SNAME STATUS CITY SNO PNO JNO QTY
--- ----- ------ ------ --- --- --- ---
S1 Smith 20 London S1 P1 J1 200
S2 Jones 10 Paris S1 P1 J4 700
S3 Blake 30 Paris S2 P3 J1 400
S4 Clark 20 London S2 P3 J2 200
S5 Adams 30 Athens S2 P3 J3 200
S2 P3 J4 500
P --- ----- ----- ------ ------ S2 P3 J5 600
PNO PNAME COLOR WEIGHT CITY S2 P3 J6 400
--- ----- ----- ------ ------ S2 P3 J7 800
P1 Nut Red 12 London S2 P5 J2 100
P2 Bolt Green 17 Paris S3 P3 J1 200
P3 Screw Blue 17 Rome S3 P4 J2 500
P4 Screw Red 14 London S4 P6 J3 300
P5 Cam Blue 12 Paris S4 P6 J7 300
P6 Cog Red 19 London S5 P2 J2 200
S5 P2 J4 100
J --- -------- ------ S5 P5 J5 500
JNO JNAME CITY S5 P5 J7 100
--- -------- ------ S5 P6 J2 200
J1 Sorter Paris S5 P1 J4 100
J2 Punch Rome S5 P3 J4 200
J3 Reader Athens S5 P4 J4 800
J4 Console Athens S5 P5 J4 400
J5 Collator London S5 P6 J4 500
J6 Terminal Oslo
J7 Tape London
Ahol:
SNO = Szállitó száma
SNAME = szállitó neve
STATUS = állapot
CITY = város
PNO = alkatrész szám
PNAME = alkatrész neve
COLOR = szin
WEIGHT = súly
Nut = anya
Bolt = fejescsavar
Screw = csavar
Cam = bütyök
Cog = fogaskerék
Red = vörös
Green = zöld
Blue = kék
JNO = project száma
JNAME = project megnevezés
Sorter = rendezö
Punch = lyukasztó
Reader = olvasó
sql.doc Page: 114
Console = konzol
Collator = válogatógép
terminal = terminál
Tape = szalag
A.2.4 Hozzunk létre egy nézetet a szállitók-alkatrészek-projec-
tek adatbázisból, mely tartalmazza az összes olyan projec-
tet (csak project szám és város oszlopok), melyeknek az S1
szállitó szállit, vagy amelyek P1 alkatrészt használnak.
A.2.5 Hozzunk létre egy nézetet, amely a nem ugyanabban a vá-
rosban lévö szállitókhoz és alkatrészekhez tartozó szállitó
számokból és alkatrész számokból áll.
A.2.6 Adva van az alábbi nézet definició:
CREATE VIEW SUMMARY ( SNO, PNO, MAXQ , MINQ, AVGQ )
AS SELECT SPJ.SNO, SPJ.PNO,
MAX ( SPJ.QTY ), MIN ( SPJ.QTY ), AVG ( SPJ.QTY )
FROM SPJ
GROUP BY SPJ.SNO, SPJ.PNO
HAVING SUM ( SPJ.QTY ) > 50
Határozza meg, hogy a következö lekérdezés kifejezések és
aktualizálási müveletek közül melyek azok, amelyek megenge-
dettek és, azokhoz, amelyek megengedettek, adja meg a lefor-
ditott ekvivalenseket.
(a) SELECT *
FROM SUMMARY
(b) SELECT *
FROM SUMMARY
WHERE SUMMARY.SNO <> 'S1'
(c) SELECT *
FROM SUMMARY
WHERE SUMMARY.MAXQ > 250
(d) SELECT SUMMARY.MAXQ - SUMMARY.MINQ, SUMMARY.SNO, SUMMARY.PNO
FROM SUMMARY
WHERE SUMMARY.SNO = 'S1'
AND SUMMARY.PNO = 'P1'
(e) SELECT SUMMARY.SNO
FROM SUMMARY
GROUP BY SUMMARY.SNO
(f) SELECT SUMMARY.SNO, SUMMARY.MAXQ
FROM SUMMARY
GROUP BY SUMMARY.SNO, SUMMARY.MAXQ
(g) SELECT S.SNO, SUMMARY.AVGQ
FROM S, SUMMARY
WHERE S.SNO = SUMMARY.SNO
sql.doc Page: 115
(h) UPDATE SUMMARY
SET SNO = 'S2'
WHERE SUMMARY.SNO = 'S1'
(i) UPDATE SUMMARY
SET SUMMARY.MAXQ = 1000
WHERE SUMMARY.SNO = 'S1'
(j) DELETE
FROM SUMMARY
WHERE SUMMARY.SNO = 'S1'
A.3 ADAT MANIPULáLáS: VISSZANYERéSI MÜVELETEK
-------- ----- ------ --------
Irjon lekérdezés kifejezéseket a következökhöz.
Egyszerü lekérdezések
A.3.1 Keressük meg minden project minden részletét.
A.3.2 Keressük meg minden londoni project minden részletét.
A.3.3 Keressük meg azon szállitók szállitó számait, akik J1
projectnek szállitanak.
A.3.4 Keressük meg az összes olyan szállitmányt, ahol a meny-
nyiség 300 és 750 (ezt is beleértve) közötti tartományban van.
A.3.5 Keressük meg az osszes alkatrész-szin/alkatrész-város kom-
bináció listáját, ismétlödö sor szin/város párok kihagyásával.
A.3.6 Keressük meg az összes olyan szállitmányt, ahol a mennyiség
nem nulla.
A.3.7 Keressük meg azokat a project számokat és városokat, ahol a
város nevében a második betüként "o" szerepel.
Összekapcsolások
A.3.8 Keressük meg az összes szállitó-szám/alkatrész szám/project
szám hármasokat, amelyeknél a jelzett szállitó, alkatrész
és project ugyanabban a városban van.
A.3.9 Keressük meg az összes olyan szállitó szám/alkatrész szám/
project szám hármast, amelyeknél a jelzett szállitó/alkatrész
és project közül nem mindegyik ugyanabban a városban van.
A.3.10 Keressük meg az összes olyan szállitószám/alkatrészszám/project
szám hármast, amelyeknél a jelzett szállitó, alkatrész és pro-
ject közül kettö ugyanabban a városban van.
A.3.11 Keressük meg azoknak az alkatrészeknek az alkatrészszámait,
amelyeket londoni szállitó szállitott.
A.3.12 Keressük meg azoknak az alkatrészeknek az alkatrészszámait,
amelyeket londoni szállitó szállit londoni projectekhez.
A.3.13 Keressük meg az összes olyan város név párt, amelyeknél az
elsö városban lévö szállitó szállit a második városban lévö
projecthez.
A.3.14 Keressük meg az összes olyan alkatrésznek az alkatrész számát,
amelyeket bármilyen projecthez ugyanabban a városban lévö
szállitó szállit, mint amelyikben a project van.
A.3.15 Keressük meg az összes olyan projecthez tartozó project szá-
sql.doc Page: 116
mot, amelyben legalább egy, nem ugyanabban a városban lévö
szállitó szállit.
A.3.16 Keressük meg az összes olyan alkatrész szám párt, amelyeknél
a jelzett mindkét alkatrészt valamilyen (ugyanaz) a szállitó
szállitja.
Al-lekérdezések
A.3.17 Keressük meg azoknak a projecteknek a neveit, melyekhez az S1
szállitó szállit.
A.3.18 Keressük meg azoknak az alkatrészeknek a szineit, melyeket az
S1 szállitó szállit.
A.3.19 Keressük meg azoknak az alkatrészeknek az alkatrész számait,
amelyeket valamilyen londoni projecthez szállitanak.
A.3.20 Keressük meg azoknak a projecteknek a project számait, amelyek
legalább egy olyan alkatrészt használnak, mely az S1 szállitó-
tól áll rendelkezésre.
A.3.21 Keressük meg azoknak a szállitóknak a szállitó számait, akik
legalább egy olyan alkatrészt szállitanak, melyet viszont lega-
lább egy olyan szállitó szállit, aki legalább egy vörös alkat-
részt szállit.
A.3.22 Keressük meg azoknak a szállitóknak a szállitó számait, akiknek
az állapota kisebb, mint az S1 szállitó állapota.
A.3.23 Keressük meg azoknak a szállitóknak a szállitó számait, akik
olyan mennyiségben szállitanak valamilyen projecthez P1 alkat-
részt, amely nagyobb, mint az ehhez a projecthez a P1 alkatrész
átlagos szállitmány mennyisége.
EXISTS
A.3.24 Ismételjük meg az A.3.19 sz. feladatot úgy, hogy a megoldásban
használjunk EXISTS-et.
A.3.25 Ismételjük meg az A.3.20 sz. feladatot úgy, hogy a megoldásban
használjunk EXISTS-et.
A.3.26 Keressük meg azoknak a projecteknek a project számait, melyek-
hez nincs olyan londoni szállitó, aki vörös alkatrészt szállit.
A.3.27 Keressük meg azoknak a projecteknek a project számait, melyek-
hez kizárólag (teljesen) az S1 szállitó szállit.
A.3.28 Keressük meg azoknak az alkatrészeknek az alkatrész számait,
melyeket az összes londoni projecthez szállitanak.
A.3.29 Keressük meg azoknak a szállitóknak a szállitó számait, akik
ugyanazt az alkatrészt szállitják minden projecthez.
A.3.30 Keressük meg azoknak a projecteknek a project számait, melyek-
hez az S1 szállitótól rendelkezésre álló összes alkatrészt
szállitják.
A következö négy (A.3.31-A.3.34) feladatban alakitsa vissza a bemuta-
tott SQL kifejezést ekvivalens, angol nyelvü megfogalmazásra.
sql.doc Page: 117
A.3.31 SELECT DISTINCT SPJX.JNO
FROM SPJ SPJX
WHERE NOT EXISTS
( SELECT *
FROM SPJ SPJY
WHERE SPJY.JNO = SPJX.JNO
AND NOT EXISTS
( SELECT *
FROM SPJ SPJZ
WHERE SPJZ.PNO = SPJY.PNO
AND SPJZ.SNO = 'S1' ))
A.3.32 SELECT DISTINCT SPJX.JNO
FROM SPJ SPJX
WHERE NOT EXISTS
( SELECT *
FROM SPJ SPJY
WHERE EXISTS
( SELECT *
FROM SPJ SPJA
WHERE SPJA.SNO = 'S1'
AND SPJA.PNO = SPJY.PNO )
AND NOT EXISTS
( SELECT *
FROM SPJ SPJB
WHERE SPJB.SNO = 'S1'
AND SPJB.PNO = SPJY.PNO
AND SPJB.JNO = SPJX.JNO ))
A.3.33 SELECT DISTINCT SPJX.JNO
FROM SPJ SPJX
WHERE NOT EXISTS
( SELECT *
FROM SPJ SPJY
WHERE EXISTS
( SELECT *
FROM SPJ SPJA
WHERE SPJA.PNO = SPJY.PNO
AND SPJA.JNO = SPJX.JNO )
AND NOT EXISTS
( SELECT *
FROM SPJ SPJB
WHERE SPJB.SNO = 'S1'
AND SPJB.PNO = SPJY.PNO
AND SPJB.JNO = SPJX.JNO ))
sql.doc Page: 118
A.3.34 SELECT DISTINCT SPJX.JNO
FROM SPJ SPJX
WHERE NOT EXISTS
( SELECT *
FROM SPJ SPJY
WHERE EXISTS
( SELECT *
FROM SPJ SPJA
WHERE SPJA.SNO = SPJY.SNO
AND SPJA.PNO.IN
( SELECT P.PNO
FROM P
WHERE P.COLOR = 'RED' )
AND NOT EXISTS
( SELECT *
FROM SPJ SPJB
WHERE SPJB.SNO = SPJY.SNO
AND SPJB.JNO = SPJX.JNO )))
Beépitett függvények
A.3.35 Keressük meg azoknak a projecteknek az össz számát, amelyeket
az S1 szállitó szállit.
A.3.36 Keressük meg annak a P1 alkatrésznek a teljes mennyiségét, a-
melyet az S1 szállitó szállit.
A.3.37 Egy projecthez leszállitandó minden alkatrészhez keressük meg
az alkatrész számát, a project számát és a megfelelö teljes
mennyiséget.
A.3.38 Keressük meg azoknak a projecteknek a project számait, amelyek
városa az elsö az ilyen városok abc-szerinti listájában.
A.3.39 Keressük meg azokhoz a projectekhez tartozó project számokat,
melyekhez P1 alkatrészt olyan átlagos mennyiségben szállitanak,
amely nagyobb, mint az a legnagyobb mennyiség, melyben valamilyen
alkatrészt a J1 projecthez szállitanak.
A.3.40 Keressük meg azoknak a szállitóknak a szállitó számait, akik
valamilyen projecthez olyan mennyiségben szállitanak P1 alkat-
részt, amelyik nagyobb, mint az átlagos mennyiség, amelyben
ehhez a projecthez P1 alkatrész szállitása történik.
Egyesités
A.3.41 Allitsuk össze az összes olyan város listáját, melyben legalább
egy szállitó, alkatrész vagy project van.
A.3.42 Mutassuk meg a következö eredményét:
SELECT P.COLOR
FROM P
UNION
SELECT P.COLOR
FROM P
sql.doc Page: 119
A.4 ADAT MANIPULáCIó: AKTUALIZALASI MÜVELETEK
Irjunk INSERT, DELETE vagy UPDATE utasitásokat (az adott helyzet-
nek megfelelöen) a következö feladatok mindegyikéhez:
A.4.1 Változtassuk meg az összes vörös alkatrész szinét narancs-
sárgára.
A.4.2 Töröljük az összes olyan projectet, melyhez nincs szállitmány.
A.4.3 Növeljük meg 10 %-kal a szállitmány szállitási mennyiségét
minden olyan szállitmány esetén, mely vörös alkatrészt szálli-
tó szállitótól érkezik.
A.4.4 Törölje az összes római projectet és minden ehhez tartozó szál-
litmányt.
A.4.5 Helyezzen be egy új szállitót (S10) az S táblába. A név és város
"White" (fehér), illetve "New York"; az állapot még nem ismert.
A.4.6 Allitsunk össze egy táblát, mely azon alkatrészek alkatrész szá-
mainak listáját tartalmazza, amelyeket vagy londoni szállitó
szállit, vagy amelyeket egy londoni projecthez szállitanak.
A.4.7 Allitsunk össze egy táblát, mely azon projectek project
számainak listáját tartalmazza, amelyek vagy londoni projec-
tek, vagy amelyekhez londoni szállitó szállit.
A.4.8 Adjunk hozzá 10-et az összes olyan szállitó állapotához,
amelynek az állapota jelenleg kisebb, mint az S4 szállitó ál-
lapota.
A.5 BEAGYAZOTT SQL
A.5.1 Irjunk beágyazott SQL programot minden szállitó felsoro-
lására, szállitó szám sorrendben. A felsorolásban minden szál-
litót közvetlenül követnie kell az összes olyan projectnek,
amelyhez ez a szállitó szállit, project szám sorrendben.
A.5.2 Módositsuk az A.5.1 számú feladatunkhoz elkészitett
megoldásunkat úgy, hogy ezen kivül tegyük a következöket: (a)
növeljük meg az állapotot 50 %-kal minden olyan szállitó ese-
tén, akik kettönél több projecthez szállitanak; (b) töröljünk
minden olyan szállitót, aki egyáltalán semmilyen projecthez sem
szállit.
A.5.3(Nehezebb). Adva vannak az alábbi táblák:
CREATE TABLE PARTS
( PNO ... NOT NULL,
DESCRIPTION ... )
CREATE TABLE PART_STRUCTURE
( MAJOR_PNO ... NOT NULL,
MINOR_PNO ... NOT NULL,
QTY ... ) ;
ahol PART_STRUCTURE mutatja, hogy mely alkatrészek (MAJOR_PNO)
mely más alkatrészeket (MINOR_PNO) tartalmaznak elsö szintü
komponensként, irjunk beágyazott SQL programot adott alkatrész
sql.doc Page: 120
minden komponens alkatrészének felsorolására, minden szinthez
(az "alkatrészek robbantási" problémája).
A.6 VALASZOK
Ebben az alfejezetben megadjuk a lehetseges válaszok halmazát
az A.2-A.5 alfejezetek feladataira. A bemutatott megoldások
nem szükségképpen az egyetlen lehetséges megoldást jelen-
tik.
A.2.1 CREATE TABLE S
( SNO CHAR(5) NOT NULL UNIQUE,
SNAME CHAR(20),
STATUS DECIMAL(3),
CITY CHAR(15) )
CREATE TABLE P
( PNO CHAR(6) NOT NULL UNIQUE,
PNAME CHAR(20),
COLOR CHAR(6),
WEIGHT DECIMAL(3),
CITY CHAR(15) )
CREATE TABLE J
( JNO CHAR(4) NOT NULL UNIQUE,
JNAME CHAR(10),
CITY CHAR(15) )
CREATE TABLE SPJ
( SNO CHAR(5) NOT NULL,
PNO CHAR(6) NOT NULL,
JNO CHAR(4) NOT NULL,
QTY DECIMAL(5)
UNIQUE ( SNO, PNO, JNO ) )
A.2.2 CREATE VIEW LONDON PROJECTS ( JNO, JNAME, CITY )
AS SELECT J.JNO, J.JNAME, J.CITY
FROM J
WHERE J.CITY = 'London'
A.2.3 CREATE VIEW SP ( SNO, PNO, QTY )
AS SELECT SPJ.SNO, SPJ.PNO, SUM ( SPJ.QTY )
FROM SPJ
GROUP BY SPJ.SNO, SPJ.PNO
A.2.4 CREATE VIEW JC ( JNO, CITY )
AS SELECT DISTINCT J.JNO. J.CITY
FROM J, SPJ
WHERE J.JNO = SPJ.JNO
AND ( SPJ.SNO = 'S1' OR
SPJ.PNO = 'P1' )
A.2.5 CREATE VIEW NON_COLOCATED ( SNO, PNO)
AS SELECT S.SNO, P.PNO
FROM S, P
sql.doc Page: 121
WHERE S.CITY <> P.CITY
A.2.6 Csak (a), (b) és (d) van megengedve. A (d) lefordi-
tott verziója:
SELECT MAX(SPJ.QTY)-MIN(SPJ.QTY), SPJ.SNO, SPJ.PNO
FROM SPJ
WHERE SPJ.SNO= 'S1'
AND SPJ.PNO= 'P1'
GROUP BY SPJ.SNO, SPJ.PNO
HAAVING SUM(SPJ.QTY)> 50
A.3.1 SELECT J.JNO, J.JNAME, J.CITY
FROM J
A.3.2 SELECT J.JNO, J.JNAME, J.CITY
FROM J
WHERE J.CITY='London'
A.3.3 SELECT DISTINCT SPJ.SNO
FROM SPJ
WHERE SPJ.JNO='J1'
ORDER BY SPJ.SNO
A.3.4 SELECT SPJ.SNO, SPJ.PNO, SPJ.JNO, SPJ.QTY
FROM SPJ
WHERE SPJ.QTY BETWEEN 300 AND 750
A.3.5 SELECT DISTINCT P.COLOR, P.CITY
FROM P
A.3.6 SELECT SPJ.SNO, SPJ.PNO, SPJ.JNO, SPJ.QTY
FROM SPJ
WHERE SPJ.QTY IS NOT NULL
A.3.7 SELECT J.JNO, J.CITY
FROM J
WHERE J.CITY LIKE '_0%'
A.3.8 SELECT S.SNO, P.PNO, J.JNO
FROM S, P, J
WHERE S.CITY = P.CITY
AND P.CITY = J.CITY
A.3.9 SELECT S.SNO, P.PNO, J.JNO
FROM S, P, J
WHERE NOT
( S.CITY = P.CITY AND P.CITY = J.CITY )
A.3.10 SELECT S.SNO, P.PNO, J.JNO
FROM S, P, J
WHERE S.CITY <> P.CITY
AND P.CITY <> J.CITY
AND J.CITY <> S.CITY
sql.doc Page: 122
A.3.11 SELECT DISTINCT SPJ.PNO
FROM SPJ, S
WHERE SPJ.SNO = S.SNO
AND S.CITY = 'London'
A.3.12 SELECT DICTINCT SPJ.PNO
FROM SPJ, S, J
WHERE SPJ.SNO = S.SNO
AND SPJ.JNO = J.JNO
AND S.CITY = 'London'
AND J.CITY = 'London'
A.3.13 SELECT DISTINCT S.CITY, J.CITY
FROM S, SPJ, J
WHERE S.SNO = SPJ.SNO
AND SPJ.JNO = J.JNO
A.3.14 SELECT DISTINCT SPJ.PNO
FROM SPJ, S, J
WHERE SPJ.SNO = S.SNO
AND SPJ.JNO = J.JNO
AND S.CITY = J.CITY
A.3.15 SELECT DISTINCT J.JNO
FROM SPJ, S, J
WHERE SPJ.SNO = S.SNO
AND SPJ.JNO = J.JNO
AND S.CITY <> J.CITY
A.3.16 SELECT SPJX.PNO, SPJY.PNO
FROM SPJ.SPJX, SPJ.SPJY
WHERE SPJX.SNO = SPJY.SNO
AND SPJX.PNO > SPJY.PNO
A.3.17 SELECT J.JNAME
FROM J
WHERE J.JNO IN
( SELECT SPJ.JNO
FROM SPJ
WHERE SPJ.SNO = 'S1' )
A.3.18 SELECT DISTINCT P.COLOR
FROM P
WHERE P.PNO IN
( SELECT SPJ.PNO
FROM SPJ
WHERE SPJ.SNO = 'S1' )
A.3.19 SELECT DISTINCT SPJ.PNO
FROM SPJ
WHERE SPJ.JNO IN
( SELECT J.JNO
FROM J
WHERE J.CITY = 'London' )
sql.doc Page: 123
A.3.20 SELECT DISTINCT SPJ.JNO
FROM SPJ
WHERE SPJ.PNO IN
( SELECT SPJ.PNO
FROM SPJ
WHERE SPJ.SNO = 'S1' )
A.3.21 SELECT DISTINCT SPJ.SNO
FROM SPJ
WHERE SPJ.PNO IN
( SELECT SPJ.PNO
FROM SPJ
WHERE SPJ.SNO IN
( SELECT SPJ.SNO
FROM SPJ
WHERE SPJ.PNO IN
( SELECT P.PNO
FROM P
WHERE P.COLOR = 'Red' ) ) )
A.3.22 SELECT S.SNO
FROM S
WHERE S.STATUS <
( SELECT S.STATUS
FROM S
WHERE S.SNO = 'S1' )
A.3.23 SELECT DISTINCT SPJX.SNO
FROM SPJ SPJX
WHERE SPJX.PNO = 'P1'
AND SPJX.QTY >
( SELECT AVG (SPJY.QTY)
FROM SPJ SPJY
WHERE SPJY.PNO = 'P1'
AND SPJY.JNO = SPJX.JNO )
A.3.24 SELECT DISTINCT SPJ.PNO
FROM SPJ
WHERE EXISTS
( SELECT *
FROM J
WHERE J.JNO = SPJ.JNO
AND J.CITY = 'London' )
A.3.25 SELECT DISTINCT SPJX.JNO
FROM SPJ SPJX
WHERE EXISTS
( SELECT *
FROM SPJ SPJY
WHERE SPJY.PNO = SPJX.PNO
AND SPJY.SNO = 'S1' )
A.3.26 SELECT J.JNO
FROM J