Datalog: [Ullman-Widom]
5.3-5.4. Datalog szabályok és lekérdezések >> lásd az előadás anyagát Datalog (jelszóval)
>> és a múlt heti feladatokat: 2.6.
Lekérdezések kifejezése Datalogban
Rekurzió: [Ullman-Widom]
10.2.
Rekurzió az SQL-ben (466-474.o.)
>>lásd az előadás anyagát Rek.Datalog, Rek.SQL (jelszóval)
Rek1.feladat:
- Az
alábbi feladat a
tankönyv (Ullman-Widom kék
könyv) 10.2 szakaszára épül. Jaratok(legitarsasag,
honnan, hova, koltseg, indulas, erkezes)
táblában repülőjáratok
adatait
tároljuk.
-
Készítsünk ebből
saját példányt: jaratok_tabla.txt
és az
alapján
dolgozzunk
DROP TABLE jaratok;
CREATE TABLE jaratok(
legitarsasag CHAR(2),
honnan VARCHAR2(10),
hova VARCHAR2(10),
koltseg NUMBER,
felszallas NUMBER,
erkezes NUMBER);
INSERT INTO jaratok VALUES('UA', 'SF','DEN', 1000, 930,1230);
INSERT INTO jaratok VALUES('AA', 'SF','DAL', 10000, 900,1430);
INSERT INTO jaratok VALUES('UA','DEN','CHI', 500, 1500,1800);
INSERT INTO jaratok VALUES('AA','DEN','DAL', 2000, 1400,1700);
INSERT INTO jaratok VALUES('AA','DAL','CHI', 600, 1530,1730);
INSERT INTO jaratok VALUES('AA','DAL', 'NY', 2000, 1500,1930);
INSERT INTO jaratok VALUES('AA','CHI', 'NY', 3000, 1900,2200);
INSERT INTO jaratok VALUES('UA','CHI', 'NY', 2000, 1830,2130);
- (Papíros feladat) Fejezzzük ki Datalog
programmal, hogy mely (x,y)
város
párokra
lehetséges egy vagy
több
átszállással eljutni x
városból y városba?
- Megoldás:
1. Eljut(X, Y)
<- Jaratok(L, X, Y, K, F, E)
2. Eljut(X, Y) <-
Eljut(X, Z) AND Jaratok(L, Z, Y, K, F, E)
- (Papíros feladat) A fenti rekurzív Datalog
programot
írd át az SQL3 szabványban
szereplő WITH RECURSIVE
utasítással! (Csak
papíron! Oracle nem támogatja).
- Megoldás:
WITH RECURSIVE eljut AS
(SELECT honnan, hova FROM jaratok
UNION
SELECT eljut.honnan, jaratok.hova
FROM eljut, jaratok
WHERE eljut.hova = jaratok.honnan)
SELECT * FROM eljut;
- (Gépes feladatok: Oracle CONNECT BY PRIOR, lásd
előző
órán 8.gyak#2.5.)
Amennyiben azt
szeretnénk
megtudni, hogy mely
városokba lehet eljutni Dallasból
ezt a következő
hierarchikus lekérdezéssel kapjuk meg
('DAL'='Dallas')
SELECT DISTINCT hova
FROM
jaratok
WHERE
HOVA <> 'DAL'
START WITH honnan = 'DAL'
CONNECT BY PRIOR hova = honnan;
- Most szúrjunk be még egy sort, ami
után
már
irányított kör is lesz a
táblában:
INSERT INTO jaratok
VALUES('LH',
'CHI', 'DEN', 2000, 1900, 2100);
Ekkor a fenti hierarchikus
lekérdezés nem
működik, viszont NOCYCLE-lel igen:
SELECT DISTINCT hova
FROM
jaratok
WHERE
HOVA <> 'DAL'
START WITH honnan = 'DAL'
CONNECT BY NOCYCLE PRIOR hova = honnan;
-
Átszállásokkal mely
városokba lehet eljutni
San Franciscoból ('SF'='San Francisco')
SELECT LPAD(' ', 4*level)
||honnan, hova,
level-1 Atszallasok
FROM jaratok
WHERE
HOVA <> 'SF'
START WITH honnan = 'SF'
CONNECT BY NOCYCLE PRIOR hova =
honnan;
- A hierarchikus lekérdezésben további
pszeudo
oszlopokat is használhatunk, amint
azt az alábbi
példában
láthatjuk az úzvonal
megadását
SELECT
hova,
sys_connect_by_path(honnan||'->'||hova, '/'),
connect_by_isleaf, connect_by_iscycle
FROM
jaratok
START
WITH honnan = 'SF'
CONNECT BY NOCYCLE PRIOR hova
= honnan;
- Mely (x, y)
várospárokra lehetséges
egy vagy több átszállással
eljutni x városból y városba?
Ezt PL/SQL programmal fogjuk
Oracle-ben megoldani (folytatjuk, lásd 11.gyak#Rek1)
Változóhasználat: 1a_valtozok.sql
- Változóhasználat
(I. az SQL*Plus felhasználói
változói,
II. az
SQL*Plus környezeti változói,
III. a PL/SQL (belső) változói). Az
adatok képernyőre való
kiíratása (Az
Oracle
beépített csomagjai,
DBMS_OUTPUT csomag PUT_LINE
eljárása). CONCAT fv. vagy || jel.
-- Írjunk egy PL/SQL blokkot
tartalmazó SQL*Plus
szkipt programot, amely
a
felhasználótól bekér egy
egész számot! Ha ez a szám nagyobb
100-nál,
akkor a PL/SQL blokkban,
egyébként pedig a PL/SQL blokkot követő
gazdanyelvi (SQL*Plus)
környezetben írassa ki
1b_select_into.sql
- A SELECT ... INTO
utasítás a
PL/SQL-ben
-- Határozzuk meg egy PL/SQL program
segítségével a
felhasználó által
megadott
telephelyen dolgozók
béröszegét. A telephelynek a
várost
(loc)
adjuk meg (mint
például Boston, Chicaco, Dallas vagy New York).
-- Ennek a feladatnak további
megoldásaira a következő szakaszban
visszatérünk
(lásd 2a_select_into.sql és
további
megoldásait is).
Vezérlési szerkezetek:
-- A programozási nyelvekből ismert egyszerű
példák 1c_if_then.sql
- Feltételes
utasítás (két
egész
szám összege páros-e) 1d_loop_ciklus.sql
- LOOP ciklus (a
Fibonacci-sorozat elemei) 1e_while_ciklus.sql
- WHILE
ciklus (az
Euklideszi
algoritmus) 1f_for_ciklus.sql
- FOR ciklus (páratlan
számok
négyzetösszege)
3.2.
SELECT INTO, hivatkozási és összetett
adattípusok -- Példák plsql_peldak.sql
2a_select_into.sql
- A SELECT ... INTO
utasítás a
PL/SQL-ben
-- Határozzuk meg egy PL/SQL program
segítségével a
felhasználó által
megadott
telephelyen dolgozók
béröszegét. A telephelynek a
várost
(loc)
adjuk meg (mint
például Boston, Chicaco, Dallas vagy New York).
-- Lásd a korábbi 1b_select_into
feladat
I.megoldását is, csak most
hivatkozási
típus
deklarálásával oldjuk meg a feladatot!
II.megoldás:
Közvetlen
összegzéssel. III.mo:
Tagonkénti összesítéssel
(nézettáblával).
-- Valamint rejtett kurzorral
való másik megoldására
még
visszatérünk. 2b_gyujtotabla.sql
- Összetett
típus, rekord,
gyűjtőtábla
- Írjunk PL/SQL programot, amely
meghatározza a 7698
azonosítójú
dolgozó
nevét
gyűjtőtábla használatával.
1.) Hello World program (alap program, kiírás a
képernyőre)
2.) Írjuk ki KING fizetését
(olvasás
táblából
változóba)
3.) Írjuk ki KING belépési
dátumát és
fizetését különböző
formátumokban 1981.11.17,
1981-november-17,
stb
(dátum
formátumok, több oszlopos
lekérdezés)
További
gyakorló feladatok találhatóak
az Oracle
Példatárban
-- Lásd Feladatok.pdf (8-9.fejezet
feladatai)
-- Ehhez: a táblák
létrehozása cr_dept_emp.sql