/* 1. példa */
/* Először deklarálunk egy egészekből álló tömböt, majd azt inicializáljuk, de nem töltjük fel elemekkel.
Ezek után hivatkozunk egy elemére, ám mivel a tömb még egyetlen elemet sem tartalmaz, a rendszer úgy veszi, hogy
a tömb egyetlen elemet sem ta. Ez a más programozási nyelveknél megszokott eltérő viselkedés annak a
következménye, hogy a beágyazott táblát és a dinamikus tömböt az esetek legnagyobb részében relációs táblák attribútumaként használjuk. */
DECLARE
TYPE egesz_tomb IS VARRAY(20) OF INTEGER;
sor egesz_tomb:=egesz_tomb(); -- a konstruktor függvény paraméterek nélkül
BEGIN
sor(1):=3;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(sor(1)));
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
DBMS_OUTPUT.PUT_LINE('Olyan elemere hivatkoztunk a dinamikus tombnek, '
'melyet meg nem inicializáltunk, ezért az nem létezik.');
END;
/* Miután az inicializációnál a sor dinamikus tömb első és második eleme értéket is kapott a konstruktor
függvény meghívásakor, ezért azokra később hivatkozhatunk. Ha viszont a harmadik elemre hivatkozunk, ismét
kivétel váltódik ki. */
DECLARE
TYPE egesz_tomb IS VARRAY(20) OF INTEGER;
sor egesz_tomb:=egesz_tomb(5, 4); -- a konstruktor függvény paraméterekkel
BEGIN
DBMS_OUTPUT.PUT_LINE('Elotte: ' || TO_CHAR(sor(1)));
sor(1):=3; -- Ezt lehet.
DBMS_OUTPUT.PUT_LINE('Utana: ' || TO_CHAR(sor(1)));
sor(3):=5; -- Ezt már nem.
DBMS_OUTPUT.PUT_LINE('Es most: ' || TO_CHAR(sor(3)));
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
DBMS_OUTPUT.PUT_LINE('Olyan elemere hivatkoztunk a dinamikus tombnek, '
'melyet meg nem inicializáltunk, ezért az nem létezik.');
END;
/* Példa a SUBSCRIPT_BEYOND_COUNT és a SUBSRIPT_OUTSIDE_LIMIT kivételek közti különbségre. */
DECLARE
TYPE egesz_tomb IS VARRAY(20) OF INTEGER;
sor egesz_tomb:=egesz_tomb(5, 4); -- a konstruktor függvény paraméterekkel
BEGIN
DBMS_OUTPUT.PUT_LINE('Elotte: ' || TO_CHAR(sor(1)));
sor(1):=3; -- Ezt lehet.
DBMS_OUTPUT.PUT_LINE('Utana: ' || TO_CHAR(sor(1)));
sor(21):=5; -- Túl "nagy" indexre hivatkozunk.
DBMS_OUTPUT.PUT_LINE('Es most: ' || TO_CHAR(sor(3)));
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
DBMS_OUTPUT.PUT_LINE('Olyan elemere hivatkoztunk a dinamikus tombnek,'
'melyet meg nem inicializáltunk, ezért az nem létezik.');
WHEN SUBSCRIPT_OUTSIDE_LIMIT THEN
DBMS_OUTPUT.PUT_LINE('Tulleptuk a dinamikus tomb deklaraciojakor megadott felso hatart!')
END;
/* 2. példa */
DECLARE
TYPE egesz_tomb IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;
sor egesz_tomb; -- Itt nincs konstruktor függvény.
BEGIN
sor(1):=3; -- Ezt lehet.
DBMS_OUTPUT.PUT_LINE(TO_CHAR(sor(1)));
DBMS_OUTPUT.PUT_LINE('Es most: ' || TO_CHAR(sor(3))); -- Ezt nem.
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Olyan elemere hivatkoztunk az indexelt tablanak,'
'melynek meg nem adtunk erteket, ezert az nem letezik.');
END;
/* 3. példa */
/* A program véletlen számokkal tölt fel egy mátrixot, majd kiírja az elemeit.
A kollekciók indexelt tábla típusúak, emiatt a ciklusok megszervezése kissé bonyodalmas. */
DECLARE
TYPE sor IS TABLE OF INTEGER
INDEX BY BINARY_INTEGER;
TYPE matrix IS TABLE OF sor
INDEX BY BINARY_INTEGER;
v_matrix matrix;
i INTEGER;
j INTEGER;
BEGIN
-- Véletlen számokkal töltjük fel a mátrixot. Az indexek nem folytonosan szerepelnek.
FOR i IN 1..3 LOOP
FOR j IN 1..2 LOOP
v_matrix(2*i)(3*j):=ROUND(DBMS_RANDOM.NORMAL());
END LOOP;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Az első mátrix:');
DBMS_OUTPUT.NEW_LINE;
-- Kiiratjuk a mátrix sorait.
i:=v_matrix.FIRST;
WHILE i IS NOT NULL LOOP
j:=v_matrix(i).FIRST;
WHILE j IS NOT NULL LOOP
DBMS_OUTPUT.PUT_LINE(v_matrix(i)(j) || ' ');
j:=v_matrix(i).NEXT(j);
END LOOP;
DBMS_OUTPUT.NEW_LINE;
i:=v_matrix.NEXT(i);
END LOOP;
END;
/* 4. példa */
/* A legelső példa javítása. Mielőtt a sor tömb első elemére hivatkoznánk, megnöveljük a sor méretét
eggyel, hogy ezt megtehessük. */
DECLARE
TYPE egesz_tomb IS VARRAY(20) OF INTEGER;
sor egesz_tomb:=egesz_tomb();
BEGIN
sor.EXTEND;
-- Most már hivatkozhatunk az első elemre.
sor(1):=3;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(sor(1)));
EXCEPTION
WHEN SUBSCRIPT_BEYOND_COUNT THEN
DBMS_OUTPUT.PUT_LINE('Olyan elemere hivatkoztunk a dinamikus tombnek,'
'melyet meg nem inicializáltunk, ezért az nem létezik.');
END;
/* 5. példa */
/* A program azon ügyfeleknél, akiknek több, mint 500000 forint van a számláin összesen,
megnöveli a keretet 200000 forintra, majd kiírja, hogy hány ilyen változtatás történt az egyes
ügyfelek esetén. A feladat majdnem megegyezik a PL_SQL_kurzor.ppt fájlban található 5. feladattal. */
DECLARE
TYPE azon_tomb IS VARRAY(20) OF VARCHAR2(3);
sor azon_tomb;
BEGIN
SELECT u.azon
BULK COLLECT INTO sor
FROM ugyfel u, szamla sz
WHERE u.azon = sz.ugyf_azon
GROUP BY u.azon
HAVING SUM(osszeg)>500000;
FORALL i IN sor.FIRST..sor.LAST
UPDATE ugyfel SET keret = 200000
WHERE azon = sor(i);
FOR i IN sor.FIRST..sor.LAST LOOP
DBMS_OUTPUT.PUT_LINE(sor(i) ||' azonositonal ' || SQL%BULK_ROWCOUNT(i) || ' valtoztatas tortent.');
END LOOP;
END;