Programozás | SQL » Oracle PL/SQL összefoglaló feladatok, megoldással, 2005

Alapadatok

Év, oldalszám:2005, 19 oldal

Nyelv:magyar

Letöltések száma:944

Feltöltve:2006. január 23.

Méret:242 KB

Intézmény:
-

Megjegyzés:

Csatolmány:-

Letöltés PDF-ben:Kérlek jelentkezz be!



Értékelések

Nincs még értékelés. Legyél Te az első!


Tartalmi kivonat

PL/SQL ÖSSZEFOGLALÓ FELADATOK Az alábbi feladatokat megoldó programokat és azok futási eredményeit, ellenőrző listáit a főkönyvtár hallgató nevű könyvtárában az Ön nevét tartalmazó Word dokumentumba (pl. C:hallgatóSasPál 1kurzus Adoc) tárolja, majd ezt zip formátumba tömörítve küldje el egy e-mail-hez csatolva a doboz123@freemailhu címre A részmegoldásokat próbafuttatásokkal ellenőrizze, és ezeket is dokumentálja. Az utasításokat struktúrált módon írja. Segítségként csak az Oracle Help funkciója, és a tankönyvek használhatók Ügyeljen arra, hogy megoldása egy összetett feladat minden követelményét kielégítse. Megjegyezzük, hogy az egyes részfeladatokat nem feltétlenül a megadásuk sorrendjében kell megoldani, ezért előbb figyelmesen olvassa végig a teljes feladatot. 1. Feladat Hozzon létre egy dolgozó nevű táblát az emp tábla dolgozóiból, és ebben növelje meg a hivatalnokok (clerk) fizetését 20%-al.

Listázással ellenőrizze a megoldás helyességét 2. Feladat Hozzon létre egy dolgozó nevű táblát az emp tábla eladóiból (salesman), és változtassa meg az mgr oszlop nevét partner névre, melyet az alábbi módon töltsön fel értékkel: Két dolgozó partnere lehet egymásnak, ha még egyiküknek sincs partnere, és 150 USD-nél nem több a fizetésük különbsége. A partnerek azonosítói szerepeljenek egymás partner oszlopában Ellenőrizze a megoldást új dolgozó felvitelével, és a partnerkeresés megismétlésével. 3. Feladat 3.1 Hozzon létre egy dolgozó nevű táblát az emp tábla rekordjaiból 3.2 Készítsen triggert a dolgozó táblába történő ellenőrzött adatbevitelhez, ahol az alábbi adatbeviteli feltételeket a trigger által meghívott tárolt alprogramokban vizsgálja meg: a.) Részleg feltétel: Egy új dolgozó részlegeként csak már létező részleg azonosítója adható meg b.) Fizetési feltétel: Egy új dolgozó fizetésként a

részlegében és vele azonos munkakörben dolgozók átlagfizetésének legalább a 3/4-ét kapja, ha a részlegében nincs vele azonos munkakörű, akkor a részlegében dolgozók átlagfizetésének 2/3-ánál legalább 300 USD-vel többet, ha pedig a részlegében ő az első dolgozó, akkor legalább 2000 USD-t. 3.3 A trigger és a tárolt eljárások ellenőrzése érdekében végezze el a szükséges adatfelviteleket 3.4 Az elkészített megoldás a tárolandó dolgozó nevét írja vissza a képernyőre, és sikeres adatfelvitel esetén írja ki a dolgozó nevét, majd az "OK!" üzenetet, míg sikertelen adatfelvitel esetén a "HIBA:" üzenetet, és a sikertelenség okát. 3.5 Utolsó lépésként listázza a dolgozó táblát, majd állítsa vissza az eredeti táblatartalmat Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -1- MEGOLDÁSOK 1. Feladat Hozzon létre egy dolgozó nevű táblát az emp tábla dolgozóiból, és ebben

növelje meg a hivatalnokok (clerk) fizetését 20%-al. Listázással ellenőrizze a megoldás helyességét Megoldás 0. lépés (Az SQL*Plus környezet inicializálása) -- Az emp tábla inicializálása (ezúttal elhagyjuk) -- Feltételezve, hogy az INIT1.sql a BIN könyvtárban van -- A dátum és megjelenítés inicializálása -- @INIT1 ALTER SESSION SET NLS DATE FORMAT = YYYY-MM-DD; SET numwidth 5 -- Az esetlegesen létező azonos nevű objektumok törlése DROP VIEW dolgozó; DROP TABLE dolgozó; A munkamenet módosítva. ORA-00942: a tábla vagy a nézet nem létezik ORA-00942: a tábla vagy a nézet nem létezik 1. lépés DROP TABLE dolgozó; CREATE TABLE dolgozó AS SELECT * FROM emp; SELECT * FROM dolgozó WHERE LOWER(job) = clerk; ORA-00942: a tábla vagy a nézet nem létezik A tábla létrejött. EMPNO ----7900 7369 7876 7934 ENAME ---------JAMES SMITH ADAMS MILLER JOB MGR HIREDATE SAL COMM DEPTNO --------- ----- ---------- ----- ----- -----CLERK 7698 1981-12-03

950 30 CLERK 7902 1980-12-17 800 20 CLERK 7788 1987-05-23 1100 20 CLERK 7782 1982-01-23 1300 10 2. lépés UPDATE dolgozó SET sal = 1.2*sal WHERE LOWER(job) = clerk; 4 sor módosítva. SELECT * FROM dolgozó WHERE LOWER(job) = clerk; EMPNO ----7900 7369 7876 7934 ENAME ---------JAMES SMITH ADAMS MILLER JOB MGR HIREDATE SAL COMM DEPTNO --------- ----- ---------- ----- ----- -----CLERK 7698 1981-12-03 1140 30 CLERK 7902 1980-12-17 960 20 CLERK 7788 1987-05-23 1320 20 CLERK 7782 1982-01-23 1560 10 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -2- 2. Feladat Hozzon létre egy dolgozó nevű táblát az emp tábla eladóiból (salesman), és változtassa meg az mgr oszlop nevét partner névre, melyet az alábbi módon töltsön fel értékkel: Két dolgozó partnere lehet egymásnak, ha még egyiküknek sincs partnere, és 150 USD-nél nem több a fizetésük különbsége. A partnerek azonosítói szerepeljenek egymás partner oszlopában Ellenőrizze a

megoldást új dolgozó felvitelével, és a partnerkeresés megismétlésével. A. Megoldás (Megoldási próbálkozás SQL-ben) 0. lépés (Az SQL*Plus környezet inicializálása) -- Az emp tábla inicializálása (ezúttal elhagyjuk) -- @INIT1 -- Feltételezve, hogy az INIT1.sql a BIN könyvtárban van -- A dátum és megjelenítés inicializálása ALTER SESSION SET NLS DATE FORMAT = YYYY-MM-DD; SET numwidth 5 -- Az esetlegesen létező azonos nevű objektumok törlése DROP VIEW dolgozó; DROP TABLE dolgozó; A munkamenet módosítva. ORA-00942: a tábla vagy a nézet nem létezik ORA-00942: a tábla vagy a nézet nem létezik 1. lépés (Konzisztens adattábla létrehozása) CREATE OR REPLACE VIEW DolgozóNézet AS SELECT * FROM emp WHERE LOWER(job) = salesman; SELECT * FROM DolgozóNézet; DROP TABLE dolgozó; CREATE TABLE dolgozó AS SELECT empno, ename, job, CASE WHEN mgr IN (SELECT empno FROM DolgozóNézet) THEN mgr ELSE NULL END AS mgr, hiredate, sal, comm, deptno FROM

DolgozóNézet; DROP VIEW DolgozóNézet; SELECT * FROM dolgozó; A nézet létrejött. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ---------- ----- ----- -----7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 A tábla létrejött. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ---------- ----- ----- -----7654 MARTIN SALESMAN 1981-09-28 1250 1400 30 7499 ALLEN SALESMAN 1981-02-20 1600 300 30 7844 TURNER SALESMAN 1981-09-08 1500 0 30 7521 WARD SALESMAN 1981-02-22 1250 500 30 2. lépés (Oszlopmódosítás és adattörlés) ALTER TABLE dolgozó RENAME COLUMN mgr TO partner; Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -3- -- A partner mező ezúttal az alábbi törlés nélkül is üres UPDATE dolgozó SET partner = NULL; SELECT * FROM dolgozó; A

tábla módosítva. EMPNO ENAME JOB PARTNER HIREDATE SAL COMM DEPTNO ----- ---------- --------- ------- ---------- ----- ----- -----7654 MARTIN SALESMAN 1981-09-28 1250 1400 30 7499 ALLEN SALESMAN 1981-02-20 1600 300 30 7844 TURNER SALESMAN 1981-09-08 1500 0 30 7521 WARD SALESMAN 1981-02-22 1250 500 30 3. lépés (Adatfeltöltés) -- Partnerkereső segédnézet létrehozása CREATE OR REPLACE VIEW PartnerKeresés(DolgozóID,DolgozóFiz, PartnerID,PartnerFiz) AS SELECT D.empno AS DolgozóID, D.sal AS DolgozóFiz, P.empno AS PartnerID, P.sal AS PartnerFiz FROM dolgozó D, dolgozó P WHERE ABS(D.sal - Psal) <= 150 AND D.empno != Pempno; SELECT * FROM PartnerKeresés; A nézet létrejött. DOLGOZÓID DOLGOZÓFIZ PARTNERID PARTNERFIZ --------- ---------- --------- ---------7654 1250 7521 1250 7499 1600 7844 1500 7844 1500 7499 1600 7521 1250 7654 1250 -- Adatmódosítás UPDATE dolgozó SET partner = (SELECT PartnerID FROM PartnerKeresés WHERE DolgozóID = empno); SELECT * FROM

dolgozó; 4 sor EMPNO ----7654 7499 7844 7521 módosítva. ENAME ---------MARTIN ALLEN TURNER WARD JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 7521 1981-09-28 1250 1400 30 SALESMAN 7844 1981-02-20 1600 300 30 SALESMAN 7499 1981-09-08 1500 0 30 SALESMAN 7654 1981-02-22 1250 500 30 4. lépés (Ellenőrzés rekordfelvitellel) INSERT INTO dolgozó VALUES(6666,SIGORSZKI,SALESMAN,NULL,2005-10-30,1250,NULL,30); 1 sor létrejött. UPDATE dolgozó SET partner = (SELECT PartnerID FROM PartnerKeresés WHERE DolgozóID = empno); SET partner = (SELECT PartnerID * Hiba a(z) 2. sorban: ORA-01427: egysoros allekérdezés egynél több sorral tér vissza >> HIBÁS az adatmódosítás! >> Derítsük ki a hiba okát, és készítsünk jó adatmódosító utasítást Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -4- SELECT * FROM PartnerKeresés; DOLGOZÓID DOLGOZÓFIZ PARTNERID PARTNERFIZ --------- ----------

--------- ---------7654 1250 7521 1250 7654 1250 6666 1250 7499 1600 7844 1500 7844 1500 7499 1600 7521 1250 7654 1250 7521 1250 6666 1250 6666 1250 7654 1250 6666 1250 7521 1250 8 sor kijelölve. >> A HIBA oka, hogy egy dolgozónak több partnere is lehet a fizetés feltétel szerint SELECT MaxPartnerID FROM (SELECT DolgozóID, MAX(PartnerID) FROM PartnerKeresés GROUP BY DolgozóID) WHERE DolgozóID = 7654; AS MaxPartnerID MAXPARTNERID -----------7521 >> Így minden dolgozó a legnagyobb azonosítójú (a fizetésre vonatkozó feltételt teljesítő) >> dolgozót kapja partnerként. >> (Ez egy módszer arra, hogy kijelöljünk egyet a lehetséges elemek közül, >> de ilyen módszer nem mindig található!) -- ÚJABB PRÓBÁLKOZÁS -- A partner mező inicializálása UPDATE dolgozó SET partner = NULL; -- A partner mező beállítása (feltöltése) UPDATE dolgozó SET partner = (SELECT MaxPartnerID FROM (SELECT DolgozóID, MAX(PartnerID) FROM

PartnerKeresés GROUP BY DolgozóID) WHERE DolgozóID = empno); SELECT * FROM dolgozó; 5 sor EMPNO ----7654 7499 7844 7521 6666 módosítva. ENAME ---------MARTIN ALLEN TURNER WARD SIGORSZKI AS MaxPartnerID JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 7521 1981-09-28 1250 1400 30 SALESMAN 7844 1981-02-20 1600 300 30 SALESMAN 7499 1981-09-08 1500 0 30 SALESMAN 7654 1981-02-22 1250 500 30 SALESMAN 7654 2005-10-30 1250 30 >> Még mindig HIBÁS az adatmódosítás! >> A HIBA oka, hogy a legnagyobb azonosítójú dolgozót többen is tudják választani. >> Ezt úgy küszöböljük ki, hogy mielőtt egy dolgozó-azonosítót partnerkódként kiosztunk, >> megvizsgáljuk, hogy azt nem kapta-e már meg valaki. >> (Ezt algebrailag felírva: {a} ⊆ B ⇔ {a} B ≠ ∅, ahol {a} a vizsgálandó dolgozó-azonosító, >> vagyis a "(SELECT MaxPartnerID." utasításrész, amelyik bár csak egyetlen

elemet ad ki, >> azért mégis csak halmaz, hiszen lista.) Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -5- -- ÚJABB PRÓBÁLKOZÁS 2. -- A partner mező inicializálása UPDATE dolgozó SET partner = NULL; -- A partner mező beállítása (feltöltése) UPDATE dolgozó SET partner = (SELECT MaxPartnerID FROM (SELECT DolgozóID, MAX(PartnerID) AS MaxPartnerID FROM PartnerKeresés GROUP BY DolgozóID) WHERE DolgozóID = empno) WHERE NOT EXISTS (SELECT MaxPartnerID FROM (SELECT DolgozóID, MAX(PartnerID) AS MaxPartnerID FROM PartnerKeresés GROUP BY DolgozóID) WHERE DolgozóID = empno MINUS SELECT partner FROM dolgozó); SELECT * FROM dolgozó; 0 sor módosítva. EMPNO ----7654 7499 7844 7521 6666 ENAME ---------MARTIN ALLEN TURNER WARD SIGORSZKI JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 1981-09-28 1250 1400 30 SALESMAN 1981-02-20 1600 300 30 SALESMAN 1981-09-08 1500 0 30 SALESMAN 1981-02-22 1250

500 30 SALESMAN 2005-10-30 1250 30 >> Még mindig HIBÁS az adatmódosítás! >> Mi lehet a HIBA oka, hiszen ez az adatmódosítás már igazán mindent figyelembe vesz? >> ???? (Ötletek küldhetők az oktat123@freemail címre.) Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -6- B. Megoldás (Megoldás PL/SQL-ben – Rejtett kurzorral és ROWID-val) 1. lépés (Konzisztens adattábla létrehozása) ugyanaz, mint az A. Megoldásban a 0 és az 1 lépés (lásd ott a szükséges SQL-utasításokat, illetve a DataLoad A.sql szkript programot) 2. lépés (Oszlopmódosítás, rekordhozzáadás) ugyanaz, mint az A. Megoldásban a 2 és a 3 lépés (lásd ott a szükséges SQL-utasításokat, illetve a DataLoad A.sql szkript programot) 3. lépés (Adatfeltöltés - ROWID használattal) -- DataLoad B.sql -------------------------------------------------------------- Adatfeltöltés rejtett kurzorral és ROWID használattal --- (Értelmezését

lásd a 12 KurzorHasználat.doc szkriptben) --------------------------------------------------------------- Utolsó javítás dátuma: 20051122 ------------------------------------------------------------SET serveroutput ON DECLARE v Egyik dolgozó.partner%TYPE; v Másik dolgozó.partner%TYPE; BEGIN -- A dolgozó tábla inicializálása UPDATE dolgozó SET partner = NULL; -- A fejléc kiíratása DBMS OUTPUT.PUT LINE(DOLGOZÓ || Fizetése || PARTNER || Fizetése); DBMS OUTPUT.PUT LINE(===================================); -- A külső ciklus (végigmegy az összes dolgozó rekordján) FOR EgyikDolgozó IN (SELECT dolgozó.*, ROWID AS RecID FROM dolgozó) LOOP -- A partner azonosító lekérdezése a külső ciklus számára: SELECT partner INTO v Egyik FROM dolgozó WHERE ROWID = EgyikDolgozó.RecID; -- A belső ciklus (ez is végigmegy az összes dolgozó rekordján) FOR MásikDolgozó IN (SELECT dolgozó.*, ROWID AS RecID FROM dolgozó) LOOP -- A partner azonosító lekérdezése

a belső ciklus számára: SELECT partner INTO v Másik FROM dolgozó WHERE ROWID = MásikDolgozó.RecID; -----IF Ha a külső ciklus aktuális dolgozójának fizetése és a belső ciklus aktuális dolgozójának fizetése között a különbség nem több 150 USD-nél, és a két dolgozó nem azonos, és egyiknek sincs még partnere, ABS(EgyikDolgozó.sal - MásikDolgozósal) <= 150 AND EgyikDolgozó.empno != MásikDolgozóempno AND v Egyik IS NULL AND Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -7- v Másik IS NULL THEN -- akkor állítsuk be a partner-azonosítót: UPDATE dolgozó SET partner = MásikDolgozó.empno WHERE ROWID = EgyikDolgozó.RecID; -- és a beállítást visszafelé is végezzük el: UPDATE dolgozó SET partner = EgyikDolgozó.empno WHERE ROWID = MásikDolgozó.RecID; -- Kiíratás DBMS OUTPUT.PUT LINE(EgyikDolgozóempno EgyikDolgozó.sal MásikDolgozó.empno MásikDolgozó.sal); || || || || || || -- Kiugrás a ciklusból

-- Az egyezés és módosítás után kiugrás a belső ciklusból, és -- ugrás a külső ciklus következő rekordjára EXIT; END IF; -- A belső (MásikDolgozó) ciklus bezárása END LOOP; -- A külső (EgyikDolgozó) ciklus bezárása END LOOP; END; / SELECT * FROM dolgozó; -- End Of DataLoad B.sql DOLGOZÓ Fizetése PARTNER Fizetése =================================== 7654 1250 7521 1250 7499 1600 7844 1500 A PL/SQL eljárás sikeresen befejeződött. EMPNO ----7654 7499 7844 7521 6666 ENAME ---------MARTIN ALLEN TURNER WARD SIGORSZKI JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 7521 1981-09-28 1250 1400 30 SALESMAN 7844 1981-02-20 1600 300 30 SALESMAN 7499 1981-09-08 1500 0 30 SALESMAN 7654 1981-02-22 1250 500 30 SALESMAN 2005-10-30 1250 30 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -8- C. Megoldás (Megoldás PL/SQL-ben – Rejtett kurzorral, ROWID nélkül) 1. lépés (Konzisztens adattábla

létrehozása) ugyanaz, mint az A. Megoldásban a 0 és az 1 lépés (lásd ott a szükséges SQL-utasításokat, illetve a DataLoad A.sql szkript programot) 2. lépés (Oszlopmódosítás, rekordhozzáadás) ugyanaz, mint az A. Megoldásban a 2 és 3 lépés (lásd ott a szükséges SQL-utasításokat, illetve a DataLoad A.sql szkript programot) 3. lépés (Adatfeltöltés - ROWID használat nélkül) A feladat megoldható ezúttal ROWID használata nélkül is, mivel van olyan, a rekordokat egyértelműen azonosító oszlop (empno), mely a kurzor-ciklusban nem változik meg. -- DataLoad C.sql -------------------------------------------------------------- Adatfeltöltés rejtett kurzorral, ROWID nélkül --- (Értelmezését lásd a 12 KurzorHasználat.doc szkriptben) --------------------------------------------------------------- Utolsó javítás dátuma: 20051122 ------------------------------------------------------------SET serveroutput ON DECLARE v Egyik dolgozó.partner%TYPE; v

Másik dolgozó.partner%TYPE; BEGIN -- A dolgozó tábla inicializálása UPDATE dolgozó SET partner = NULL; -- A fejléc kiíratása DBMS OUTPUT.PUT LINE(DOLGOZÓ || Fizetése || PARTNER || Fizetése); DBMS OUTPUT.PUT LINE(===================================); -- A külső ciklus (végigmegy az összes dolgozó rekordján) FOR EgyikDolgozó IN (SELECT * FROM dolgozó) LOOP -- A partner azonosító lekérdezése a külső ciklus számára: SELECT partner INTO v Egyik FROM dolgozó WHERE empno = EgyikDolgozó.empno; -- A belső ciklus (ez is végigmegy az összes dolgozó rekordján) FOR MásikDolgozó IN (SELECT * FROM dolgozó) LOOP -- A partner azonosító lekérdezése a belső ciklus számára: SELECT partner INTO v Másik FROM dolgozó WHERE empno = MásikDolgozó.empno; -----IF Ha a külső ciklus aktuális dolgozójának fizetése és a belső ciklus aktuális dolgozójának fizetése között a különbség nem több 150 USD-nél, és a két dolgozó nem azonos, és

egyiknek sincs még partnere, ABS(EgyikDolgozó.sal - MásikDolgozósal) <= 150 AND EgyikDolgozó.empno != MásikDolgozóempno AND v Egyik IS NULL AND v Másik IS NULL Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) -9- THEN -- akkor állítsuk be a partner-azonosítót: UPDATE dolgozó SET partner = MásikDolgozó.empno WHERE empno = EgyikDolgozó.empno; -- és a beállítást visszafelé is végezzük el: UPDATE dolgozó SET partner = EgyikDolgozó.empno WHERE empno = MásikDolgozó.empno; -- Kiíratás DBMS OUTPUT.PUT LINE(EgyikDolgozóempno EgyikDolgozó.sal MásikDolgozó.empno MásikDolgozó.sal); || || || || || || -- Kiugrás a ciklusból -- Az egyezés és módosítás után kiugrás a belső ciklusból, és -- ugrás a külső ciklus következő rekordjára EXIT; END IF; -- A belső (MásikDolgozó) ciklus bezárása END LOOP; -- A külső (EgyikDolgozó) ciklus bezárása END LOOP; END; / SELECT * FROM dolgozó; -- End Of DataLoad C.sql

DOLGOZÓ Fizetése PARTNER Fizetése =================================== 7654 1250 7521 1250 7499 1600 7844 1500 A PL/SQL eljárás sikeresen befejeződött. EMPNO ----7654 7499 7844 7521 6666 ENAME ---------MARTIN ALLEN TURNER WARD SIGORSZKI JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 7521 1981-09-28 1250 1400 30 SALESMAN 7844 1981-02-20 1600 300 30 SALESMAN 7499 1981-09-08 1500 0 30 SALESMAN 7654 1981-02-22 1250 500 30 SALESMAN 2005-10-30 1250 30 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 10 - D. Hibás Megoldás Tekintsük az előző, C. Megoldást, ám ezúttal ne a dolgozó táblából, hanem az egyes ciklusok rejtett kurzoraiból kérdezzük le egyszerű értékadással (az adott ciklus ciklusváltozóján keresztül) az aktuális rekord partner értékét (lásd a DataLoad D.sql szkript programot) Eredményként az alábbi táblát kapjuk: EMPNO ----7654 7499 7844 7521 6666 ENAME

---------MARTIN ALLEN TURNER WARD SIGORSZKI JOB PARTNER HIREDATE SAL COMM DEPTNO --------- ------- ---------- ----- ----- -----SALESMAN 7521 1981-09-28 1250 1400 30 SALESMAN 7844 1981-02-20 1600 300 30 SALESMAN 7499 1981-09-08 1500 0 30 SALESMAN 6666 1981-02-22 1250 500 30 SALESMAN 7521 2005-10-30 1250 30 Ez láthatóan hibás (Martinnak és Sigorszkinak ugyanaz a partner jutott). Mi a hiba oka? A magyarázat a kurzorok alaptermészetében keresendő: A kurzorbeli lekérdezés eredménye egy zárt memóriaterületre kerül, melyet nem befolyásol azon adattábla tartalmának megváltozása, melyre a kurzorlekérdezés történt. Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 11 - 3. Feladat 3.1 Hozzon létre egy dolgozó nevű táblát az emp tábla rekordjaiból 3.2 Készítsen triggert a dolgozó táblába történő ellenőrzött adatbevitelhez, ahol az alábbi adatbeviteli feltételeket a trigger által meghívott tárolt alprogramokban vizsgálja

meg: a.) Részleg feltétel: Egy új dolgozó részlegeként csak már létező részleg azonosítója adható meg b.) Fizetési feltétel: Egy új dolgozó fizetésként a részlegében és vele azonos munkakörben dolgozók átlagfizetésének legalább a 3/4-ét kapja, ha a részlegében nincs vele azonos munkakörű, akkor a részlegében dolgozók átlagfizetésének 2/3-ánál legalább 300 USD-vel többet, ha pedig a részlegében ő az első dolgozó, akkor legalább 2000 USD-t. 3.3 A trigger és a tárolt eljárások ellenőrzése érdekében végezze el a szükséges adatfelviteleket 3.4 Az elkészített megoldás a tárolandó dolgozó nevét írja vissza a képernyőre, és sikeres adatfelvitel esetén írja ki a dolgozó nevét, majd az "OK!" üzenetet, míg sikertelen adatfelvitel esetén a "HIBA:" üzenetet, és a sikertelenség okát. 3.5 Utolsó lépésként listázza a dolgozó táblát, majd állítsa vissza az eredeti táblatartalmat Megoldás 0.

lépés (Az SQL*Plus környezet inicializálása) -- Az emp tábla inicializálása (ezúttal elhagyjuk) -- @INIT1 -- Feltételezve, hogy az INIT1.sql a BIN könyvtárban van -- A dátum és megjelenítés inicializálása ALTER SESSION SET NLS DATE FORMAT = YYYY-MM-DD; SET numwidth 5 -- Az esetlegesen létező azonos nevű objektumok törlése DROP VIEW dolgozó; DROP TABLE dolgozó; -- A PL/SQL kiíratások engedélyezése SET serveroutput ON; A munkamenet módosítva. ORA-00942: a tábla vagy a nézet nem létezik ORA-00942: a tábla vagy a nézet nem létezik 1. lépés feladata 3.1 Hozzon létre egy dolgozó nevű táblát az emp tábla rekordjaiból 1. lépés feladatának megoldása DROP TABLE dolgozó; CREATE TABLE dolgozó AS SELECT * FROM emp; SELECT * FROM dolgozó; ORA-00942: a tábla vagy a nézet nem létezik A tábla létrejött. EMPNO ----7839 7698 7782 7566 7654 7499 7844 7900 7521 7902 7369 ENAME ---------KING BLAKE CLARK JONES MARTIN ALLEN TURNER JAMES WARD FORD

SMITH JOB MGR HIREDATE SAL COMM DEPTNO --------- ----- ---------- ----- ----- -----PRESIDENT 1981-11-17 5000 10 MANAGER 7839 1981-05-01 2850 30 MANAGER 7839 1981-06-09 2450 10 MANAGER 7839 1981-04-02 2975 20 SALESMAN 7698 1981-09-28 1250 1400 30 SALESMAN 7698 1981-02-20 1600 300 30 SALESMAN 7698 1981-09-08 1500 0 30 CLERK 7698 1981-12-03 950 30 SALESMAN 7698 1981-02-22 1250 500 30 ANALYST 7566 1981-12-03 3000 20 CLERK 7902 1980-12-17 800 20 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 12 - 7788 SCOTT 7876 ADAMS 7934 MILLER ANALYST CLERK CLERK 7566 1987-04-19 7788 1987-05-23 7782 1982-01-23 3000 1100 1300 20 20 10 14 sor kijelölve. 2. lépés feladata 3.2 Készítsen triggert a dolgozó táblába történő ellenőrzött adatbevitelhez, ahol az alábbi adatbeviteli feltételeket a trigger által meghívott tárolt alprogramokban vizsgálja meg: a.) Részleg feltétel: Egy új dolgozó részlegeként csak már létező részleg azonosítója

adható meg b.) Fizetési feltétel: Egy új dolgozó fizetésként a részlegében és vele azonos munkakörben dolgozók átlagfizetésének legalább a 3/4-ét kapja, ha a részlegében nincs vele azonos munkakörű, akkor a részlegében dolgozók átlagfizetésének 2/3-ánál legalább 300 USD-vel többet, ha pedig a részlegében ő az első dolgozó, akkor legalább 2000 USD-t. 3.4 Az elkészített megoldás a tárolandó dolgozó nevét írja vissza a képernyőre, és sikeres adatfelvitel esetén írja ki a dolgozó nevét, majd az "OK!" üzenetet, míg sikertelen adatfelvitel esetén a "HIBA:" üzenetet, és a sikertelenség okát. 2. lépés feladatának megoldása Megjegyzés: m1. A részlegfeltétel ellenőrzése érdekében létre kell hoznunk a részleg táblát is m2. A 34 pontbeli követelményt célszerű a triggerben, illetve a trigger által meghívott tárolt eljárásokban megvalósítani 2.1 lépés (A részleg tábla létrehozása) -- Az

esetlegesen létező azonos nevű objektumok törlése DROP VIEW részleg; DROP TABLE részleg; -- A részleg tábla létrehozása CREATE TABLE részleg AS SELECT * FROM dept; SELECT * FROM részleg; ORA-00942: a tábla vagy a nézet nem létezik ORA-00942: a tábla vagy a nézet nem létezik A tábla létrejött. DEPTNO -----10 20 30 40 DNAME -------------ACCOUNTING RESEARCH SALES OPERATIONS LOC ------------NEW YORK DALLAS CHICAGO BOSTON 2.2 lépés (A részlegfeltételt ellenőrző tárolt alprogram létrehozása) -- A részleglétezést ellenőrző tárolt alprogram -- Ennek két kimenete van attól függően, hogy létezik-e a megadott részleg, -- vagy nem (ez a hiba ág). CREATE OR REPLACE PROCEDURE Részlegfeltétel(RészlegID IN NUMBER) AS Előfordulás INTEGER; BEGIN SELECT COUNT(*) INTO Előfordulás FROM részleg WHERE deptno = RészlegID; IF Előfordulás = 0 -- F-a. FELTÉTEL! THEN RAISE APPLICATION ERROR(-20110, >>HIBA: A Részlegfeltétel nem teljesül!);

Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 13 - ELSE DBMS OUTPUT.PUT LINE(OK! || (A Részlegfeltétel teljesül.)); END IF; END; / SHOW ERROR Az eljárás létrejött. Nincsenek hibák. 2.3 lépés (A fizetési feltételt ellenőrző tárolt alprogram létrehozása) -- A fizetési feltételt ellenőrző tárolt alprogramban két vizsgálatot kell elvégezni. -- Először azt, hogy van-e már a megadott részlegben dolgozó, vagy nincs, -- Ha van dolgozó, akkor pedig azt, hogy van-e azonos munkakörű, vagy nincs. CREATE OR REPLACE PROCEDURE Fizetésfeltétel(RészlegID IN NUMBER, Munkakör IN VARCHAR2, Fizetés IN NUMBER) IS RészlegbeliDolgozók INTEGER; MunkakörbeliDolgozók INTEGER; RészlegÁtlag dolgozó.sal%TYPE; MunkakörÁtlag dolgozó.sal%TYPE; FizetésHatár dolgozó.sal%TYPE; BEGIN -- Az új dolgozó részlegében már dolgozók számának meghatározása SELECT COUNT(*) INTO RészlegbeliDolgozók FROM dolgozó WHERE deptno = RészlegID;

-- A fizetés vizsgálata a részlegbeli dolgozók számától függően IF RészlegbeliDolgozók = 0 THEN -- Ekkor az új dolgozó az első dolgozó a részlegében IF Fizetés >= 2000 -- F-b3. FELTÉTEL! THEN DBMS OUTPUT.PUT LINE(OK! || (Az új fizetés legalább 2000 USD.)); ELSE RAISE APPLICATION ERROR(-20113, >>HIBA: Az új fizetés kisebb 2000 USD-nél!); END IF; ELSE -- Ekkor már vannak mások is az új dolgozó részlegében -- Kérdés: Vannak-e azonos munkakörbeliek is? SELECT COUNT(*) INTO MunkakörbeliDolgozók FROM dolgozó WHERE deptno = RészlegID AND UPPER(job) = UPPER(Munkakör); -- A fizetés vizsgálata a részlegbeli dolgozók munkakörétől függően IF MunkakörbeliDolgozók = 0 THEN -- Nincs azonos munkakörű a részlegben SELECT AVG(sal) INTO RészlegÁtlag FROM dolgozó GROUP BY deptno HAVING deptno = RészlegID; FizetésHatár := ROUND(2/3 * RészlegÁtlag) + 300; DBMS OUTPUT.PUT LINE(> 2/3 * RészlegÁtlag + 300 = || FizetésHatár); Oracle

PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 14 - IF Fizetés >= FizetésHatár -- F-b2. FELTÉTEL! THEN DBMS OUTPUT.PUT LINE(OK! || (Az új fizetés a részlegátlag 2/3-ánál min. 300 USD-vel több)); ELSE RAISE APPLICATION ERROR(-20112, >>HIBA: Az új fizetés kisebb, || mint a részlegátlag 300 USD-vel megnövelt értéke!); END IF; ELSE -- Van azonos munkakörű a részlegben SELECT AVG(sal) INTO MunkakörÁtlag FROM dolgozó GROUP BY deptno, job HAVING deptno = RészlegID AND UPPER(job) = UPPER(Munkakör); FizetésHatár := ROUND(3/4 * MunkakörÁtlag); DBMS OUTPUT.PUT LINE(> 3/4 * MunkakörÁtlag = || FizetésHatár); IF Fizetés >= FizetésHatár -- F-b1. FELTÉTEL! THEN DBMS OUTPUT.PUT LINE(OK! || (Az új fizetés a részlegbeli munkaköri átlag 3/4-nél több.)); ELSE RAISE APPLICATION ERROR(-20111, >>HIBA: Az új fizetés kisebb, || mint a részlegbeli munkaköri átlag 3/4-e!); END IF; END IF; END IF; END; / SHOW ERROR Az

eljárás létrejött. Nincsenek hibák. Megjegyzés A fenti tárolt eljárásban a SELECT AVG(sal) INTO RészlegÁtlag FROM dolgozó GROUP BY deptno HAVING deptno = RészlegID; helyett írhattuk volna SELECT AVG(sal) INTO RészlegÁtlag FROM dolgozó WHERE deptno = RészlegID; valamint a SELECT AVG(sal) INTO MunkakörÁtlag FROM dolgozó GROUP BY deptno, job HAVING deptno = RészlegID AND UPPER(job) = UPPER(Munkakör); helyett írhattuk volna SELECT AVG(sal) INTO MunkakörÁtlag FROM dolgozó WHERE deptno = RészlegID AND UPPER(job) = UPPER(Munkakör); Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 15 - 2.4 lépés (Az adatbevitel-felügyelő trigger létrehozása) -- A sortrigger a feltételvizsgáló tárolt alprogramokat hívja meg. DROP TRIGGER AdatFelügyelő; CREATE OR REPLACE TRIGGER AdatFelügyelő BEFORE INSERT ON dolgozó FOR EACH ROW BEGIN DBMS OUTPUT.PUT LINE (> A felviendő dolgozó: ||:newename); Részlegfeltétel(:new.deptno);

Fizetésfeltétel(:new.deptno, :newjob, :newsal); DBMS OUTPUT.PUT LINE (:newename || : OK!); END; / SHOW ERROR ORA-04080: ADATFELÜGYELŐ trigger nem létezik A trigger létrejött. Nincsenek hibák. 3. lépés feladata 3.3 A trigger és a tárolt eljárások ellenőrzése érdekében végezze el a szükséges adatfelviteleket 3. lépés feladatának megoldása (A felügyelt adatbevitel ellenőrzése) Az alábbiakban ellenőrizni kell az F-a., F-b1, F-b2 és F-b3 feltételek mindegyikének teljesülését és nem teljesülését. Ennek célszerű módja olyan adatfelviteleket készíteni, melyekben mindig csak egy feltétel nem-teljesülését és teljesülését vizsgáljuk. Mivel az F-a feltétel teljesülése az összes többihez szükséges, így mindössze hét adatfelvitel szükséges a teljes ellenőrzéshez. 3.1 lépés (Adatlekérdezések az ellenőrzéshez) -- Részlegenkénti munkaköri átlagok (az F-b1. feltétel vizsgálatához) SELECT deptno job ROUND(AVG(sal)*3/4) FROM

dolgozó GROUP BY deptno, job; RÉSZLEG ---------10 10 10 20 20 20 30 30 30 AS Részleg, AS Munkakör, AS "RészlegMunkakörÁtlag 3/4-e" MUNKAKÖR RészlegMunkakörÁtlag 3/4-e --------- -------------------------CLERK 975 MANAGER 1838 PRESIDENT 3750 CLERK 713 ANALYST 2250 MANAGER 2231 CLERK 713 MANAGER 2138 SALESMAN 1050 9 sor kijelölve. -- Részlegátlagok (az F-b2. feltétel vizsgálatához) SELECT deptno ROUND(AVG(SAL)*2/3)+300 FROM dolgozó GROUP BY deptno; AS Részleg, AS "2/3-ad RészlegÁtlag + 300" RÉSZLEG 2/3-ad RészlegÁtlag + 300 ---------- ------------------------10 2244 20 1750 30 1344 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 16 - 3.2 lépés (Ellenőrzések) -- 1. Ellenőrzés: -- Az F-a. (Részlegfeltétel) NEM-teljesülésének vizsgálata INSERT INTO dolgozó VALUES(1234,Péter(a),SALESMAN,7698,2005.1211,2000,NULL,50); > A felviendő dolgozó: Péter(a) INSERT INTO dolgozó * Hiba a(z) 1. sorban:

ORA-20110: >>HIBA: A Részlegfeltétel nem teljesül! ORA-06512: a(z) "SCOTT.RÉSZLEGFELTÉTEL", helyen a(z) 11 sornál ORA-06512: a(z) "SCOTT.ADATFELÜGYELŐ", helyen a(z) 3 sornál ORA-04088: hiba a(z) SCOTT.ADATFELÜGYELŐ trigger futása közben -- 2. Ellenőrzés: -- Az F-a. (Részlegfeltétel) teljesülése mellett -- az F-b1. (Fizetési feltétel, RészlegMunkakör Fizátlag 3/4-e) vizsgálata INSERT INTO dolgozó VALUES(1234,János1(b1),SALESMAN,7698,2005.1211,1049,NULL,30); INSERT INTO dolgozó VALUES(1234,János2(b1),SALESMAN,7698,2005.1211,1050,NULL,30); > A felviendő dolgozó: János1(b1) OK! (A Részlegfeltétel teljesül.) > 3/4 * MunkakörÁtlag = 1050 INSERT INTO dolgozó * Hiba a(z) 1. sorban: ORA-20111: >>HIBA: Az új fizetés kisebb, mint a részlegbeli munkaköri átlag 3/4-e! ORA-06512: a(z) "SCOTT.FIZETÉSFELTÉTEL", helyen a(z) 78 sornál ORA-06512: a(z) "SCOTT.ADATFELÜGYELŐ", helyen a(z) 4 sornál

ORA-04088: hiba a(z) SCOTT.ADATFELÜGYELŐ trigger futása közben > A felviendő dolgozó: János2(b1) OK! (A Részlegfeltétel teljesül.) > 3/4 * MunkakörÁtlag = 1050 OK! (Az új fizetés a részlegbeli munkaköri átlag 3/4-nél több.) János2(b1): OK! 1 sor létrejött. -- 3. Ellenőrzés: -- Az F-a. (Részlegfeltétel) teljesülése mellett -- az F-b2. (Fizetési feltétel, 2/3-ad RészlegÁtlag + 300) NEM-teljesülésének vizsgálata INSERT INTO dolgozó VALUES(1234,Éva1(b2),TANULÓ,7698,2005.1211,1749,NULL,20); INSERT INTO dolgozó VALUES(1234,Éva2(b2),TANULÓ,7698,2005.1211,1750,NULL,20); > A felviendő dolgozó: Éva1(b2) OK! (A Részlegfeltétel teljesül.) > 2/3 * RészlegÁtlag + 300 = 1750 INSERT INTO dolgozó * Hiba a(z) 1. sorban: ORA-20112: >>HIBA: Az új fizetés kisebb, mint a részlegátlag 300 USD-vel megnövelt értéke! ORA-06512: a(z) "SCOTT.FIZETÉSFELTÉTEL", helyen a(z) 57 sornál ORA-06512: a(z)

"SCOTT.ADATFELÜGYELŐ", helyen a(z) 4 sornál ORA-04088: hiba a(z) SCOTT.ADATFELÜGYELŐ trigger futása közben > A felviendő dolgozó: Éva2(b2) OK! (A Részlegfeltétel teljesül.) > 2/3 * RészlegÁtlag + 300 = 1750 OK! (Az új fizetés a részlegátlag 2/3-ánál min. 300 USD-vel több) Éva2(b2): OK! 1 sor létrejött. Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 17 - -- 4. Ellenőrzés: -- Az F-a. (Részlegfeltétel) teljesülése mellett -- az F-b3. (Fizetési feltétel, a részlegben még nincs dolgozó) NEM-teljesülésének vizsgálata INSERT INTO dolgozó VALUES(1234,Ágnes1(b3),SALESMAN,7698,2005.1211,1999,NULL,40); INSERT INTO dolgozó VALUES(1234,Ágnes2(b3),SALESMAN,7698,2005.1211,2000,NULL,40); > A felviendő dolgozó: Ágnes1(b3) OK! (A Részlegfeltétel teljesül.) INSERT INTO dolgozó * Hiba a(z) 1. sorban: ORA-20113: >>HIBA: Az új fizetés kisebb 2000 USD-nél! ORA-06512: a(z)

"SCOTT.FIZETÉSFELTÉTEL", helyen a(z) 27 sornál ORA-06512: a(z) "SCOTT.ADATFELÜGYELŐ", helyen a(z) 4 sornál ORA-04088: hiba a(z) SCOTT.ADATFELÜGYELŐ trigger futása közben > A felviendő dolgozó: Ágnes2(b3) OK! (A Részlegfeltétel teljesül.) OK! (Az új fizetés legalább 2000 USD.) Ágnes2(b3): OK! 1 sor létrejött. 4. lépés feladata 3.5 Utolsó lépésként listázza a dolgozó táblát, majd állítsa vissza az eredeti táblatartalmat 4. lépés feladatának megoldása -- A dolgozó tábla listázása és adatvisszaállítás SELECT * FROM dolgozó; ROLLBACK; SELECT * FROM dolgozó; EMPNO ---------7839 7698 7782 7566 7654 7499 7844 7900 7521 7902 7369 7788 7876 7934 1234 1234 1234 ENAME ---------KING BLAKE CLARK JONES MARTIN ALLEN TURNER JAMES WARD FORD SMITH SCOTT ADAMS MILLER János2(b1) Éva2(b2) Ágnes2(b3) JOB MGR HIREDATE SAL COMM DEPTNO --------- ---------- ---------- ---------- ---------- ---------PRESIDENT 1981-11-17 5000 10 MANAGER

7839 1981-05-01 2850 30 MANAGER 7839 1981-06-09 2450 10 MANAGER 7839 1981-04-02 2975 20 SALESMAN 7698 1981-09-28 1250 1400 30 SALESMAN 7698 1981-02-20 1600 300 30 SALESMAN 7698 1981-09-08 1500 0 30 CLERK 7698 1981-12-03 950 30 SALESMAN 7698 1981-02-22 1250 500 30 ANALYST 7566 1981-12-03 3000 20 CLERK 7902 1980-12-17 800 20 ANALYST 7566 1987-04-19 3000 20 CLERK 7788 1987-05-23 1100 20 CLERK 7782 1982-01-23 1300 10 SALESMAN 7698 2005-12-11 1050 30 TANULÓ 7698 2005-12-11 1750 20 SALESMAN 7698 2005-12-11 2000 40 17 sor kijelölve. A visszaállítás befejeződött. EMPNO ---------7839 7698 7782 7566 7654 7499 7844 7900 7521 7902 7369 ENAME ---------KING BLAKE CLARK JONES MARTIN ALLEN TURNER JAMES WARD FORD SMITH JOB MGR HIREDATE SAL COMM DEPTNO --------- ---------- ---------- ---------- ---------- ---------PRESIDENT 1981-11-17 5000 10 MANAGER 7839 1981-05-01 2850 30 MANAGER 7839 1981-06-09 2450 10 MANAGER 7839 1981-04-02 2975 20 SALESMAN 7698 1981-09-28 1250 1400 30 SALESMAN 7698

1981-02-20 1600 300 30 SALESMAN 7698 1981-09-08 1500 0 30 CLERK 7698 1981-12-03 950 30 SALESMAN 7698 1981-02-22 1250 500 30 ANALYST 7566 1981-12-03 3000 20 CLERK 7902 1980-12-17 800 20 Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 18 - 7788 SCOTT 7876 ADAMS 7934 MILLER ANALYST CLERK CLERK 7566 1987-04-19 7788 1987-05-23 7782 1982-01-23 14 sor kijelölve. Oracle PL-SQL összefoglaló feladatok, megoldással (2005, 19 oldal) - 19 - 3000 1100 1300 20 20 10