Adatbázisok szerver oldali programozása Előadás, 2006.03.31.

A VIK Wikiből

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>


<< Előadás, 2006.03.31. >>

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

  1. logikailag összetartozó függvények egységbe zárása
  2. 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.

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.