11.GYAKORLAT (ADATBÁZISOK)
   
     Témakör: Oracle PL/SQL témakör 3.gyakorlata: Oracle Példatár 10.fejezete
     - Kivétel- és hibakezelés, alprogramok, tárolt eljárások és függvények
     - PL/SQL doksi: Oracle Database Rel.12.2 - PL/SQL Language Reference
       >> List of Examples (PL/SQL Lang.Ref.12.2) -- példákhoz: create_hr_tables.txt
       >> SQL/PSM, PL/SQL: SQL4.pdf (2020.tavaszi AB1EA/HajasCs. 8.ea PL/SQL)
   
      4.rész:  PL/SQL eljárások és függvények >> 8.fej. PL/SQL Alprogramok
      >> példa2-17 Változók hatásköre, láthatósága, élettartalma (2.fej. Alapok)
      >> példa4-1 IF-THEN utasítás (már itt is volt eljárás: 4.fej. Utasítások)
      >> (összefoglaló) 06_alprogramok.pdfpl_procedura_fv.txt 
 
      5.rész:  PL/SQL triggerek, csomagok >> 9.fej. Triggerek; 10.fej. Csomagok
     >> habár fontosak a gyakorlatban (és lásd Oracle Példatár 10.fej. példáit is), 
          viszont időhiány miatt PL/SQL trigger feladatok NEM lesznek a III.ZH-án!
     >> (összefoglaló) 09_triggerek.pdf10_rendszertriggerek.pdf14_csomagok.pdf
     
      6.rész:  PL/SQL kivétel- és hibakezelés >> 11.fej. Kivétel-és hibakezelés
      >> táblázat-11-3 előre definiált kivételek (Predefined Exceptions) Táblázat
      >> példa-11-3 példa előre definiált NO_DATA_FOUND hiba kezelésére
      >> példa11-6 példa előre definiált ZERO_DIVIDE (egyszerű névtelen blokk)
      >> példa-11-10 példa felhasználó által definiált kivételre
            -- Javítások: CREATE PROCEDURE helyett CREATE OR REPLACE PROCEDURE
            -- és az utasításrészben, ahol TO_DATE('01-JUL-2010', 'DD-MON-YYYY') kieg.:
                TO_DATE('01-JUL-2010', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE = American')
      >> (összefoglaló) 07_kivetelek.pdf; pl_kivetel0.txt;  pl_kivetel1.txtpl_kivetel2.txt
   
   > PL/SQL FELADATSOR --3:
     -- Ehhez is, mint a DML-hez: createDolg (no constraint)
     -- A PL/SQL blokk előtt minden alkalommal állítsuk be: SET SERVEROUTPUT ON
    1-10.) Lásd az előző heti gyakorlaton az első PL/SQL feladatokat: ezeket most
           írjuk át eljárásokra/függvényekre, plusz legyen benne hiba- és kivételkezelés! 
      -- Előre definiált kivételek: NO_DATA_FOUND, TOO_MANY_ROWS, lásd példa-11-3
     2.) Írjuk ki KING fizetését (olvasás táblából változóba és a képernyőre való kiíratás)
          abban az esetben,  ha pontosan egy KING nevű dolgozó szerepel a táblában, 
          viszont ha nincs ilyen nevű dolgozó vagy több ilyen is van, akkor azt írjuk ki!
     11.-21.) További feladatok alprogramokra (tárolt függvényekre, tárolt eljárásokra)
   
-- -- --  --    
11.)
/* Írjunk meg egy függvényt, amelyik eldönti egy számról, hogy prím-e. igen/nem -> 1/0 */
CREATE OR REPLACE FUNCTION prim(n integer) RETURN number IS
Tesztelés:
SELECT prim(26388279066623) from dual;
    
-- -- --  --    
12.)
/* Írjunk meg egy procedúrát, amelyik kiírja az n-edik Fibonacchi számot
   fib_1 = 0, fib_2 = 1, fib_3 = 1, fib_4 = 2 ... fib_i = a megelőző kettő összege
*/
CREATE OR REPLACE PROCEDURE fib(n integer) IS
Tesztelés:
set serveroutput on
execute fib(10);
 
-- -- --  --    
 13.)
/* Írjunk meg egy függvényt, amelyik visszaadja két szám legnagyobb közös osztóját */
CREATE OR REPLACE FUNCTION lnko(p1 integer, p2 integer) RETURN number IS
Tesztelés:
SELECT lnko(3570,7293) FROM dual;
 
-- -- --  --    
14.)
/* Írjunk meg egy függvényt, amelyik visszaadja n faktoriálisát */
CREATE OR REPLACE FUNCTION faktor(n integer) RETURN integer IS
Tesztelés:
SELECT faktor(10) FROM dual;
 
-- -- --  --    
15.)
/* Írjunk meg egy függvényt, amelyik megadja, hogy hányszor fordul elő egy
   karakterláncban -> p1 egy másik részkarakterlánc -> p2
*/
CREATE OR REPLACE FUNCTION hanyszor(p1 VARCHAR2, p2 VARCHAR2) RETURN integer IS
Tesztelés:
SELECT hanyszor ('ab c ab ab de ab fg', 'ab') FROM dual;
 
-- -- --  --    
16.)
/* SELECT ... INTO v1
Írjunk meg egy függvényt, amelyik visszaadja egy adott fizetési kategóriába tartozó
dolgozók átlagfizetését.
*/
CREATE OR REPLACE FUNCTION kat_atlag(n integer) RETURN number IS
Tesztelés:
SELECT kat_atlag(2) FROM dual;
 
-- -- --  --    
17.)
/* SELECT ... INTO v1, v2
Írjunk meg egy procedúrát, amelyik kiírja azon dolgozók számát és átlagfizetését,
akiknek a belépési dátuma a paraméterül megadott nevű napon (pl. Hétfő') volt.
*/
CREATE OR REPLACE PROCEDURE nap_atl(d varchar2) IS
...
set serveroutput on
call nap_atl('Csütörtök'); -- példa output: Dolgozók száma: 4, Átlag fiz: 2481,25

Tippek:
   1. to_char(hiredate, 'Day', 'nls_date_language=hungarian')
   2. vigyázzunk a to_char által visszaadott nap névre, a végén szóközök lehetnek
 
-- -- --  --    
18.)
/* Insert, Delete, Update
Írjunk meg egy procedúrát, amelyik megnöveli azoknak a dolgozóknak a fizetését, akiknek a
fizetési kategóriája ugyanaz, mint a procedúra paramétere. A növelés mértéke a dolgozó
osztályában előforduló legkisebb fizetés legyen.
A procedúra a módosítás után írja ki a módosított (új) fizetések átlagát két tizedesjegyre kerekítve.
*/
CREATE OR REPLACE PROCEDURE kat_novel(p_kategoria NUMBER) IS
...
set serveroutput on
execute kat_novel(2);
 
-- -- --  --    
19.)
/* Cursor (több soros SELECT)
Írjunk meg egy procedúrát, amelyik veszi a paraméterül megadott osztály dolgozóit ábécé
szerinti sorrendben, és kiírja a foglalkozásaikat egy karakterláncban összefűzve.
*/
CREATE OR REPLACE PROCEDURE print_foglalkozas(o_nev varchar2) IS
...
set serveroutput on
call print_foglalkozas('ACCOUNTING');  -- példa output: MANAGER-PRESIDENT-CLERK
 
-- -- --  --    
20.) 
/* Módosítás kurzorral
Írjunk meg egy procedúrát, amelyik módosítja a paraméterében megadott osztályon
a fizetéseket, és kiírja a dolgozó nevét és új fizetését. 
A módosítás mindenki fizetéséhez adjon hozzá n*10 ezret,
ahol n a dolgozó nevében levő magánhangzók száma (a, e, i, o, u).
*/
CREATE OR REPLACE PROCEDURE fiz_mod(p_oazon INTEGER) IS
Tesztelés:
set serveroutput on
execute fiz_mod(10);
 
-- -- --  --    
21.)
/* Exception
Írjunk meg egy függvényt, amelyik egy karakteres típusú paraméterben egy dátumot
kap a következő formátumban: 'éééé.hh.nn' vagy 'nn.hh.éééé'.
A függvény adja vissza a nap nevét, pl. 'kedd'.
Ha a megadott karakterlánc nem egy érvényes dátum, akkor adja vissza, hogy 'rossz dátum'.
*/
CREATE OR REPLACE FUNCTION nap_nev(p_kar VARCHAR2) RETURN VARCHAR2 IS
...
SELECT nap_nev('2017.05.01'), nap_nev('02.05.2017'), nap_nev('2017.13.13') FROM dual;
   
 

 
   Ţovábbi gyakorló PL/SQL feladatok 
   > CANVAS-ban az IP-18AB1G Adatbázisok I. gyakorlat oldalán
   > Oracle Példatár Feladatok.pdf, de most NEM a 10.fejezet trigger-feladatait, hanem
      vegyük elő a korábbi 8. fejezet és 9.fejezet feladatait újból, és azokat írjuk át tárolt
      eljárásra/függvényre, és ahol lehet még egészítsük ki kivétel- és hibakezeléssel is!
 
-- -- --  --  
    A köv.gyakorlaton írjuk a III.ZH-át, három típusfeladat a három PL/SQL gyakorlatból:
    1.feladat (9.+11.gyak.) DML utasítások és SELECT INTO utasítás a programban
    2.feladat (10.gyak.) Több sort visszaadó SELECT, implicit kurzor használata
    3.feladat (9.+11.gyak.) Egyszerű programozási feladat tárolt eljárásra/függvényre