online kép - Fájl  tube fájl feltöltés file feltöltés - adja hozzá a fájlokat online fedezze fel a legújabb online dokumentumok Kapcsolat
   
 

Letöltheto dokumentumok, programok, törvények, tervezetek, javaslatok, egyéb hasznos információk, receptek - Fájl kiterjesztések - fajltube.com

 

Online dokumentumok - kep
   
kategória
 

Biológia állatok Fizikai Földrajz Kémia Matematika Növénytan Számítógépes
Filozófia
Gazdaság
Gyógyszer
Irodalom
Menedzsment
Receptek
Vegyes

 
 
 
 













































 
 

SQL referencia

számítógépes

Fájl küldése e-mail Esszé Projekt


egyéb tételek

 
I/19 Vírusok és vírusvédelem
A programozasi technikak és jellemzőik
A .NET
A képernyőtervezés elemei
Kommunikació és tarsadalom az Interneten, a XX. szazad végén
Egy operaciós rendszer bemutatasa
A MagicDVDRipper kezelése
BGP - Border Gateway Protokol
Szervezési ismeretek
Az SQL nyelv hasznalata az ORACLE adatbazis-kezelő rendszerben
 
 
           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
        



Találat: 1245