ΚΕΡΑΜΟΠΟΥΛΟΣ ΕΥΚΛΕΙΔΗΣ
Είναι τμήματα προγράμματος Βάσης Δεδομένων (διαδικασίες\procedures ή συναρτήσεις\functions) που αποθηκεύονται μόνιμα και εκτελούνται στον διακομιστή της Βάσης Δεδομένων. Δρ. Κεραμόπουλος Ευκλείδης 2
Οι αποθηκευμένες διαδικασίες είναι προγράμματα τα οποία έχουν τα παρακάτω χαρακτηριστικά: Αποθηκεύονται και τρέχουν στον διακομιστή της Βάσης. Καλούνται με το όνομα τους από οποιαδήποτε εφαρμογή συνδεθεί με τη Βάση. Η εφαρμογή μπορεί να χωριστεί σε δύο μέρη: Η εφαρμογή τρέχει στον πελάτη Η αποθηκευμένη διαδικασία στον διακομιστή. Περιέχει προγραμματιστικές εντολές (if, loops) αλλά ταυτόχρονα μπορεί να χειριστεί SQL κώδικα. Δρ. Κεραμόπουλος Ευκλείδης 3
Οι αποθηκευμένες διαδικασίες μπορούν να έχουν την παρακάτω χρήση: Για έλεγχο πολύπλοκων περιορισμών. Για απόκρυψη του κώδικα της διαδικασίας. Για δημιουργία βιβλιοθήκης έτοιμων συναρτήσεων στον διακομιστή. Για δημιουργία Data Web Services με βάση τις αποθηκευμένες διαδικασίες. Δρ. Κεραμόπουλος Ευκλείδης 4
Βελτιώνουν την ασφάλεια του DBMS. Υποστηρίζουν το «κρύψιμο» (encapsulation) του κώδικα τους, και με σωστό σχεδιασμό και συστηματική χρήση τους είναι δυνατόν να εξαφανιστεί η δομή της βάσης από τους χρήστες. Δρ. Κεραμόπουλος Ευκλείδης 5
Βελτιώνει την ταχύτητα απόκρισης του εξυπηρετητή της Βάσης. Αυτό οφείλεται στο ότι είναι προμεταγλωττισμένες (precompiled) και έτσι εκτελούνται γρηγορότερα. Δρ. Κεραμόπουλος Ευκλείδης 6
Επίσης, αντικαθιστώντας ένα σύνολο SQL εντολών με την κλήση μιας συνάρτησης που περιέχει όλες αυτές τις SQL εντολές, «ελαφρύνει» την κίνηση στο δίκτυο μεταξύ πελάτη και διακομιστή. Για παράδειγμα, αν η συνάρτηση περιέχει 10 SQL εντολές τότε αν εκτελέσουμε ξεχωριστά κάθε SQL εντολή στον πελάτη θα έχουμε 10 κλήσεις της βάσης στον εξυπηρετητή ενώ αν όλες οι SQL εντολές έχουν οργανωθεί σε μία καταχωρημένη διεργασία τότε θα απαιτείται μία κλήση της βάσης στον εξυπηρετητή. Δρ. Κεραμόπουλος Ευκλείδης 7
Ο τρόπος υλοποίησης μιας αποθηκευμένης διαδικασίας μπορεί να διαφέρει από ΣΔΒΔ σε ΣΔΒΔ. Μία αποθηκευμένη διαδικασία μπορεί να υλοποιηθεί εσωτερικά στο ΣΔΒΔ με χρήση SQL εντολών και ονομάζεται SQL Stored procedure εξωτερικά σε μία γλώσσα προγραμματισμού. Δρ. Κεραμόπουλος Ευκλείδης 8
Οι SQL συναρτήσεις εκτελούν μία λίστα από SQL εντολές. Στην απλή περίπτωση επιστρέφουν την πρώτη γραμμή (εγγραφή) του αποτελέσματος της τελευταίας εντολής. Υπάρχει η δυνατότητα να επιστρέψουν και μία συλλογή από γραμμές του αποτελέσματος. Αν η τελευταία εντολή δεν επιστρέφει καθόλου εγγραφές επιστρέφεται η τιμή void. Το σώμα μιας SQL συνάρτησης πρέπει να είναι μια λίστα μιας ή περισσότερων εντολών SQL, χωρισμένων με ερωτηματικό (;). Δρ. Κεραμόπουλος Ευκλείδης 9
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); $$ LANGUAGE SQL; Δρ. Κεραμόπουλος Ευκλείδης 11
Η κλήση μίας συνάρτησης γίνεται ως SELECT αίτημα με κλήση της συνάρτησης. Παράδειγμα SELECT CREATEDB(); Δρ. Κεραμόπουλος Ευκλείδης 12
create function dropdb() returns void AS $$ drop table Reserves; drop table Sailors; drop table Boats; $$ LANGUAGE SQL; SELECT dropdb(); Δρ. Κεραμόπουλος Ευκλείδης 13
create function insertdb() returns void AS $$ insert into Sailors (sid, sname, rating, age) values (22, 'Dustin', 7, 45.0); insert into Sailors (sid, sname, rating, age) values (29, 'Brutus', 1, 33.0); insert into Sailors (sid, sname, rating, age) values (31, 'Lubber', 8, 55.5); insert into Sailors (sid, sname, rating, age) values (32, 'Andy', 8, 25.5); insert into Sailors (sid, sname, rating, age) values (58, 'Rusty', 10, 35.0); insert into Sailors (sid, sname, rating, age) values (64, 'Horatio', 7, 35.0); insert into Sailors (sid, sname, rating, age) values (71, 'Zorba', 10, 16.0); insert into Sailors (sid, sname, rating, age) values (74, 'Horatio', 9, 40.0); insert into Sailors (sid, sname, rating, age) values (85, 'Art', 3, 25.5); insert into Sailors (sid, sname, rating, age) values (95, 'Bob', 3, 63.5); insert into Boats (bid, bname, color) values (101, 'Interlake', 'blue'); insert into Boats (bid, bname, color) values (102, 'Interlake', 'red'); insert into Boats (bid, bname, color) values (103, 'Clipper', 'green'); insert into Boats (bid, bname, color) values (104, 'Marine', 'red ); Δρ. Κεραμόπουλος Ευκλείδης 14
insert into Reserves (sid, bid, day1) values (22, 101, date '1998-10-10'); insert into Reserves (sid, bid, day1) values (22, 102, date '1998-10-10'); insert into Reserves (sid, bid, day1) values (22, 103, '10-8-1998'); insert into Reserves (sid, bid, day1) values (22, 104, date '1998-7-10'); insert into Reserves (sid, bid, day1) values (31, 102, date '1998-10-11'); insert into Reserves (sid, bid, day1) values (31, 103, date '1998-6-11'); insert into Reserves (sid, bid, day1) values (31, 104, date '1998-12-11'); insert into Reserves (sid, bid, day1) values (64, 101, date '1998-5-9'); insert into Reserves (sid, bid, day1) values (64, 102, date '1998-8-9'); insert into Reserves (sid, bid, day1) values (74, 103, date '1998-8-9'); $$ LANGUAGE SQL; SELECT insertdb(); Δρ. Κεραμόπουλος Ευκλείδης 15
Επιστρέφουν ένα απλό βασικό τύπο. π.χ. ακέραιο, αλφαριθμητικό, κτλ. CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$ SELECT $1 + $2; $$ LANGUAGE SQL; SELECT add_em(1, 2) AS answer; Η στήλη του αποτελέσματος θα έχει όνομα answer. Αν παραληφθεί το AS answer τότε το όνομα του αποτελέσματος θα είναι το όνομα της συνάρτησης. Δρ. Κεραμόπουλος Ευκλείδης 16
Ένα σύνολο διαφορετικών τύπων SQL εντολών μπορεί να ομαδοποιηθεί σε μία συνάρτηση. Εκτός από SELECT εντολές μπορούν να συμπεριληφθούν και οι INSERT, UPDATE και DELETE. Η τελευταία εντολή, όμως, θα πρέπει να είναι μία SELECT της οποίας το αποτέλεσμά της θα είναι και η επιστρεφόμενη τιμή της συνάρτηση. Αν πάλι, δε θέλουμε να μας επιστραφεί καμία τιμή τότε θα βάλουμε σαν επιστρεφόμενο τύπο της συνάρτηση το void. Σε αυτή την περίπτωση η τελευταία εντολή δε θα πρέπει να είναι SELECT. Δρ. Κεραμόπουλος Ευκλείδης 17
2 ο Παράδειγμα CREATE FUNCTION tf1 (integer, numeric) RETURNS numeric AS $$ UPDATE bank SET balance = balance - $2 WHERE accountno = $1; SELECT balance FROM bank WHERE accountno = $1; $$ LANGUAGE SQL; SELECT tf1(17, 100.0); Δρ. Κεραμόπουλος Ευκλείδης 18
CREATE FUNCTION clean_emp() RETURNS void AS $$ DELETE FROM emp WHERE salary <= 0; $$ LANGUAGE SQL; Αφού καλέσουμε την συνάρτηση clean_emp() δεν θα επιστραφεί αποτέλεσμα. Δρ. Κεραμόπουλος Ευκλείδης 19
Όταν ορίζουμε συναρτήσεις με παραμέτρους σύνθετων τύπων, πρέπει να προσδιορίσουμε όχι μόνο ποια παράμετρο θέλουμε (όπως κάναμε με τα $1 και $2) αλλά και τα πεδία αυτής της παραμέτρου. Δρ. Κεραμόπουλος Ευκλείδης 20
Στο ακόλουθο παράδειγμα ο emp είναι ένας πίνακας υπαλλήλων. Ως εκ τούτου, είναι και το όνομα του σύνθετου τύπου κάθε γραμμής του πίνακα. Η συνάρτηση double_salary υπολογίζει το διπλάσιο του μισθού κάποιου υπαλλήλου: Δρ. Κεραμόπουλος Ευκλείδης 21
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; $$ LANGUAGE SQL; Δρ. Κεραμόπουλος Ευκλείδης 22
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'; Δρ. Κεραμόπουλος Ευκλείδης 23
Όλες οι SQL συναρτήσεις μπορούν να χρησιμοποιηθούν στο τμήμα FROM ενός query. Αυτό είναι ιδιαίτερα χρήσιμο για συναρτήσεις που επιστρέφουν σύνθετους τύπους. Εάν η συνάρτηση έχει οριστεί να επιστρέφει ένα βασικό τύπο, τότε η χρήση της στη θέση πίνακα παράγει ένα μονόστηλο πίνακα. Εάν η συνάρτηση έχει οριστεί να επιστρέφει ένα σύνθετο τύπο, τότε η χρήση της στη θέση πίνακα παράγει μια στήλη για κάθε χαρακτηριστικό του σύνθετου τύπου. Δρ. Κεραμόπουλος Ευκλείδης 24
Π.χ. Δημιουργούμε τον πίνακα Atable και εισάγουμε τρεις εγγραφές: 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 OR REPLACE FUNCTION geta(int) RETURNS Atable AS $$ SELECT * FROM Atable WHERE id = $1; $$ LANGUAGE SQL; Δρ. Κεραμόπουλος Ευκλείδης 25
και την καλούμε με παράμετρο την τιμή 1: SELECT * FROM geta(1) AS t1; Δρ. Κεραμόπουλος Ευκλείδης 26
Όταν μια SQL συνάρτηση έχει δηλωθεί να επιστρέφει SETOF κάποιου τύπου, η τελική εντολή SELECT της συνάρτησης εκτελείται μέχρι τέλους, και κάθε γραμμή που παράγει επιστρέφεται ως ένα στοιχείο του συνόλου αποτελεσμάτων. Αυτό το χαρακτηριστικό χρησιμοποιείται κανονικά όταν η συνάρτηση καλείται στο τμήμα FROM Δρ. Κεραμόπουλος Ευκλείδης 27
CREATE OR REPLACE FUNCTION getb(int) RETURNS SETOF Atable AS $$ SELECT * FROM Atable WHERE id = $1; $$ LANGUAGE SQL; SELECT * FROM getb(1) AS t1; Δρ. Κεραμόπουλος Ευκλείδης 28
Η δήλωση της περιέχει κώδικα SQL και αποτελείται από τα παρακάτω: Το όνομα της αποθηκευμένης διαδικασίας Τις παραμέτρους που θα πάρει Τον τύπο κάθε παραμέτρου Το είδος της παραμέτρου (IN, OUT, INOUT) Τη γλώσσα στην οποία είναι γραμμένη, π.χ. SQL Δρ. Κεραμόπουλος Ευκλείδης 30
CREATE PROCEDURE ΟΝΟΜΑ ( IN ΠΑΡΑΜΕΤΡΟΣ ΤΥΠΟΣ, OUT ΠΑΡΑΜΕΤΡΟΣ ΤΥΠΟΣ, INOUT ΠΑΡΑΜΕΤΡΟΣ ΤΥΠΟΣ ) LANGUAGE SQL BEGIN -- END (ΣΥΜΒΟΛΟ ΤΕΛΟΥΣ) Δρ. Κεραμόπουλος Ευκλείδης 31
Δρ. Κεραμόπουλος Ευκλείδης 32
Μέσα στο σώμα μίας διαδικασίας μπορούν να περιέχονται τα παρακάτω: Δηλώσεις DECLARE <variable> DECLARE <condition> DECLARE <condition handler> DECLARE CURSOR SET Υποθετικές φράσεις CASE IF Βρόγχοι FOR REPEAT WHILE Εντολές Μεταφοράς CALL GOTO LEAVE RETURN Χειρισμός Λαθών SIGNAL Δρ. Κεραμόπουλος Ευκλείδης 33
Με αυτήν την εντολή δηλώνουμε μεταβλητές. Σύνταξη: DECLARE <variable-name> <datatype> [DEFAULT <value>]; Η δήλωση των μεταβλητών είναι τοπική. Οι μεταβλητές δεν είναι case sensitive γιατί μετατρέπονται σε κεφαλαία τα γράμματα τους Πρέπει να δηλωθούν πριν χρησιμοποιηθούν. Μπορεί να δηλωθεί μία default τιμή. Για να μεταβληθεί η τιμή μια μεταβλητής μετά τη δήλωση πρέπει να χρησιμοποιηθεί η εντολή SET. Δρ. Κεραμόπουλος Ευκλείδης 34
Με αυτήν την εντολή δηλώνουμε handlers τα οποία χρησιμοποιούμε για να χειριζόμαστε ειδικά μπλοκ εντολών. Δήλωση: DECLARE CONTINUE EXIT UNDO HANDLER FOR <condition> <SQL PL statement or block>; Τρεις τύποι handler υποστηρίζονται: EXIT, συνεχίζει την εκτέλεση των εντολών από την επόμενη εντολή από το σημείο που δηλώθηκε το handler CONTINUE, συνεχίζει την εκτέλεση των εντολών από την επόμενη εντολή από το σημείο που βρέθηκε το exception UNDO, συνεχίζει την εκτέλεση των εντολών από την επόμενη εντολή από το σημείο που δηλώθηκε το handler και ακυρώνει τις εντολές που εκτελέστηκαν μέσα στο handler. Δρ. Κεραμόπουλος Ευκλείδης 35
Με την declare condition προγραμματίζουμε τι θα γίνει όταν συμβεί μία συνθήκη. π.χ Δήλωση: 1) a condition handler: DECLARE CONTINUE EXIT UNDO HANDLER FOR SQLSTATE '<state>'... 2) a named condition: DECLARE <condition-name> CONDITION FOR SQLSTATE [VALUE] '<sqlstate>'; DECLARE CONTINUE HANDLER FOR NOT FOUND set cursor_end = 1; Τρεις τύποι condition handler υποστηρίζονται: 1. SQLEXCEPTION 2. SQLWARNING 3. NOT FOUND Δρ. Κεραμόπουλος Ευκλείδης 36
Χρησιμοποιείται για τη δήλωση ενός cursor. Δήλωση: DECLARE <cursorname> CURSOR [WITH HOLD] [WITH RETURN TO CALLER CLIENT] FOR <sql-statement>; WITH HOLD: O cursor κλείνει μετά από ένα commit. WITHOUT HOLD: O cursor δεν κλείνει μετά από ένα commit. Είναι το default. TO CALLER: Ο cursor επιστρέφει ένα result set στην procedure ή στο πρόγραμμα που κάλεσε τη διαδικασία. Είναι το default. TO CLIENT: Ο cursor επιστρέφει ένα result set μόνο σε πρόγραμμα client που κάλεσε τη διαδικασία. Δρ. Κεραμόπουλος Ευκλείδης 37
Με τη χρήση του SET παίρνουν τιμές οι μεταβλητές. Παραδείγματα: set v_string = NULL; set v_string = 'ABCDEF'; set v_date = current date; set v_var01 = v_var01 + 1; set v_var02 = v_var01 + 10; set (v_col1, v_col2) = (select col1, col2 from mytab fetch first 1 rows only); Αν δεν ζητήσουμε μόνο μία γραμμή να επιστρέψει θα δώσει λάθος. set v_var02 = (select count(*) from mytab); Δρ. Κεραμόπουλος Ευκλείδης 38
Η εντολή CASE χρησιμοποιείται ως μία υποθετική φράση όπου όταν ικανοποιηθεί εκτελείται η αντίστοιχη εντολή. Υπάρχουν δύο τύποι CASE: O απλός, ο οποίος στηρίζεται σε μία απλή τιμή (literal) O σύνθετος, ο οποίος στηρίζεται σε μία έκφραση (expression) Μετά το WHEN που ικανοποιεί την CASE ακολουθεί η εκτελέσιμη φράση Δρ. Κεραμόπουλος Ευκλείδης 39
1. CREATE PROCEDURE UPDATE_DEPT (IN p_workdept) 2. LANGUAGE SQL 3. BEGIN 4. DECLARE v_workdept CHAR(3); 5. SET v_workdept = p_workdept; 6. CASE v_workdept 7. WHEN 'A00' THEN 8. UPDATE department SET deptname = 'D1'; 9. WHEN 'B01' THEN 10. UPDATE department SET deptname = 'D2'; 11. ELSE 12. UPDATE department SET deptname = 'D3'; 13. END CASE 14. END Δρ. Κεραμόπουλος Ευκλείδης 40
1. CREATE PROCEDURE UPDATE_DEPT (IN p_workdept) 2. LANGUAGE SQL 3. BEGIN 4. DECLARE v_workdept CHAR(3); 5. SET v_workdept = p_workdept; 6. CASE 7. WHEN v_workdept = 'A00' THEN 8. UPDATE department SET deptname = 'D1'; 9. WHEN v_workdept = 'B01' THEN 10. UPDATE department SET deptname = 'D2'; 11. ELSE 12. UPDATE department SET deptname = 'D3'; 13. END CASE 14. END Δρ. Κεραμόπουλος Ευκλείδης 41
1. CREATE PROCEDURE UPDATE_SAL (IN empnum CHAR(6), IN rating SMALLINT) 2. LANGUAGE SQL 3. BEGIN 4. IF rating = 1 THEN 5. UPDATE employee SET salary = salary * 1.10, bonus = 1000 WHERE empno = empnum; 6. ELSEIF rating = 2 THEN 7. UPDATE employee SET salary = salary * 1.05, bonus = 500 WHERE empno = empnum; 8. ELSE 9. UPDATE employee SET salary = salary * 1.03, bonus = 0 WHERE empno = empnum; 10. END IF; 11. END Δρ. Κεραμόπουλος Ευκλείδης 42
O FOR βρόγχος χρησιμοποιείται ως ένας read-only cursor. O cursor που δηλώνεται εντός ενός FOR βρόγχου δεν μπορεί να χρησιμοποιηθεί εκτός του βρόγχου. Επίσης, χρησιμοποιούνται οι εκφράσεις OPEN, FETCH, ή CLOSE μ αυτό το είδος του cursor. Δήλωση: for <loop-name> as [<cursor-name>] cursor for <select-statement> do <inside-loop-logic> end for; Παράδειγμα: create procedure myproc begin FOR each_record AS cursor1 CURSOR FOR SELECT name, rating FROM customer DO UPDATE customer SET rating = rating * 1.1 WHERE CURRENT OF cursor1; END FOR; end! Με την φράση CURRENT OF cursor έχουμε πρόσβαση στην τρέχουσα εγγραφή Δρ. Κεραμόπουλος Ευκλείδης 43
REPEAT εντολες UNTIL (συνθήκη) END REPEAT Δήλωση Μεταβλητών CREATE PROCEDURE DEL_DEPT (IN deldept VARCHAR(3)) LANGUAGE SQL BEGIN DECLARE cursor_end integer default 0; DECLARE currentdept CHAR(3); Δήλωση CURSOR DECLARE mycur CURSOR FOR select DEPTNO as v_dept from DEPARTMENT where deptno = deldept; DECLARE CONTINUE HANDLER FOR NOT FOUND set cursor_end = 1; OPEN mycur; REPEAT FETCH FROM mycur INTO currentdept; delete from EMPLOYEE where workdept = currentdept; UNTIL cursor_end = 1 END REPEAT; CLOSE mycur; delete from DEPARTMENT where deptno = deldept; END! Δρ. Κεραμόπουλος Ευκλείδης 44
WHILE (συνθήκη) D0 εντολες END WHILE CREATE PROCEDURE DEL_DEPT (IN deldept VARCHAR(3)) LANGUAGE SQL BEGIN DECLARE currentdept CHAR(3); DECLARE SQLCODE INTEGER DEFAULT 0; DECLARE mycur CURSOR FOR select DEPTNO as v_dept from DEPARTMENT where deptno = deldept; OPEN mycur; FETCH FROM mycur INTO currentdept; WHILE (SQLCODE = 0) DO delete from EMPLOYEE where workdept = currentdept; fetch from mycur into currentdept; END WHILE; CLOSE mycur; delete from DEPARTMENT where deptno = deldept; END! Δρ. Κεραμόπουλος Ευκλείδης 45
Για να καλέσουμε μία διαδικασία χρησιμοποιούμε την εντολή CALL Υποστηρίζεται η αναδρομή στη κλήση διαδικασιών. Θα πρέπει όμως να είμαστε προσεκτικοί στο κλείσιμο των δρομέων. Κατά την κλήση όλες οι παράμετροι θα πρέπει να πάρουν τιμές. Οι OUT παράμετροι παίρνουν?. Παράδειγμα: CALL myproc ( <inputvalue1>, <inputvalue2>,?,? ); Δρ. Κεραμόπουλος Ευκλείδης 46
GOTO: Με αυτήν την εντολή μετακινούμαστε σε συγκεκριμένη ετικέτα. LEAVE: Με αυτήν την εντολή μπορούμε να βγούμε από ένα βρόγχο. RETURN: Με αυτήν την εντολή μπορούμε να επιστρέψουμε από μία αποθηκευμένη διαδικασία. Δρ. Κεραμόπουλος Ευκλείδης 47
SIGNAL: Αν δημιουργηθεί ένα λάθος τότε αυτόματα δημιουργείται ένα μήνυμα λάθους. Με την εντολή SIGNAL μπορούμε να ορίσουμε εμείς ένα λάθος. Δήλωση: SIGNAL SQLSTATE <sqlstate> [SET MESSAGE_TEXT '<text>' ] Παράδειγμα: create procedure myproc (in v_var01 integer) begin if v_var01 > 100 then signal SQLSTATE '70000' set message_text='the input parameter must be lower than 100!'; end if; end! Κλήση της συνάρτησης: call myproc(200); SQL0438N Application raised error with diagnostic text: "The input parameter must be lower than 100!". SQLSTATE=70000 Δρ. Κεραμόπουλος Ευκλείδης 48
Δρ. Κεραμόπουλος Ευκλείδης 49
Δρ. Κεραμόπουλος Ευκλείδης 50
1. CREATE PROCEDURE CREATE_OLYMPICS () 2. LANGUAGE SQL 3. BEGIN 4. CREATE TABLE VOLUNTEER ( 5. at char(10) not null primary key, 6. name char(20), 7. surname char(30), 8. gender char(6), 9. age integer); 10. CREATE TABLE STADIUM ( 11. name char(30) not null primary key, 12. capacity integer, 13. city char(20)); 14. CREATE TABLE JUDGE ( 15. code integer not null primary key, 16. name char(20), 17. surname char(30), 18. gender char(6), 19. date_of_birth date); Δρ. Κεραμόπουλος Ευκλείδης 51
20. CREATE TABLE TRAINER ( 21. code integer not null primary key, 22. name char(20), 23. surname char(30), 24. country_of_origin char(20)); 25. CREATE TABLE SPORT ( 26. code integer not null primary key, 27. name char(50), 28. gender char(6), 29. record float, 30. record_date date, 31. recordman_surname char(30), 32. recordman_name char(20)); 33. CREATE TABLE ATHLETE ( 34. code integer not null primary key, 35. name char(50), 36. surname char(30), 37. gender char(6), 38. date_of_birth date, 39. weight float, 40. height integer, 41. country_of_origin char(20), 42. country_of_participation char(20), 43. trainer_code integer, 44. foreign key(trainer_code) references TRAINER(code)); Δρ. Κεραμόπουλος Ευκλείδης 52
45. CREATE TABLE GAMES ( 46. code integer not null primary key, 47. level char(20), 48. gdate date, 49. gtime time, 50. stadium char(30) not null references STADIUM(name), 51. sport integer not null references SPORT(code), 52. judge integer not null references JUDGE(code)); 53. CREATE TABLE HELPS ( 54. game integer not null references GAMES(code), 55. volunteer char(10) not null references VOLUNTEER(at), 56. primary key(game, volunteer)); 57. CREATE TABLE PARTICIPATES ( 58. game integer not null references GAMES(code), 59. athlete integer not null references ATHLETE(code), 60. primary key(game, athlete), 61. performance float, 62. cancellation char); 63. END@ CALL CREATE_OLYMPICS() Δρ. Κεραμόπουλος Ευκλείδης 53
1. CREATE PROCEDURE DROP_OLYMPICS() 2. LANGUAGE SQL 3. BEGIN 4. drop TABLE PARTICIPATES; 5. drop TABLE HELPS; 6. drop TABLE GAMES; 7. drop TABLE ATHLETE; 8. drop TABLE SPORT; 9. drop TABLE TRAINER; 10. drop TABLE JUDGE; 11. drop TABLE STADIUM; 12. drop TABLE VOLUNTEER; 13. END@ 14. CALL DROP_OLYMPICS() 15. DROP PROCEDURE DROP_OLYMPIC() Δρ. Κεραμόπουλος Ευκλείδης 54
1. CREATE PROCEDURE INSERT_OLYMPICS (IN tablename CHAR(20)) 2. LANGUAGE SQL 3. BEGIN 4. CASE 5. when tablename = 'PARTICIPATES' THEN 6. INSERT INTO PARTICIPATES (game, athlete, performance, cancellation) VALUES (4, 39, 83.14, 'Q'); 7. INSERT INTO PARTICIPATES (game, athlete, performance, cancellation) VALUES (4, 40, 83.01, 'Q'); 8. WHEN tablename = 'HELPS' THEN 9. INSERT INTO HELPS (game, volunteer) VALUES (1, 'M100902'); 10. INSERT INTO HELPS (game, volunteer) VALUES (2, 'O212754'); 11. INSERT INTO HELPS (game, volunteer) VALUES (3, 'K256984'); 12. WHEN tablename = 'ATHLETE' THEN 13. INSERT INTO ATHLETE (code, name, surname, gender, date_of_birth, weight, height, country_of_origin, country_of_participation) VALUES (1, 'Aziz', 'Zakari', 'Male', '2/9/1976', 85, 175, 'Ghana', 'Ghana'); 14. INSERT INTO ATHLETE (code, name, surname, gender, date_of_birth, weight, height, country_of_origin, country_of_participation) VALUES (2, 'Kim', 'Collins', 'Male', '5/4/1976', 77, 180, 'SKN', 'SKN'); 15. INSERT INTO ATHLETE (code, name, surname, gender, date_of_birth, weight, height, country_of_origin, country_of_participation) VALUES (3, 'Michael', 'Frater', 'Male', '6/10/1982', 73, 175, 'Jamaica', 'Jamaica'); 16. INSERT INTO ATHLETE (code, name, surname, gender, date_of_birth, weight, height, country_of_origin, country_of_participation) VALUES (4, 'Frank', 'Fredericks', 'Male', '2/10/1967', 75, 180, 'Namibia', 'Namibia'); 17. END CASE; 18. END@ call insert_olympics('athlete') Δρ. Κεραμόπουλος Ευκλείδης 55
1. CREATE PROCEDURE ATHLETE_EAT_A_LOT (in prsurname varchar(20)) 2. LANGUAGE SQL 3. BEGIN 4. DECLARE proc_name CHAR(50); 5. DECLARE proc_surname CHAR(30); 6. DECLARE at_end INT DEFAULT 0; 7. DECLARE not_found CONDITION FOR '02000'; 8. DECLARE c1 CURSOR FOR 9. SELECT name, surname 10. FROM athlete 11. where surname = prsurname 12. FOR UPDATE; 13. DECLARE CONTINUE HANDLER FOR not_found 14. SET at_end = 1; 15. 16. OPEN c1; 17. FETCH c1 INTO proc_name, proc_surname; 18. WHILE at_end = 0 DO 19. UPDATE ATHLETE 20. SET WEIGHT = WEIGHT + 10 21. WHERE CURRENT OF c1; 22. FETCH c1 INTO proc_name, proc_surname; 23. END WHILE; 24. CLOSE c1; 25. END@ call ATHLETE_EAT_A_LOT('Zakari') Δρ. Κεραμόπουλος Ευκλείδης 56
1. import java.sql.*; 2. public class Jdbc_dblab2_call_SP_db2 { 3. static String driverclassname = "com.ibm.db2.jcc.db2driver" ; 4. static String url = "jdbc:db2://localhost:50000/sqwctrl" ; 5. static String username = euclid"; 6. static String passwd = euclid"; 7. static Connection dbconnection = null; 8. static CallableStatement call_statement = null; 9. public static void main (String[] argv) throws Exception 10. { 11. Class.forName (driverclassname); 12. dbconnection = DriverManager.getConnection (url, username, passwd); 13. 14. String DROPOLYMPICS = "call DROP_OLYMPICS () "; 15. call_statement = dbconnection.preparecall(dropolympics); 16. call_statement.execute(); 17. 18. String CREATEOLYMPICS = " call CREATE_OLYMPICS () "; 19. call_statement = dbconnection.preparecall(createolympics); 20. call_statement.execute(); 21. call_statement.close(); 22. dbconnection.close(); 23. } 24. } Δρ. Κεραμόπουλος Ευκλείδης 57
1. import java.sql.*; 2. public class Jdbc_dblab2_call_SP_db2 { 3. static String driverclassname = "com.ibm.db2.jcc.db2driver" ; 4. static String url = "jdbc:db2://localhost:50000/sqwctrl" ; 5. static String username = euclid"; 6. static String passwd = euclid"; 7. static Connection dbconnection = null; 8. static CallableStatement call_statement = null; 9. public static void main (String[] argv) throws Exception 10. { 11. Class.forName (driverclassname); 12. dbconnection = DriverManager.getConnection (url, username, passwd); 13. 14. String DROPOLYMPICS = "call DROP_OLYMPICS () "; 15. call_statement = dbconnection.preparecall(dropolympics); 16. call_statement.execute(); 17. 18. String CREATEOLYMPICS = " call CREATE_OLYMPICS () "; 19. call_statement = dbconnection.preparecall(createolympics); 20. call_statement.execute(); 21. call_statement.close(); 22. dbconnection.close(); 23. } 24. } Δρ. Κεραμόπουλος Ευκλείδης 58
Δρ. Κεραμόπουλος Ευκλείδης 59
import java.sql.*; import java.io.*; class Jdbc_call_stored_procedure_db2 { static String driverclassname = "com.ibm.db2.jcc.db2driver" ; static String url = "jdbc:db2://localhost:50000/sqwctrl" ; static Connection dbconnection = null; static CallableStatement call_statement = null; public static void main (String[] argv) throws Exception { Class.forName (driverclassname); dbconnection = DriverManager.getConnection (url, "euclid", "euclid"); String sql = "CALL stats(?,?,?)"; call_statement = dbconnection.preparecall(sql); BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); String temp = " ; System.out.print("Enter sailor rating: "); temp = keyboard.readline(); int in1 = Integer.parseInt(temp); } } call_statement.setint(1,in1); call_statement.registeroutparameter(2,types.integer); call_statement.registeroutparameter(3,types.integer); call_statement.execute(); int output1 = call_statement.getint(2); int output2 = call_statement.getint(3); System.out.println("output1: " + output1);system.out.println("output2: " + output2); call_statement.close(); dbconnection.close(); Δρ. Κεραμόπουλος Ευκλείδης 60
public void registeroutparameter(int parameterindex, int sqltype) throws SQLException ενημερώνει ότι η παράμετρος στην θέση parameterindex είναι OUT και sqltype (java type) τύπου Την τιμή την παίρνουμε με τη μέθοδο getxxx(parameterindex) π.χ. getstring(parameterindex) Δρ. Κεραμόπουλος Ευκλείδης 61