ΑΠΟΘΗΚΕΥΜΕΝΕΣΔΙΑΔΙΚΑΣΙΕΣ ΓΕΝΙΚΑ Οι αποθηκευμένες διαδικασίες είναι τμήματα προγράμματος Βάσης Δεδομένων (διαδικασίες\procedures ή συναρτήσεις\functions) που αποθηκεύονται μόνιμα και εκτελούνταιστονδιακομιστήτηςβάσηςδεδομένων. Έχουνταπαρακάτωχαρακτηριστικά: ΑποθηκεύονταικαιτρέχουνστονδιακομιστήτηςΒάσης. ΚαλούνταιμετοόνοματουςαπόοποιαδήποτεεφαρμογήσυνδεθείμετηΒάση. Ηεφαρμογήμπορείναχωριστείσεδύομέρη: Ηεφαρμογήτρέχειστονπελάτη Ηαποθηκευμένηδιαδικασίαστονδιακομιστή. Περιέχει προγραμματιστικές εντολές (if, loops) αλλά ταυτόχρονα μπορεί να χειριστείsqlκώδικα. Επίσης,μπορούνναχρησιμοποιηθούνγιαένααπότουςπαρακάτωλόγους: Γιαέλεγχοπολύπλοκωνπεριορισμών. Γιααπόκρυψητουκώδικατηςδιαδικασίας. Γιαδημιουργίαβιβλιοθήκηςέτοιμωνσυναρτήσεωνστονδιακομιστή. ΓιαδημιουργίαDataWebServicesμεβάσητιςαποθηκευμένεςδιαδικασίες. Τασημαντικότεραπλεονεκτήματάτους,είναι: 1. ΒελτιώνουντηνασφάλειατουDBMS.Υποστηρίζουντο«κρύψιμο»(encapsulation) του κώδικα τους, και με σωστό σχεδιασμό και τη συστηματική χρήση τους είναι δυνατόνναεξαφανιστείηδομήτηςβάσηςαπότουςχρήστες. 2. ΒελτιώνειτηνταχύτητααπόκρισηςτουεξυπηρετητήτηςΒάσης.Αυτόοφείλεταιστο ότιείναιπρομεταγλωττισμένες(precompiled)καιέτσιεκτελούνταιγρηγορότερα. 3. Τέλος, αντικαθιστώντας ένα σύνολο SQL εντολών με την κλήση μιας συνάρτησης που περιέχει όλες αυτές τις SQL εντολές, «ελαφρύνει» την κίνηση στο δίκτυο μεταξύ πελάτη και διακομιστή. Για παράδειγμα, αν η συνάρτηση περιέχει 10 SQL εντολέςτότεανεκτελέσουμεξεχωριστάκάθεsqlεντολήστονπελάτηθαέχουμε10 κλήσειςτηςβάσηςστονεξυπηρετητήενώανόλεςοιsqlεντολέςέχουνοργανωθεί
σε μία καταχωρημένη διεργασία τότε θα απαιτείται μία κλήση της βάσης στον εξυπηρετητή,γιανακληθείμόνοηδιαδικασία. ΤΡΟΠΟΣΥΛΟΠΟΙΗΣΗΣ ΟτρόποςυλοποίησηςμιαςαποθηκευμένηςδιαδικασίαςδιαφέρειαπόΣΔΒΔσεΣΔΒΔ.Δύο είναιοιπιθανοίτρόποιυλοποίησης: 1. εσωτερικάστοσδβδμεχρήσηsqlεντολώνκαιονομάζεταιsqlstoredprocedure 2. εξωτερικάσεμίαγλώσσαπρογραμματισμού. Εδώθαπαρουσιάσουμεμόνοτηνπρώτηπερίπτωση,ηοποίαχωρίζεταισεδύοκατηγορίες. ΣτιςδιαδικασίεςπουχρησιμοποιούνμόνοSQLεντολέςκαισεαυτέςπουχρησιμοποιούνκαι προγραμματιστικέςεντολέςόπωςif THEN ELSE,LOOPsκτλ. ΗσύνταξημίαςσυνάρτησηςστηνPOSTGRESείναι: CREATE FUNCTION όνοµα_συνάρτησης(τύπος_παρ 1,τύπος_παρ 2,,τύπος_παρ n ) RETURNS τύπος AS $$ Λίσταεντολών $$ LANGUAGE SQL ή plpgsql; SQLδιαδικασίες ΤαβασικάχαρακτηριστικάτωνδιαδικασιώνπουχρησιμοποιούνμόνοSQLεντολέςείναιτα παρακάτω: ΟιSQLσυναρτήσειςεκτελούνμίαλίστααπόSQLεντολές. Στην απλή περίπτωση επιστρέφουν την πρώτη γραμμή(εγγραφή) του αποτελέσματος τηςτελευταίαςεντολής. Υπάρχει η δυνατότητα να επιστρέψουν και μία συλλογή από γραμμές του αποτελέσματος. Ανητελευταίαεντολήδενεπιστρέφεικαθόλουεγγραφέςεπιστρέφεταιητιμήvoid. ΤοσώμαμιαςSQLσυνάρτησηςπρέπειναείναιμιαλίσταμιαςήπερισσότερωνεντολών SQL,χωρισμένωνμεερωτηματικό(;).
Παράδειγμαvoidσυνάρτησης create function createdb() returns void AS $$ create table Sailors (sid integer not null, sname varchar(15), rating integer, age real, primary key(sid)); create table Boats (bid integer not null, bname char(20), color char(20), primary key(bid), constraint b_color check (color in ('red', 'green', 'blue', 'yellow')) ); create table Reserves (sid integer not null, bid integer not null, day1 date not null, primary key (sid, bid, day1), constraint r_sid foreign key(sid) references Sailors on delete cascade on update cascade, constraint r_bid foreign key(bid) references Boats on delete cascade on update cascade); ΗκλήσημίαςσυνάρτησηςγίνεταιωςSELECTαίτημαμεκλήσητηςσυνάρτησης. SELECT CREATEDB(); Παράδειγμασυνάρτησηςπουεπιστρέφειέναναπλόβασικότύπο CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$ SELECT $1 + $2; SELECT add_em(1, 2) AS answer; Ηστήλητουαποτελέσματοςθαέχειόνομαanswer.Ανπαραληφθείτο«ASanswer»τότετο όνοματουαποτελέσματοςθαείναιτοόνοματηςσυνάρτησης. ΣεμίασυνάρτησηείναιδυνατόνναομαδοποιηθούνένασύνολοδιαφορετικώντύπωνSQL εντολών. Εκτός από SELECT εντολές μπορούν να συμπεριληφθούν και οι INSERT, UPDATE και DELETE. Η τελευταία εντολή, όμως, θα πρέπει να είναι μία SELECT της οποίας το αποτέλεσμάτηςθαείναικαιηεπιστρεφόμενητιμήτηςσυνάρτηση.ανπάλι,δεθέλουμενα
μας επιστραφεί καμία τιμή τότε θα βάλουμε σαν επιστρεφόμενο τύπο της συνάρτηση το void.σεαυτήτηνπερίπτωσηητελευταίαεντολήδεθαπρέπειναείναιselect. Παράδειγμασυνάρτησηςπουεπιστρέφειένανσύνθετοτύπο Ότανορίζουμεσυναρτήσειςμεπαραμέτρουςσύνθετωντύπων,πρέπειναπροσδιορίσουμε όχιμόνοποιαπαράμετροθέλουμε(όπωςκάναμεμετα$1και$2)αλλάκαιταπεδίααυτής της παραμέτρου. Στο ακόλουθο παράδειγμα ο emp είναι ένας πίνακας υπαλλήλων. Ως εκ τούτου, είναι και το όνομα του σύνθετου τύπου κάθε γραμμής του πίνακα. Η συνάρτηση double_salaryυπολογίζειτοδιπλάσιοτουμισθούκάποιουυπαλλήλου: CREATE TABLE emp ( name varchar(20) primary key, salary integer, age integer ); CREATE FUNCTION double_salary(emp) RETURNS integer AS $$ SELECT $1.salary * 2 AS salary; Κλήση SELECT name, double_salary(emp) AS dream FROM emp WHERE emp.name = 'Maria'; ή SELECT name, double_salary(emp.*) AS dream FROM emp WHERE emp.name = 'Maria'; ΌλεςοιSQLσυναρτήσειςμπορούνναχρησιμοποιηθούνστοτμήμαFROMενόςquery.Αυτό είναι ιδιαίτερα χρήσιμο για συναρτήσεις που επιστρέφουν σύνθετους τύπους. Εάν η συνάρτησηέχειοριστείναεπιστρέφειέναβασικότύπο,τότεηχρήσητηςστηθέσηπίνακα παράγειέναμονόστηλοπίνακα.εάνησυνάρτησηέχειοριστείναεπιστρέφειένασύνθετο τύπο, τότε η χρήση της στη θέση πίνακα παράγει μια στήλη για κάθε χαρακτηριστικό του σύνθετουτύπου. Στοακόλουθοπαράδειγμαδημιουργούμετονπίνακαfooκαιεισάγουμετρειςεγγραφές: CREATE TABLE Atable (id int, subid int, name varchar(10));
INSERT INTO Atable VALUES (1, 1, 'Joe'); INSERT INTO Atable VALUES (1, 2, 'Ed'); INSERT INTO Atable VALUES (2, 1, 'Mary'); Δημιουργούμετηνσυνάρτηση: CREATE FUNCTION geta(int) RETURNS Atable AS $$ SELECT * FROM Atable WHERE id = $1; καιτηνκαλούμεμεπαράμετροτηντιμή1: SELECT * FROM geta(1) AS t1; Ανκαιτοαποτέλεσματηςθαέπρεπεναείναιδύογραμμέςμαςεπιστρέφειμόνομία.Γιανα μπορέσουμε να πάρουμε όλα τα αποτελέσματα θα πρέπει να χρησιμοποιήσουμε τον τελεστήsetofστοreturnsτμήματηςδήλωσηςτηςσυνάρτησης.ότανμιαsqlσυνάρτηση έχειδηλωθείναεπιστρέφειsetofκάποιουτύπου,ητελικήεντολήselectτηςσυνάρτησης εκτελείται μέχρι τέλους, και κάθε γραμμή που παράγει επιστρέφεται ως ένα στοιχείο του συνόλου αποτελεσμάτων. Αυτό το χαρακτηριστικό χρησιμοποιείται κανονικά όταν η συνάρτησηκαλείταικαιστοτμήμαfrom. Τροποποίησητουπροηγούμενουπαραδείγματοςγιαναπάρουμεόλατααποτελέσματα. CREATE FUNCTION getb(int) RETURNS SETOF Atable AS $$ SELECT * FROM Atable WHERE id = $1; SELECT * FROM getb(1) AS t1; plpgsqlδιαδικασίες Μεχρήσητηςγλώσσαςplpgsqlέχουμεστηδιάθεσημαςόλαταπρογραμματιστικάεργαλεία πουέχουμεσεμίαγλώσσαπρογραμματισμού. Δήλωσημεταβλητών: ΓιαναδηλώσουμεμίαμεταβλητήχρησιμοποιούμετηνεντολήDECLARE. DECLARE metablitia integer; DECLARE metablitib integer := 1;
IF THEN ELSE: Για να χρησιμοποιήσουμε την εντολή IF THEN ELSE στην plpgsql θα πρέπει να ακολουθήσουμετηνπαρακάτωσύνταξη: IF boolean-expression THEN ELSIF boolean-expression THEN ELSIF boolean-expression THEN... ELSE END IF; CASE: ΓιαναχρησιμοποιήσουμετηνεντολήCASEστηνplpgsqlθαπρέπειναακολουθήσουμετην παρακάτωσύνταξη: CASE search-expression WHEN expression [, expression [... ]] THEN [ WHEN expression [, expression [... ]] THEN... ] [ ELSE ] END CASE; FOR LOOP: Για να χρησιμοποιήσουμε την εντολή FOR στην plpgsql θα πρέπει να ακολουθήσουμε την παρακάτωσύνταξη: [ <<label>> ] FOR name IN [ REVERSE ] expression.. expression [ BY expression ] LOOP END LOOP [ label ]; WHILE LOOP: ΓιαναχρησιμοποιήσουμετηνεντολήWHILEστηνplpgsqlθαπρέπειναακολουθήσουμετην παρακάτωσύνταξη:
[ <<label>> ] WHILE boolean-expression LOOP END LOOP [ label ]; Περισσότεραμπορείτεναβρείτεστο http://www.postgresql.org/docs/9.1/static/plpgsql.html