Adatbázisok szerver oldali programozása Előadás, 2006.03.31.
Ez az oldal a korábbi SCH wikiről lett áthozva.
Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!
Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.
<style> code.pre { white-space: pre; display: block; mergin-top: 2px; margin-bottom: 2px;} li { line-height: 18px; } </style>
Csomagok
A csomag egy olyan séma objektum, ami logikailag összetartozó elemeket tartalmaz. Részei:
- Típusok
- Alprogramok
- Kivételek
A csomagok 2 részből állnak:
- nyilvános specifikáció (interfész)
- privát törzs (implementáció)
Csomagok célja
- logikailag összetartozó függvények egységbe zárása
- olyan eljárás létrehozása, aminek a kimenő paramétere eredményhalmaz
- SQL Serverben van lehetőség eljáráson belül több sort visszaadó
SELECT
-ek hívására. Az eredményt a kliens olvassa ki. - Oracle-ben az eredményt kötelező változóban elhelyezni (
SELECT ... INTO
). Több soros kimenetet csak kurzor változóval lehet kezelni, amit vagy lokálisan, vagy csomagon belül kell deklarálni. A Java támogatja a kurzor típust, a Visual Studioban csak külön plugin telepítése után lehet kiolvasni a kurzorváltozó tartalmát.
- SQL Serverben van lehetőség eljáráson belül több sort visszaadó
Csomagok előnyei
- modularitás
- egyszerű programfejlesztés: a specifikáció fordítható a törzs nélkül is
- információ elrejtés
- bővített funkcionalitás: a változók és a kurzorok a session végéig élnek, az alprogramok megosztva használhatják őket
- teljesítmény: lehetőség van tranzakciók között infót átadni táblák használata nélkül (1 sessionben)
Felhasználó által definiált csomagok
Vizsgán az Oracle rész egyik feladata biztosan csomagkezelésről fog szólni.
Szintaxis
Csomag fejléc
CREATE [OR REPLACE] PACKAGE csomagnév
[AUTHID {CURRENT_USER|DEFINER}]
{IS|AS}
kollekció típusok
altípusok
konstansok
kivételek
objektumok
kurzor deklarációk
függvény deklarációk
eljárás deklarációk
END [csomagnév];
- Az =AUTHID= azt határozza meg, hogy a csomag alprogramjai kinek a nevében fussanak.
- A deklarációs részben utoljára kell felsorolni a függvényeket és az eljárásokat.
Csomag törzs
CREATE [OR REPLACE] PACKAGE BODY csomagnév
...
lokális változók
kurzor törzsek
függvény törzsek
eljárás törzsek
[BEGIN
utasítások;]
END [csomagnév];
- A csomag törzsében az alprogramok deklarációjának karakterről karakterre meg kell egyeznie a csomag fejlécében található deklarációval.
- A =BEGIN= és =END= közötti szakasz az első függvényhívás előtt fut le.
Példa: jogosultságkezelés a tanár-diák adatbázisban
ALTER TABLE student ADD stud_pwd VARCHAR2(20);
UPDATE student SET stud_pwd='jelszo' WHERE stud_id='XSFXCF';
CREATE PACKAGE userlogin IS
hibasjelszo EXCEPTION;
nincsbelepve EXCEPTION;
PROCEDURE login(id CHAR, passwd VARCHAR2);
PROCEDURE logout;
FUNCTION is_logged_in(hibatdob BOOLEAN) RETURN BOOLEAN;
END;
CREATE PACKAGE BODY userlogin IS
loggedin BOOLEAN;
PROCEDURE login(id CHAR, passwd VARCHAR2) IS
jelszo VARCHAR2(20);
BEGIN
SELECT stud_pwd INTO jelszo FROM student WHERE stud_id=id;
IF passwd!=jelszo THEN
RAISE hibasjelszo;
ELSE
loggedin:=TRUE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
loggedin:=FALSE;
RAISE hibasjelszo;
END;
PROCEDURE logout IS
BEGIN
loggedin:=FALSE;
END;
FUNCTION is_logged_in(dobhibat BOOLEAN)
RETURN boolean IS
BEGIN
IF dobhibat AND loggedin=FALSE THEN
RAISE nincsbelepve;
END;
RETURN loggedin;
END;
BEGIN
loggedin:=FALSE;
END userlogin;
Példa a userlogin csomag használata
CREATE PROCEDURE getcourses(diakid CHAR, szemeszter CHAR)
IS
belepve BOOLEAN;
CURSOR c IS SELECT sub_id, sub_name
FROM subject, course, sutdent_course
WHERE sc_studentid = diakid
AND sc_courseid = cou_id
AND cou_semestername = szemeszter
AND cou_subjectid = sub_id;
BEGIN
belepve:=userlogin.is_logged_in(true);
FOR crec IN c LOOP
DBMS_OUTPUT.PUT_LINE(crec.sub_id ||| ' ' || crec.sub_name);
END LOOP;
EXCEPTION
WHEN userlogin.nincsbelepve
RAISE_APPLICATION_ERROR(-20101, 'nincs belépve');
END;
DECLARE
code VARCHAR2(20);
message VARCHAR2(200);
BEGIN
getcourses('XSFXCF', '20012');
EXCEPTION
WHEN OTHERS THEN
code:=SQLCODE;
message:=SQLERRM;
DBMS_OUTPUT.PUT_LINE(code ||| ' ' || message);
userlogin.login('XSFXCF', 'jelszo');
getcourses('XSFXCF', '20012');
userlogin.logout;
getcourses('XSFXCF', '20012');
END;
Példa kurzor típusú kimenetre
CREATE PACKAGE tanar_csomag IS
TYPE tanarlista_type IS REF CURSOR;
PROCEDURE tanar_lista(tanszekkod CHAR, tanarlista OUT tanarlista_type);
END;
CREATE PACKAGE BODY tanar_csomag IS
PROCEDURE tanar_lista(tanszekkod CHAR, tanarlista OUT tanarlista_type) IS
BEGIN
OPEN tanarlista FOR
SELECT tea_grade ||| ' ' |||| tea_lname |||| ' ' || tea_fname, tea_id, status_id
FROM teacher, sort_status
WHERE tea_status=status_id AND tea_dept=tanszekkod
ORDER BY status_id;
END;
END tanar_csomag;
Használat:
DECLARE
tanlist tanar_csomag.tanar_lista('AUT', tanlist);
LOOP
FETCH tanlist INTO nev, kod, statusz;
EXIT WHEN tanlista%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(...);
END LOOP;
END;
Beépített csomagok
Vizsgakérdés lehet, hogy soroljunk fel hármat.
- =DBMS_OUTPUT=: standard output
- =STANDARD=: kivételek, sysdate, sum, ...
- =DBMS_LOB=: large objectek kezelése
- =DBMS_PIPE=: sessionök közti kommunikáció
- =UTL_FILE=: filekezelés
- =DBMS_LOCK=:
- =DBMS_RANDOM=: véletlenszám generálás
-- Peti - 2006.04.02.