10.07.2015 Views

PL/SQL I.

PL/SQL I.

PL/SQL I.

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>PL</strong>/<strong>SQL</strong> 1. részProcedural Language extension to <strong>SQL</strong>


• utasítást ; zárja le• <strong>PL</strong>/<strong>SQL</strong> blokk lezárása: /Szintaxis• kis- és nagybetű egyenértékű (az utasításokban akulcsszavakat szoktuk nagybetűvel írni, de nem kötelező)• megjegyzés: REM vagy --, többsoros /* */• használat előtt deklarálni kell a változókat, azonosítókat,eljárásokat• ** hatványozás, != nem egyenlő, || karakterláncösszefűzés• egy <strong>PL</strong>/<strong>SQL</strong> program egy vagy több blokkból áll, ablokkok egymásba ágyazhatók


Blokk felépítése[blokk név][DECLARE[lokális változók] ]BEGIN[utasítás blokk][EXCEPTION[kivételkezelés] ]END [blokk név];/Megjegyzés:• A törtvonal akkor kell,ha több utasítást,blokkot szeretnénk egyszkriptbe írni• A törtvonalat lehet . -alhelyettesíteni


Blokk jellemzői• Egy <strong>PL</strong>/<strong>SQL</strong> program egy vagy több blokkból is állhat• A blokkok egymásba ágyazhatók• Blokk lehet:• anonymus blokk (névtelen) – nem tárolódik le az adatbázisban• névvel ellátott• alprogram (paraméterezhetőek):• függvény (FUNCTION) - van visszatérési értéke• eljárás (PROCEDURE)• <strong>PL</strong>/<strong>SQL</strong> blokk tartalmazhat: <strong>SQL</strong> parancsfájl, eljárás vagyfüggvény, befogadó nyelvi program, trigger


PéldaVAR X NUMBERDECLAREa NUMBER;BEGINa := 3;:X := a + 3;END;.PRINT XACCEPT szovegVARCHAR(30) PROMPT'Adj meg valami szöveget';DECLAREa VARCHAR(60);BEGINa := &szoveg;dbms_output.put_line(a);END;/


Deklaráció szintaxisa• változónév [CONSTANT] adattípus [NOT NULL][DEFAULT érték]• CONSTANT és NOT NULL esetén a kezdőértékadáskötelező• DEFAULT helyett ":=" is írható.• Példák:szoveg VARCHAR2(50);szam NUMBER DEFAULT 10;szam NUMBER := 10;egy CONSTANT NUMBER := 1;


PéldaDECLAREa CONSTANT NUMBER := 3;b NUMBER NOT NULL := 5;BEGIN:X := :X + a + b + 3;END;/PRINT X


DBMS_OUTPUT (<strong>PL</strong>/<strong>SQL</strong> csomag)• Kiíratni a DBMS_OUTPUT csomag segítségével lehet• Használatát a SET SERVEROUTPUT ON <strong>SQL</strong>*Plusparanccsal engedélyezni kell• Föbb kiíratási függvényei:• PUT: ugyanabba a sorba ír több outputot• NEW_LINE: sor végét jelzi• PUT_LINE: minden outputot külön sorba ír• Egy bufferbe íródik először a kiírandó szöveg. Hasikeresen lefutott a program, akkor a buffer tartalma aképernyőre íródik.


PéldaSET SERVEROUTPUT ONACCEPT nev PROMPT 'Kerem adja meg a nevét: 'DECLAREszoveg varchar2(50);BEGINszoveg := CONCAT('&nev',' sikeresen végrehajtotta a programot!');DBMS_OUTPUT.PUT_LINE (szoveg);END;


Változó értékadás a SELECT... INTO... utasítással• SELECT utasítás <strong>PL</strong>/<strong>SQL</strong> blokkon belüli használatakor azINTO alparanccsal változó(k)hoz rendelünk értéket• Csak akkor fut le helyesen, ha pontosan egy értéket advisszaCREATE TABLE T1(e INTEGER,f INTEGER);INSERT INTO T1VALUES(1, 3);INSERT INTO T1VALUES(2, 4);DECLAREa NUMBER;b NUMBER;BEGINSELECT e,f INTO a,bFROM T1 WHERE e>1;INSERT INTO T1VALUES(b,a);END;


Rekordtípus• Rekord deklarálása:• TYPE rekordtípusnév IS RECORD (mezőnév típus,...,mezőnév típus);• Rekord típusú váltózó létrehozása:• változónév rekordtípusnév;• Hivatkozás a komponensekre:• változónév.mezőnév


Változó deklarálás adattáblatípusokból• Tábla egy mezőjének típusára hivatkozás:• változónév tábla.mező%TYPE;• Rekord típusú változó létrehozása (sor típusú változó):• változónév tábla%ROWTYPE;• Hivatkozás egy oszlopára:• változónév.oszlop;


Példa Rekord használatáraDECLARETYPE dolgozo_rekord IS RECORD (adoszamINTEGER, nev CHAR(30), lakcim VARCHAR(50));BEGINEND;egy_dolgozo dolgozo_rekord;egy_dolgozo.nev = 'Kovacs';


Példa TYPE használatáraDECLAREfizetes emp.sal%TYPE;BEGINSELECT avg(sal) INTO fizetesFROM emp;DBMS_OUTPUT.PUT_LINE('Átlagos fizetés: ' || fizetes);END;


Példa ROWTYPE használatáraDECLAREv_sor emp%ROWTYPE;BEGINSELECT * INTO v_sorFROM empWHERE ename LIKE 'WARD';DBMS_OUTPUT.PUT_LINE(v_sor.ename || ' fizetése: ' ||v_sor.sal);END;


Vezérlési szerkezetekIFIF feltétel THENutasítások[ELSIF feltétel THENutasítások]…[ELSEutasítások]END IF;


PéldaDECLAREv_avgber emp.sal%TYPE;szoveg VARCHAR2(50);BEGINSELECT AVG(sal)INTO v_avgberFROM emp;IF v_avgber < 2000 THENszoveg:='kevesebb mint ketezer';ELSIF (v_avgber > 2000) AND (v_avgber


CASE• CASE valtozo, WHEN ertek THEN, ..., ELSE, ENDCASE;• Példa:CASE numWHEN 1 THEN dbms_output.put_line('Egy');. . .WHEN 9 THEN dbms_output.put_line('Kilenc');ELSE dbms_output.put_line('Nem egyjegyu');END CASE;


LOOP Ciklusutasítások• Végtelen ciklus kilépési ponttal:LOOPutasítások[EXIT;][EXIT WHEN feltétel;]END LOOP;


PéldaDECLAREv_sorsz dept.deptno%TYPE := 10;v_megnev dept.dname%TYPE;BEGINLOOPSELECT dnameINTO v_megnevFROM deptWHERE deptno = v_sorsz;DBMS_OUTPUT.PUT_LINE(v_megnev);v_sorsz := v_sorsz +10;EXIT WHEN v_sorsz > 30;END LOOP;END;


WHILE cilkus• WHILE feltétel, LOOP, END LOOP;DECLAREv_sorsz dept.deptno%TYPE := 10;v_megnev dept.dname%TYPE;BEGINWHILE v_sorsz < 40LOOPSELECT dnameINTO v_megnevFROM deptWHERE deptno = v_sorsz;DBMS_OUTPUT.PUT_LINE(v_megnev);v_sorsz := v_sorsz +10;END LOOP;END;


FOR ciklus• FOR ciklusváltozó IN [REVERSE] alsóhatár .. felsohatár LOOP,END LOOP;BEGINFOR num IN 1..10 LOOPDBMS_OUTPUT.PUT_LINE(num ||'^2='||num*num);END LOOP;END;


Gyűjtőtábla deklarálása• Létrehozás:TYPE táblatípusnévIS TABLE OF {oszloptípus | rekordtípus}INDEX BY BINARY_INTEGER• Tábla típusú változó deklarálása:• változónév táblatípusnév;• Összes rekord egy gyűjtőtáblába:• SELECT * bulk collect INTO valtozonev FROM dept;• az INSERT, UPDATE, FETCH, SELECT utasításokkalkezelhető, de soraira változónév(index) módon ishivatkozhatunk. Ha nem létező indexre hivatkozunk,NO_DATA_FOUND kivétel keletkezik.


Gyűjtőtábla metódusok• EXISTS(n) - igaz, ha létezik az n-edik elem• COUNT - táblában lévő elemek száma• FIRST - tábla első indexértéke• LAST - tábla utolsó indexértéke• NEXT - a táblában a következő index értéke• DELETE(n) - az n-edik elem törlése


PéldaDECLARETYPE tipus IS TABLE OF dept%ROWTYPEINDEX BY BINARY_INTEGER;valtozo tipus;ind BINARY_INTEGER := 1;BEGINLOOPSELECT * INTO valtozo(ind)FROM deptWHERE deptno = ind * 10;ind := ind + 1;EXIT WHEN ind > 4;END LOOP;ind := valtozo.FIRST;LOOPDBMS_OUTPUT.PUT_LINE( valtozo(ind).dname);ind := ind + 1;EXIT WHEN ind > valtozo.LAST;END LOOP;END;


[blokk név][DECLARE[lokális változók] ]BEGIN[utasítás blokk][EXCEPTION[kivételkezelés] ]END [blokk név];/• Kivételek típusai:• Rendszer által definiált• Felhasználó által definiáltKivételkezelésEXCEPTIONWHEN kivétel [OR kivétel ...] THENutasítások[WHEN kivétel [OR kivétel ...] THENutasítások]...[WHEN OTHERS THENutasítások]• A WHEN OTHERS rész a fel nem sorolt kivételek elfogásáraszolgál


Rendszerbeli kivételek• NO_DATA_FOUND: SELECT utasitas nem ad visszasort• TOO_MANY_ROWS: egy sort kellett volna visszaadniaegy SELECT-nek, de többet kaptunk• INVALID_NUMBER: karakterlánc sikertelen számmákonvertálása• DUP_VAL_ON_INDEX: kulcsfeltétel megsértése


PéldaDECLAREv_ber emp.sal%TYPE;v_nev emp.ename%TYPE;BEGINv_ber := 3000;SELECT enameINTO v_nevFROM empWHERE sal = v_ber;DBMS_OUTPUT.PUT_LINE(v_nev);EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('Nincs ilyen fizetés');WHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('Több embernek is ez afizetése');WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Egyéb hiba');END;


Felhasználói kivételek• a DECLARE szakaszban:• kivételnév EXCEPTION;• végrehajtható szegmensben kivétel dobása:• RAISE kivételnév;


Felhasználói kivételekDECLAREnincs_vevo EXCEPTION;BEGINDBMS_OUTPUT.PUT_LINE('Ez vegrehajtodik');RAISE nincs_vevo;DBMS_OUTPUT.PUT_LINE('Ez nem hajtodikvegre');EXCEPTIONWHEN nincs_vevo THENDBMS_OUTPUT.PUT_LINE('Nincs ilyen vevo');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('Egyéb hiba');END;


Feladatok1. Kérj be két egész számot, és döntsd el, hogy az összegükpáros vagy páratlan!2. Adj egy programot, ami kiírja az EMP tábla sorainakszámát, és a tárolt dolgozók átlagfizetését.3. Adj meg egy programot, ami létrehozza a FIBON(n,ertek)táblát, és feltölti azt n=100-ig a Fibonacci számokkal


1. Feladatok megoldásaSET SERVEROUTPUT ON;ACCEPT elso PROMT 'elso:';ACCEPT masodik PROMT 'masodik:';DECLAREosszeg NUMBER;BEGINosszeg:=&elso+&masodik;IF MOD(osszeg,2)=0 THENDBMS_OUTPUT.PUT_LINE('Paros');ELSEDBMS_OUTPUT.PUT_LINE('Paratlan');END IF;END;


2. Feladatok megoldásaSET SERVEROUTPUT ONDECLAREsorok NUMBER;atlag_fiz NUMBER;BEGINSELECT COUNT(*), AVG(sal) INTO sorok, atlag_fizFROM EMP;DBMS_OUTPUT.PUT_LINE('Sorok szama: ' || sorok);DBMS_OUTPUT.PUT_LINE('Atlag fizetes: ' || atlag_fiz);END;


3. Feladatok megoldásaDROP TABLE FIBON;CREATE TABLE FIBON(n NUMBER(5) PRIMARY KEY,ertek NUMBER(28));INSERT INTO FIBON VALUES(0, 0);INSERT INTO FIBON VALUES(1, 1);DECLAREf_szam FIBON.ertek%TYPE;f_1 FIBON.ertek%TYPE;f_2 FIBON.ertek%TYPE;BEGINFOR i IN 2..100 LOOPSELECT ertek INTO f_1 FROM FIBON WHERE n=i-1;SELECT ertek INTO f_2 FROM FIBON WHERE n=i-2;INSERT INTO FIBON VALUES (i, f_1+f_2);END LOOP;END;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!