Professional Documents
Culture Documents
Βάσεις Δεδομένων Ι Και ΙΙ (Εργαστηριο) Χ. Σκουρλάς, Α. Τσολακίδης ΤΕΙ Αθήνας
Βάσεις Δεδομένων Ι Και ΙΙ (Εργαστηριο) Χ. Σκουρλάς, Α. Τσολακίδης ΤΕΙ Αθήνας
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Εισαγωγή στη χρήση του προϊόντος της Oracle
CREATE TABLE EMP(EMPNO NUMBER(4) NOT NULL, ENAME VARCHAR2(10), JOB VARCHAR2(25),
DEPTNO NUMBER(2));
3
2. Εισαγωγή στη χρήση του προϊόντος mySQL
USE new_personnel;
DEPTNO INT(2));
SHOW TABLES;
4
Δείτε τα στοιχεία των πινάκων της βάσης.
mySQL Oracle
CREATE DATABASE new_personnel;
USE new_personnel;
CREATE TABLE DEPT(DEPTNO INT(2) NOT NULL, CREATE TABLE DEPT(DEPTNO NUMBER(2) NOT NULL,
DNAME VARCHAR(14), LOC VARCHAR(14)); DNAME VARCHAR2(14), LOC VARCHAR2(14));
CREATE TABLE EMP(EMPNO INT(4) NOT NULL, CREATE TABLE EMP(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR(10), JOB VARCHAR(25), ENAME VARCHAR2(10), JOB VARCHAR2(25),
HIREDATE DATE, MGR INT(4), HIREDATE DATE, MGR NUMBER(4),
SAL FLOAT(7,2), COMM FLOAT(7,2), SAL NUMBER(7,2), COMM NUMBER(7,2),
DEPTNO INT(2)); DEPTNO NUMBER(2));
INSERT INTO DEPT(DEPTNO, DNAME, LOC) INSERT INTO DEPT(DEPTNO, DNAME, LOC)
VALUES (10, 'ACCOUNTING', 'NEW YORK'); VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO EMP INSERT INTO EMP
VALUES (10, 'CODD', 'ANALYST', '1989/01/01', 15, 3000, VALUES (10, 'CODD', 'ANALYST', '01/01/1989', 15, 3000,
NULL, 10); NULL, 10);
SELECT * FROM EMP; SELECT * FROM EMP;
SELECT * FROM DEPT; SELECT * FROM DEPT;
DROP TABLE EMP; DROP TABLE EMP;
DROP TABLE DEPT; DROP TABLE DEPT;
DROP DATABASE NEW_PERSONNEL;
SHOW TABLES; SELECT * FROM Tab;
Πίνακας 1. Συγκριτικός πίνακας διαφορών MySQL και Oracle
Άσκηση
Να υλοποιήσετε τη βάση δεδομένων με χρήση του προϊόντος Oracle.
Η εγκατάσταση των προϊόντων μπορεί να γίνει εύκολα από τον ενδιαφερόμενο που θέλει
να δοκιμάσει εντολές SQL για τη διαχείριση σχεσιακών βάσεων δεδομένων. Πιο
συγκεκριμένα, υπάρχουν δύο εναλλακτικές λύσεις:
5
1) Λύση για αρχάριους: Ο ενδιαφερόμενος μπορεί να εγκαταστήσει κάποιο προϊόν
που διατίθεται ελεύθερα. Για παράδειγμα, θα μπορούσε να εγκαταστήσει το
προϊόν MySQL ή το προϊόν Oracle XE ή το προϊόν PostgreSQL. Η εγκατάσταση είναι
μάλλον απλή υπόθεση. Ακολουθούν στοιχεία:
Σε περίπτωση προβλήματος!
6
Στοιχεία για την εγκατάσταση του προϊόντος DBTechNet DebianDB virtual
machine package
Αντιγράφουμε από την ιστοσελίδα:
http://dbtech.uom.gr/mod/resource/view.php?id=824
DBTechNet DebianDB virtual machine package (attention: 4.9 GBytes in its size!)
Download
Quick Start to the DebianDB Database Laboratory (.pdf document written by Martii Laiho))
“DebianDB is a Debian Linux virtual machine providing a portable and free database
laboratory to be used either on classroom courses or as self study tool of students or
individual professionals. It is based on an earlier version developed at University of
Macedonia in Thessaloniki for DBTech EXT project of DBTechNet, and further developed by
Mr. Taito Halonen at Haaga Helia UAS in Helsinki for DBTechNet.
The purpose of this document is to help you in installing the lab and to start using the
database product (s) of your choice in this Linux based database laboratory of your own,
even if you are not too familiar to Linux before.”
- Εκκινούμε το προϊόν σε Command Line Client (ή μέσα από τον Workbench client ή
μέσα από άλλον client που εγκαταστήσατε).
- Πληκτρολογείτε το συνθηματικό σας (αν έχετε δηλώσει συνθηματικό κατά την
εγκατάσταση, βέβαια καλό είναι να δηλώνετε συνθηματικά)
- Είσαστε έτοιμοι να γράψετε τις εντολές σας.
- Αν έχετε γράψει τις εντολές σε κάποιο αρχείο (καλή πρακτική) μπορείτε με copy-
paste (σε “Command Line Client” χρησιμοποιήστε δεξιό click στο ποντίκι για τη
λειτουργία paste) άμεσα να τις εκτελέσετε.
7
- Επίσης, αν έχετε προετοιμάσει κάποιο script εντολών δηλαδή αρχείο κειμένου που
περιλαμβάνει τις εντολές σας και έχει επέκταση .SQL (txt file, extension .SQL),
δηλαδή file_name.SQL, μπορείτε να το εκτελέσετε με την εντολή SOURCE.
mysql> \. file_name
PRESIDENTS
8
LOSERS
LOSER L_PARTY
STEVENSON DEM
NIXON REP
GOLDWATER REP
HUMPHREY DEM
WALLACE IND
McGOVERN DEM
FORD DEM
CARTER DEM
ANDERSON IND
MONDALE DEM
DOUKAKIS DEM
BUSH REP
PERAULT IND
ELECTIONWINNER
9
ELECTIONLOSER
1952 STEVENSON 89
1956 STEVENSON 73
1964 GOLDWATER 52
1968 WALLACE 46
1972 McGOVERN 17
1980 CARTER 49
1980 ANDERSON 0
1984 MONDALE 13
1988 DOUKAKIS 41
l_party VARCHAR2(15));
10
4. Αναζήτησης στοιχείων από τους πίνακες βάσης (script SELECT.SQL).
l_party VARCHAR2(15));
SQL> @CREATE.SQL
11
………
/* τέλος script */
SQL> @INSERT.SQL
Αναζητήσεις (queries)
SELECT winner,w_party,w_state
FROM presidents;
κ.λπ.
SQL> @SELECT.SQL
Διαγραφή πινάκων
/* script διαγραφής πινάκων */
/* τέλος εντολών */
SQL> @DROP.SQL
Άσκηση
Να υλοποιήσετε τη βάση δεδομένων με χρήση του προϊόντος mySQL.
12
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 2: Δημιουργία και διαχείριση βάσης προσωπικού με χρήση του προϊόντος
mySQL
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Case study: Διαχείριση βάσης προσωπικού με χρήση mySQL
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 2002-02-01 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-12-24 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-10-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 2001-05-02 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-11-27 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-29 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1987-11-12 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 2007-10-19 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 2003-05-07 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 2003-12-12 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 2003-12-19 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 2003-01-19 | 1300.00 | NULL | 10 |
| 7999 | BATES | ANALYST | 7566 | 2004-01-04 | 1300.00 | NULL | NULL |
+-------+--------+-----------+------+------------+---------+---------+--------+
USE personnel;
PRIMARY KEY(DEPTNO));
3
ENAME VARCHAR(10), JOB VARCHAR(9),
DEPTNO INT(2),
PRIMARY KEY(EMPNO),
SHOW TABLES;
Εισαγωγή δεδομένων
4
VALUES (7521, 'WARD', 'SALESMAN', 7698, '2002/02/01', 1250, 500, 30);
5
(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
FROM Emp;
FROM Emp;
sal+IFNULL(comm, 0) "σύνολο"
FROM EMP
6
ORDER BY job, ename;
Υπολογίστε μέσο όρο μισθού, ελάχιστο μισθό, μέγιστο μισθό, άθροισμα μισθών,
πόσοι υπάλληλοι έχουν μισθό, πόσοι είναι οι υπάλληλοι.
FROM EMP;
FROM EMP
WHERE job='ANALYST';
FROM EMP
ORDER BY job;
FROM EMP
FROM EMP
7
WHERE job IN ('ANALYST', 'PROGRAMMER')
FROM EMP
Τι δείχνει η αναζήτηση:
FROM EMP
FROM EMP
εντολή UPDATE
UPDATE Emp
SET job='ANALYST'
8
WHERE ename = 'ADAMS';
UPDATE Emp
Εντολή DROP
9
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 3: Δημιουργία μοντέλου για βάση δεδομένων – παράδειγμα μοντέλου για
βάση δεδομένων διαχείρισης προσωπικού
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Δημιουργία Μοντέλου Βάσης Δεδομένων
USE new_personnel;
PRIMARY KEY(DEPTNO));
3
FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO));
SHOW TABLES;
4
1.3 Δημιουργία μοντέλου
Υπόδειξη
5
Χρησιμοποιήστε το προϊόν Workbench για να κατασκευάσετε αρχικά το παρακάτω μοντέλο:
6
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 4: Δημιουργία και διαχείριση βάσης προσωπικού με χρήση απλών και
σύνθετων δηλώσεων (statements) SQL στα προϊόντα mySQL και Oracle. Έμφαση σε
θέματα αναζήτησης (queries)
Χ. Σκουρλάς, Α. Τσολακίδης
Λέξεις Κλειδιά: SQL, mySQL, Oracle, CREATE TABLE, INSERT INTO, SELECT
2
1. Δημιουργία βάσης
Χρήση βάσης
USE new_personnel;
Δημιουργία πινάκων
CREATE TABLE DEPT(DEPTNO INT(2) NOT NULL,
DNAME VARCHAR(14), LOC VARCHAR(14),
PRIMARY KEY(DEPTNO));
CREATE TABLE EMP(EMPNO INT(4) NOT NULL,
3
ENAME VARCHAR(10), JOB VARCHAR(25),
HIREDATE DATE, MGR INT(4), SAL FLOAT(7,2), COMM FLOAT(7,2),
DEPTNO INT(2),
PRIMARY KEY(EMPNO),
FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO));
CREATE TABLE PROJ (projno INT(3) NOT NULL,
pname VARCHAR(15),
budget FLOAT(12,2),
PRIMARY KEY(projno));
CREATE TABLE ASSIGN(
EMPNO INT(4) NOT NULL, PROJNO INT(3) NOT NULL,
PTIME INT(3),
PRIMARY KEY(EMPNO,PROJNO),
FOREIGN KEY(EMPNO) REFERENCES EMP(EMPNO),
FOREIGN KEY(PROJNO) REFERENCES PROJ(PROJNO));
SHOW TABLES;
4
Διαγραφή των πινάκων
DROP TABLE assign;
DROP TABLE emp;
DROP TABLE proj;
DROP TABLE dept;
M CO DEPT
EMPNO ENAME JOB GR HIREDATE SAL MM NO
10 100 40
10 200 60
15 100 100
20 200 100
30 100 100
5
2. Πώς αναζητούμε στοιχεία με τη γλώσσα sql. Σύνταξη της
δήλωσης select. Πρακτικοί κανόνες
Παράδειγμα
Η παρακάτω εντολή δείχνει τα στοιχεία του πίνακα DEPT.
SELECT * FROM dept;
Παράδειγμα
Η παρακάτω εντολή δείχνει τις στήλες DNAME, LOC :
Παράδειγμα
Η παρακάτω εντολή δείχνει τους υπαλλήλους της εταιρείας με το μισθό τους.
SELECT ENAME "ΟΝΟΜΑ ΥΠΑΛΛΗΛΟΥ", SAL "ΜΙΣΘΟΣ"
FROM EMP;
Σε mySQL:
SELECT ENAME , SAL/(25*8) "ΩΡΙΑΙΑ ΑΜΟΙΒΗ",
SAL+IFNULL(COMM,0) "ΣΥΝΟΛΟ ΑΠΟΔΟΧΩΝ"
FROM EMP;
Σημείωση 2: Αν το όνομα που δίνουμε είναι μόνο μια λέξη δεν είναι
απαραίτητο να το γράφουμε σε εισαγωγικά.
6
SELECT ENAME "ΟΝΟΜΑ ΥΠΑΛΛΗΛΟΥ", SAL ΜΙΣΘΟΣ
FROM EMP;
Σε mySQL:
SELECT ENAME "ΟΝΟΜΑ ΥΠΑΛΛΗΛΟΥ", SAL "ΜΙΣΘΟΣ"
FROM EMP;
SELECT empno||ename FROM emp;
Παράδειγμα
Η παρακάτω αναζήτηση προσδιορίζει τα επαγγέλματα των υπαλλήλων
επαναλαμβάνοντας τις τιμές στα αποτελέσματα:
SELECT JOB FROM EMP;
Αντίθετα η αναζήτηση
SELECT DISTINCT JOB FROM EMP;
δεν τις επαναλαμβάνει, δηλαδή, αναγράφει όλα τα επαγγέλματα που
υπάρχουν στο πίνακα EMP και μάλιστα μόνο μία φορά το καθένα.
Παράδειγμα
Παρατηρήστε τη διαφορά και στις επόμενες εντολές:
SELECT job, deptno
from emp;
SELECT DISTINCT job, deptno
from emp;
7
Παράδειγμα
Η παρακάτω αναζήτηση βρίσκει ποια τμήματα έχουν έδρα NEW YORK.
SELECT DNAME "ΟΝΟΜΑ ΤΜΗΜΑΤΟΣ", LOC ΕΔΡΑ
FROM DEPT
WHERE LOC = 'NEW YORK';
MySQL:
SELECT DNAME "ΟΝΟΜΑ ΤΜΗΜΑΤΟΣ", LOC "ΕΔΡΑ"
FROM DEPT
WHERE LOC = 'NEW YORK';
Παράδειγμα Βρες υπαλλήλους με προμήθεια μεγαλύτερη του δέκατου του μισθού τους.
SELECT ENAME,SAL,SAL/10, COMM
FROM EMP
WHERE COMM > SAL/10;
8
Βλέπουμε τη σημερινή ημερομηνία με τη συνάρτηση sysdate
χρησιμοποιώντας τον μονοθέσιο πίνακα dual του συστήματος.
SELECT sysdate FROM dual;
mySQL:
SELECT current_date;
Παράδειγμα
Όπως είδαμε και στα προηγούμενα η παρακάτω αναζήτηση βρίσκει την
ωριαία και τη συνολική αμοιβή υπαλλήλων
SELECT ENAME ΟΝΟΜΑ, SAL/(25*8) "ΩΡΙΑΙΑ ΑΜΟΙΒΗ",
SAL+NVL (COMM,0) "ΣΥΝΟΛΙΚΗ ΑΜΟΙΒΗ"
FROM EMP;
MySQL:
SELECT ENAME "ΟΝΟΜΑ", SAL/(25*8) "ΩΡΙΑΙΑ ΑΜΟΙΒΗ",
SAL+IFNULL(COMM,0) "ΣΥΝΟΛΙΚΗ ΑΜΟΙΒΗ"
FROM EMP;
9
2.7 Πως σχηματίζουμε σύνθετες συνθήκες σε υποπρόταση WHERE.
Τελεστές σύγκρισης, Aριθμητικοί, Boole, LIKE, NOT LIKE,
BETWEEN ...AND, NOT BETWEEN ...AND, σύνολα (ΙΝ).
1) τελεστές σύγκρισης (>, <, >=, <=, != , <>,^ =), όπου οι τρεις
τελευταίοι (ή και άλλοι ανάλογα με το προϊόν) συμβολίζουν το
διάφορο.
2) αριθμητικούς (+, -, /, *),
3) τελεστές Boole (AND, OR, NOT),
4) τελεστή LIKE ή NOT LIKE (π.χ. ENAME NOT LIKE '%ΑΣ'),
5) τελεστές BETWEEN ...AND ή NOT BETWEEN ...AND
(π.χ. SAL BETWEEN 2500 AND 3000)
6) σύνολα τιμών (τελεστής ΙΝ),
(π.χ. JOB IN ('ΠΩΛΗΤΗΣ', 'ΑΝΑΛΥΤΗΣ ΣΥΣΤΗΜΑΤΩΝ')),
7) παρενθέσεις.
mySQL:
SELECT ENAME "ΟΝΟΜΑ", SAL "ΜΙΣΘΟΣ", COMM "ΠΡΟΜΗΘΕΙΑ"
FROM EMP
WHERE JOB = 'SALESMAN'
AND (SAL> 1300) OR (COMM > SAL/10);
10
Παράδειγμα 4: Χρήση συνάρτησης substr
Η αναζήτηση βρίσκει αναλυτές με όνομα που αρχίζει από C, D, E.
SELECT ename, job FROM emp
WHERE (ename > = 'C' AND ename < 'F' )
AND job = 'ANALYST';
mySQL:
SELECT ename, job FROM emp
WHERE (ename >= 'C' AND ename < 'F' )
AND job = 'ANALYST';
Σημείωση
Η χρήση LIKE για την σύγκριση ορμαθών (ή συμβολοσειρών) (strings)
συνδέεται συνήθως με το σύμβολο % όπως φαίνεται στα
παραδείγματα:
mySQL:
select DISTINCT job
from emp
where job like 'A%';
11
Παράδειγμα 5: Χρήση BETWEEN … AND με ημερομηνίες
Η παρακάτω αναζήτηση βρίσκει αυτούς που το επώνυμο τους αρχίζει
από C ή D και προσλήφθηκαν από το 1989 έως και το 1995
SELECT ename, hiredate from emp
where ename between 'C' and 'F'
and hiredate Between '01/01/1989' and '12/31/1995';
mySQL:
SELECT ename, hiredate from emp
where ename between 'C' and 'F'
and hiredate Between '1989/01/01' and '1995/12/31';
Στο Παράδειγμα μπορείτε να χρησιμοποιήσετε και τη συνάρτηση substr.
Παράδειγμα Βρες όνομα,θέση και μισθό των υπαλλήλων του Τμήματος 20 που κερδίζουν
πάνω από 2,000.
SELECT ENAME,JOB,SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10
AND SAL > 2000;
Παράδειγμα Βρες τους πωλητές ή αναλυτές που δεν ανήκουν στο τμήμα 10.
SELECT ENAME, JOB, SAL, DEPTNO
FROM EMP
WHERE (JOB = 'ANALYST' OR JOB = 'SALESMAN')
AND DEPTNO <> 10;
Παράδειγμα Βρες τους πωλητές ή αναλυτές που ανήκουν στο τμήμα 10.
SELECT ENAME, JOB, SAL, DEPTNO
FROM EMP
WHERE (JOB = 'ANALYST' OR JOB = 'SALESMAN')
AND DEPTNO=10;
Παράδειγμα Βρες πωλητές οποιουδήποτε τμήματος και αναλυτές του Τμήματος 10.
SELECT *
FROM EMP
WHERE JOB = 'SALESMAN'
OR (JOB = 'ANALYST' AND DEPTNO = 10);
12
AND DEPTNO = 20;
Παράδειγμα Βρες υπάλληλους της Τμήματος 10 που δεν είναι πωλητές ή αναλυτές.
SELECT *
FROM EMP
WHERE NOT (JOB = 'SALESMAN' OR JOB = 'ANALYST')
AND DEPTNO = 10;
Παράδειγμα Χρησιμοποίησε το τελεστή BETWEEN με τον τελεστή NOT για να βρείς τους
υπόλοιπους υπάλληλους.
SELECT ENAME,JOB,SAL
FROM EMP
WHERE SAL NOT BETWEEN 1500 AND 1800;
Παράδειγμα Βρες υπάλληλους που το όνομα τους τελειώνει σε THE και είναι Πωλητές.
SELECT ENAME,JOB,DEPTNO
FROM EMP
WHERE ENAME LIKE '%THE'
AND JOB = 'SALESMAN';
13
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 5: Υποαναζητήσεις στη γλώσσα SQL στα προϊόντα mySQL και Oracle
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Δημιουργία Βάσης Δεδομένων
3
M
EMP G CO DEPT
NO ENAME JOB R HIREDATE SAL MM NO
10 100 40
10 200 60
15 100 100
20 200 100
30 100 100
4
FROM EMP
WHERE JOB IN (SELECT JOB
FROM EMP
WHERE ENAME='CODD' OR ENAME='ELMASRI')
AND SAL > 1250;
SELECT ENAME,DEPTNO
FROM EMP
WHERE JOB = 'ANALYST'
AND DEPTNO IN
(SELECT DEPTNO
FROM EMP
WHERE JOB = 'PROGRAMMER');
5
SELECT ENAME,DEPTNO
FROM EMP
WHERE JOB = 'ANALYST'
AND DEPTNO NOT IN
(SELECT DEPTNO
FROM EMP
WHERE JOB = 'SALESMAN');
ENAME DEPTNO
ELMASRI 10
CODD 10
SELECT ENAME,JOB,DEPTNO,SAL
FROM EMP
WHERE JOB IN
(SELECT JOB
FROM EMP
WHERE ENAME = 'CODD')
OR SAL >=
(SELECT SAL
FROM EMP
WHERE ENAME = 'DATE')
ORDER BY JOB,SAL;
6
SELECT * FROM dept;
DEPTNO DNAME LOC
ELMASRI ANALYST 10
CODD ANALYST 10
DATE PROGRAMMER 10
7
Άσκηση
Γράψε αναζήτηση που βρίσκει ποιοί υπάλληλοι έχουν την ίδια θέση με
κάποιο υπάλληλο του τμήματος ACCOUNTING.
8
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 6: Ταξινόμηση
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Ταξινόμηση
COM
EMPNO ENAME JOB MGR HIREDATE SAL M DEPTNO
3
Η Δημιουργία της βάσης με mySQL έγινε στην Τρίτη άσκηση. Οι πίνακες
δημιουργούνται με κύρια και ξένα κλειδιά.
NEW
10 ACCOUNTING
YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
M CO
G M DEPT
EMPNO ENAME JOB R HIREDATE SAL M NO
01/01/198 300
10 CODD ANALYST 15 - 10
9 0
02/05/199 120
15 ELMASRI ANALYST 15 150 10
5 0
07/07/197 200
20 NAVATHE SALESMAN 20 - 20
7 0
4
SELECT * FROM proj
10 100 40
10 200 60
15 100 100
20 200 100
30 100 100
WHERE συνθήκη
όνομα_πίνακα.όνομα_στήλης κτλ.;
5
Δηλαδή, ο προγραμματιστής μπορεί να επιλέξει πολλά επίπεδα ταξινόμησης κατά
αύξουσα σειρά (όταν η αντίστοιχη στήλη συνοδεύεται με δήλωση ASC ή δεν
συνοδεύεται από δήλωση) ή φθίνουσα σειρά (όταν η αντίστοιχη στήλη συνοδεύεται
με δήλωση DESC).
Για χαρακτήρες η ταξινόμηση ακολουθεί την σειρά του πίνακα ASCII. Ετσι το 0
προηγείται του 9, το Α του Ζ κτλ.
Στην περίπτωση του προϊόντος της ORACLE οι τιμές NULL πάντοτε εμφανίζονται
πρώτες στα αποτελέσματα και απαιτείται τέχνασμα με χρήση συνάρτησης NVL-Null
Value για να ανατραπεί το γεγονός αυτό. Τι συμβαίνει στην περίπτωση του
προϊόντος της mySQL;
Η παρακάτω αναζήτηση ταξινομεί τους υπαλλήλους κατά Τμήμα και φθίνουσα τάξη
μισθού.
FROM EMP
6
ENAME DEPTNO JOB SAL
Ασκήσεις
Άσκηση1 Βρες τους υπάλληλους της Τμήματος 10 και δείξε τους κατά μισθό.
Άσκηση 3 Να διατάξεις τους υπαλλήλους κατά θέση και για κάθε θέση κατά
φθίνουσα τάξη μισθού.
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 7: Υποπρόταση GROUP BY. Χρήση υποπρότασης HAVING σε συνδυασμό με
υποπρόταση GROUP BY
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Υποπρόταση GROUP BY. Χρήση υποπρότασης HAVING σε
συνδυασμό με υποπρόταση GROUP BY
3
SELECT * FROM dept
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
M CO DEPT
EMPNO ENAME JOB GR HIREDATE SAL MM NO
4
SELECT * FROM assign
10 100 40
10 200 60
15 100 100
20 200 100
30 100 100
GROUP BY όνομα_πίνακα.όνομα_στήλης;
5
Παράδειγμα: Χρήση απλής στήλης ως κριτηρίου σε GROUP BY
Η παρακάτω αναζήτηση ομαδοποιεί τους υπαλλήλους ανά τμήμα και
βρίσκει το μέσο όρο μισθού.
GROUP BY DEPTNO;
DEPTNO AVG(SAL)
20 2000
10 2000
HAVING συνθήκη;
6
Παράδειγμα 1: Χρήση GROUP BY … HAVING
Η παρακάτω αναζήτηση βρίσκει το μέσο όρο μισθού υπαλλήλων που
κάνουν την ίδια εργασία όταν ο μέσος μισθός ξεπερνά τις 1250.
GROUP BY JOB
JOB AVG(SAL)
SALESMAN 2000
ANALYST 2100
PROGRAMMER 1800
FROM EMP
GROUP BY JOB
ANALYST 2100 2
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 8: Συνδέσεις
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Συνδέσεις
3
SELECT * FROM dept
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
M
G CO DEPT
EMPNO ENAME JOB R HIREDATE SAL MM NO
4
SELECT * FROM assign
10 100 40
10 200 60
15 100 100
20 200 100
30 100 100
όνομα_πίνακα2.όνομα_στήλης, ....
WHERE όνομα_πίνακα1.όνομα_στήλης =
όνομα_πίνακα2.όνομα_στήλης κτλ.
5
ENAME JOB SAL LOC
Επεξήγηση
EMP.DEPTNO = DEPT.DEPTNO
SELECT *
FROM EMP,DEPT
E
M
P DE
N EN AM MG HIRED A CO PT DEP
O E JOB R TE S AL MM NO TNO DN AM E LOC
NEW
3 PROGR ACCOUNTI
DATE 15 04/05/2004 1800 200 10 10 YOR
0 AMMER NG
K
NEW
1 ELMAS ANALYS ACCOUNTI
15 02/05/1995 1200 150 10 10 YOR
5 RI T NG
K
NEW
1 ANALYS ACCOUNTI
CODD 15 01/01/1989 3000 - 10 10 YOR
0 T NG
K
FROM EMP,DEPT
6
ENAME JOB SAL LOC
Προσοχή!
CUSTOMER(cust_name, cust_city)
SUPPLIER(suppl_name, suppl_city)
SUPPL_NAME SUPPL_CITY
ELMASRI ATHENS
7
SELECT * FROM customer;
CUST_NAME CUST_CITY
DATE BERLIN
Η παρακάτω αναζήτηση βρίσκει ποιοί πελάτες (customers) έχουν έδρα την ίδια
πόλη με κάποιο προμηθευτή (supplier):
SELECT *
WHERE customer.cust_city=supplier.suppl_city;
customer.cust_city=supplier.suppl_city
Καρτεσιανό Γινόμενο:
Προσοχή! Η εντολή
8
ENAME SAL LOC
9
Άσκηση 2: Χρήση σύνδεσης INNER JOIN - JOIN
Βρες όλους τους CODD από το πίνακα EMP και τη θέση της έδρας τους
από το πίνακα DEPT .
10
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 9: Επανάληψη σε δηλώσεις SQL - Εμβάθυνση
Χ. Σκουρλάς, Α. Τσολακίδης
Στόχος του εργαστηρίου είναι η εκμάθηση των δηλώσεις SQL με επανάληψη και η
εμβάθυνση με πρακτική άσκηση στα προϊόντα mySQL και Oracle
2
1. Επανάληψη σε δηλώσεις SQL - Εμβάθυνση
DEPTNO DNAM E
10 ACCOUNTING
20 SALES
30 PERSONNEL
3
Αλλάξτε στην εντολή τη σειρά πινάκων, συνθηκών και διαπιστώστε ότι η εντολή
υπολογίζει τα ίδια αποτελέσματα.
DEPTNO COUNT(*)
20 2
10 2
10 ACCOUNTING 2
20 SALES 2
JOBCODE COUNT(*)
100 2
4
Προσοχή! Δείτε την παρακάτω εντολή στην Oracle. Δοκιμάστε την ίδια εντολή στη
mySQL. Τι παρατηρείτε;
Προσοχή! Δείτε την παρακάτω εντολή στην Oracle. Δοκιμάστε την ίδια εντολή στη
mySQL. Τι παρατηρείτε;
SELECT *
FROM Employee
WHERE ename='smith'
Προσοχή! Δείτε την παρακάτω εντολή στην Oracle. Δοκιμάστε την ίδια εντολή στη
mySQL. Τι παρατηρείτε;
SELECT *
FROM Employee
WHERE ename='SMITH'
UPDATE Employee
SET ename='NICK'
WHERE empno=300;
5
Προσθέστε στήλη hiredate στον πίνακα Employee
ALTER TABLE Employee ADD(hiredate date);
UPDATE Employee
SET hiredate='2010/1/1'
WHERE empno=300;
Κ.λπ
Δείτε στην Oracle προσθήκη στήλης που δείχνει αριθμό υπαλλήλων και πως
μπορούμε να υπολογίσουμε αυτόματα τις τιμές της στήλης αυτής.
Δεδομένου ότι οι εντολές UPDATE, DELETE παρουσιάζουν διαφορές από προϊόν σε
προϊόν δοκιμάστε αν η εντολή UPDATE εκτελείται και στη mySQL
ALTER TABLE Department ADD (no_of_employees NUMBER(3));
UPDATE Department
SET no_of_employees =
(SELECT COUNT(*)
FROM Employee
WHERE Employee.deptno = Department.deptno);
10 ACCOUNTING 2
20 SALES 2
30 PERSONNEL 0
Δημιουργήστε νέο πίνακα και μεταφέρετε με μία εντολή INSERT δεδομένα από
άλλον πίνακα
CREATE TABLE my_Employee(empno NUMBER(4) NOT NULL,
ename VARCHAR2(20),
jobcode NUMBER(3) NOT NULL,deptno NUMBER(2) NOT NULL);
6
SELECT * FROM my_Employee;
MySQL:
SELECT empno,ename,jobcode,deptno
FROM Employee;
Διαγράψτε τη βάση
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 10: Σύστημα Διαχείρισης Βάσης Βιβλιοθήκης (Library Information System) -
Μοντελοποίηση και Κανονικοποίηση - Επανάληψη εντολών SQL
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Σύστημα Διαχείρισης Βάσης Βιβλιοθήκης (Library Information
System) - Μοντελοποίηση και Κανονικοποίηση - Επανάληψη
εντολών SQL
Έστω ότι η εταιρεία “Library Automation” στην οποία εργάζεστε αναλαμβάνει την
οργάνωση της νέας σπουδαστικής βιβλιοθήκης “La Galeria” που θα λειτουργεί
παράλληλα ως κέντρο πληροφόρησης σε μικρή επαρχιακή πόλη.
Δικό σας έργο είναι η δημιουργία και λειτουργία καταλόγου βιβλίων και η
οργάνωση της ταξινόμησης των βιβλίων στα ράφια.
Τέλος, η βιβλιοθήκη ενημερώνει έναν πίνακα με θέματα (subjects) και κάθε βιβλίο
μπορεί να έχει ένα ή περισσότερα θέματα.
2. Κάθε βιβλίο έχει πολλά θέματα και για ένα θέμα υπάρχουν πολλά βιβλία
στη βιβλιοθήκη.
3. Κάθε βιβλίο έχει ένα μοναδικό ISBN (Διεθνή Αριθμό Βιβλίου) και έναν
ακριβώς τίτλο.
3
4. Κάθε βιβλίο έχει τουλάχιστον ένα συγγραφέα και ένας συγγραφέας έχει
γράψει ένα ή περισσότερα βιβλία.
5. Κάθε βιβλίο έχει ένα μόνο εκδότη και κάθε εκδότης εκδίδει ένα ή
περισσότερα βιβλία..
6. Κάθε εκδότης έχει μία μόνο διεύθυνση και ένα μοναδικό όνομα.
Ακολουθεί μοντελοποίηση:
4
Η αντίστοιχη Τρίτη κανονική μορφή είναι η παρακάτω:
/* SCRIPT */
USE Library;
Subject VARCHAR(40));
Address VARCHAR(40));
5
SHOW TABLES;
Δείξτε ότι είναι δυνατόν να εισαχθούν πολλές φορές οι ίδιες γραμμές. Για
παράδειγμα στον πίνακα του βιβλίου (BOOKS) μπορείτε να καταχωρήσετε δύο
φορές το ίδιο βιβλίο ή δύο γραμμές (βιβλία) με τον ίδιο αριθμό βιβλίου. Αυτό
επιτρέπεται επειδή ενώ θεωρείτε τη στήλη ISBN του πίνακα BOOKS σαν κύριο
κλειδί αν δεν το δηλώσετε στον ορισμό του πίνακα τότε δεν γίνεται έλεγχος κατά
την εισαγωγή στοιχείων.
Διαγράψτε τους πίνακες BOOKS και PUBLISHERS και δημιουργήστε τους πάλι
ορίζοντας κύρια και ξένα κλειδιά. Εξετάστε με ποιά σειρά πρέπει να
δημιουργηθούν οι πίνακες
/* drop tables */
PRIMARY KEY(ISBN));
Παρατηρήστε ότι τώρα δεν μπορούμε να εισάγουμε την ίδια γραμμή σε πίνακα
όπου έχετε δηλώσει κύριο κλειδί. Εξετάστε αν μπορούμε να εισάγουμε γραμμή
6
στον πίνακα BOOKS που να περιλαμβάνει στοιχεία εκδότη που δεν υπάρχουν
στον πίνακα PUBLISHERS όταν οι δύο πίνακες είναι δεμένοι με σχέση κύριου -
ξένου κλειδιού.
/* drop tables */
PRIMARY KEY(ISBN),
FOREIGN KEY(PubName)
REFERENCES PUBLISHERS(PubName));
VALUES('0-672-30852-5',
7
'CLIENT/SERVER APPLICATIONS', 'SAMS', '005.74 DAT1');
ORDER BY PUBNAME;
ORDER BY PUBNAME;
8
Με ποιά σειρά πρέπει να διαγράψετε τους πίνακες BOOKS και PUBLISHERS όταν
οι δύο πίνακες είναι δεμένοι με σχέση κύριου - ξένου κλειδιού;
/* drop tables */
PRIMARY KEY(ISBN),
VALUES('0-672-30852-5' ,
9
Γράψτε αναζήτηση που να χρησιμοποιεί σύνδεση ανάμεσα στους πίνακες αυτούς.
ORDER BY PUBNAME;
DESCRIBE PUBLISHERS;
DESCRIBE AUTHORS;
10
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 11: Μελέτη Περιπτώσεως: Σύστημα Διαχείρισης Βάσης Βιβλιοθήκης
(Library Information System) – Μοντελοποίηση και Κανονικοποίηση -
Μοντελοποίηση με χρήση mySQL workbench
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Μελέτη Περιπτώσεως: Σύστημα Διαχείρισης Βάσης
Βιβλιοθήκης (Library Information System) – Μοντελοποίηση
και Κανονικοποίηση - Μοντελοποίηση με χρήση mySQL
workbench
3
Ακολουθούν οδηγίες για το πως θα συμπληρώσετε και τα στοιχεία Dewey. Αν δεν
κατανοήσετε τις παρακάτω οδηγίες γράψτε τυχαία παραδείγματα κωδικών Dewey.
Θα ήταν καλό όμως να προσπαθήσετε να κατανοήσετε τα παρακάτω για να μάθετε
να χρησιμοποιείτε τη βιβλιοθήκη.
Με το δεκαδικό σύστημα που ανέπτυξε ο Melvil Dewey το 1876 (το σύστημα έχει
τροποποιηθεί – επεκταθεί πάνω από είκοσι φορές από τότε) οι βιβλιοθηκονόμοι,
αλλά και οι έμπειροι χρήστες της βιβλιοθήκης, τοποθετούν τα βιβλία στα ράφια με
τέτοιο τρόπο ώστε να τα βρίσκουν εύκολα και επίσης να τα επιστρέφουν εύκολα
στη θέση τους. Το σύστημα Dewey χρησιμοποιείται σε περισσότερες από 200,000
βιβλιοθήκες σε περισσότερες από 130 χώρες!
200 – Religion
400 – Language
800 – Literature
4
Επομένως έχουμε 10 κύριες κατηγορίες (main classes), 100 διευθύνσεις (divisions)
και 1000 ενότητες (sections). Να οι πρώτες από τις 1000 ενότητες:
001 Knowledge
003 Systems
007 [Unassigned]
008 [Unassigned]
009 [Unassigned]
Με άμεση (online) πρόσβαση στα στοιχεία του καταλόγου της βιβλιοθήκης, που
γίνεται μέσω διαδικτύου (δες Υπηρεσίες - - > βιβλιοθήκη κ.λπ. στον ιστότοπο του
ΤΕΙ), μπορούν οι σπουδαστές να βλέπουν στον υπολογιστή τους αν υπάρχει ένα
βιβλίο στη βιβλιοθήκη και επιπλέον τους παρέχονται στοιχεία ώστε να το βρουν
εύκολα όταν πάνε στη βιβλιοθήκη. Ακολουθούν παραδείγματα:
Παράδειγμα 1ο
Έστω ότι βλέπετε τα παρακάτω στοιχεία βιβλιου που σας ενδιαφέρει στον κατάλογο
της βιβλιοθήκης. Τα στοιχεία είναι προσβάσιμα από την ιστοσελίδα.
ISBN: 0201113589
5
Πληροφορίες Αντιτύπου
Διαθέσιμο
Παράδειγμα 2ο
Στοιχεία καταλόγου
ISBN: 0077092333
Πληροφορίες Αντιτύπου
Διαθέσιμο
6
Ερώτηση
Τι σημαίνουν τα γράμματα μετά τους αριθμούς στις δύο ταξινομήσεις;
005.74 DAT1
003 AVI 1
“Books are placed on the shelf in increasing numerical order of the decimal number,
e.g. 050, 220, 330, 330.973, 331. When two books have the same classification
number the second line of the call number (usually the first letter or letters of the
author's last name, the title if there is no identifiable author) is placed in alphabetical
order”.
Υπόδειξη Βρείτε τα δύο παραπάνω βιβλία στα ράφια της βιβλιοθήκης του ΤΕΙ
Αθήνας
Βιβλιογραφία
http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
http://en.wikipedia.org/wiki/List_of_Dewey_Decimal_classes
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 12: Μελέτη Περιπτώσεως: Σύστημα Διαχείρισης Βάσης Βιβλιοθήκης
(Library Information System) - Ορισμός και χρήση View
Χ. Σκουρλάς, Α. Τσολακίδης
Στόχος του εργαστηρίου είναι η εκμάθηση και εμβάθυνση σε δηλώσεις SQL που
διαχειρίζονται views.
2
1. Μελέτη Περιπτώσεως: Σύστημα Διαχείρισης Βάσης
Βιβλιοθήκης (Library Information System) - Ορισμός και χρήση
View
Έστω ότι η εταιρεία “Library Automation” στην οποία εργάζεστε αναλαμβάνει την
οργάνωση της νέας σπουδαστικής βιβλιοθήκης “La Galeria” που θα λειτουργεί
παράλληλα ως κέντρο πληροφόρησης σε μικρή επαρχιακή πόλη.
Δικό σας έργο είναι η δημιουργία και λειτουργία καταλόγου βιβλίων και η
οργάνωση της ταξινόμησης των βιβλίων στα ράφια.
Ακολουθεί μοντελοποίηση:
3
WRITER (ISBN, AuthorNo)
PUBLISHER (PubName, Address)
USE Library;
4
Ορίστε την παρακάτω όψη:
/* create view */
CREATE VIEW NEW_YORK_PUBL(PNAME, PADD)
AS SELECT PubName, Address
FROM PUBLISHERS
WHERE Address = 'NEW YORK';
Διαπιστώστε ότι οι γραμμές που εισάγετε στον πίνακα PUBLISHERS φαίνονται και
στην όψη αν ικανοποιείται το κριτήριο Address = ‘NEW_YORK’.
Διαπιστώστε ότι οι γραμμές που εισάγετε στην όψη (και ικανοποιείται το κριτήριο
Address = ‘NEW_YORK’ ) φαίνονται και στον πίνακα PUBLISHERS .
5
DROP VIEW NEW_YORK_PUBL;
6
Άσκηση
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 13: Μελέτη Περιπτώσεως: Αμερικανικές Προεδρικές εκλογές
Χ. Σκουρλάς, Α. Τσολακίδης
Στόχος του εργαστηρίου είναι η εκμάθηση και εμβάθυνση σε δηλώσεις SQL και σε
θέματα σχεδιασμού και κανονικοποίησης.
2
Case Study: Αμερικανικές Προεδρικές εκλογές
Έστω απλουστευμένη βάση των αμερικανικών προεδρικών εκλογών.
Στο δείγμα (παγκόσμια σχέση) παρατίθενται εκλογικά αποτελέσματα
για τις αναμετρήσεις από το 1952 έως το 1992.
Η αναγραφή NULL σε μια θέση του πίνακα σημαίνει ότι η αντίστοιχη θέση δεν έχει
τιμή.
Στη συνέχεια παραθέτουμε τέσσερις (4) πίνακες (3RD Normal Form - 3NF) στους
οποίους πρέπει να γράψετε τα στοιχεία των εκλογών.
3
PRESIDENTS
LOSERS
LOSER L_PARTY
STEVENSON DEMOCRAT
REPUBLICAN
NIXON
ELECTIONWINNER
ELECTIONLOSER
1952 STEVENSON 89
1956 STEVENSON 73
4
1.1 Υλοποίηση
Ακολουθούν εντολές δημιουργίας πινάκων στο προϊόν της Oracle. Στους ορισμούς
αυτούς παραλείπονται τα πρωτεύοντα και τα ξένα κλειδιά.
PRESIDENTS
LOSERS
LOSER L_PARTY
ELECTIONWINNER
ELECTIONLOSER
5
Δημιουργήστε τη βάση ELECTIONS με τους παραπάνω πίνακες στο προϊόν της
mySQL. Στους ορισμούς σας να συμπεριλάβετε πρωτεύοντα και ξένα κλειδιά.
Γράψτε όλες τις εντολές εισαγωγής δεδομένων στο προϊόν της mySQL
6
SELECT winner, w_party, w_state
FROM presidents
FROM presidents
FROM presidents
SELECT winner,w_party,w_state
FROM presidents
7
Τέλος, γράψτε τις παρακάτω αναζητήσεις:
8
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 14: Μελέτη Περιπτώσεως: Ακτινοθεραπευτικό Κέντρο Blue Sky
Χ. Σκουρλάς, Α. Τσολακίδης
Στόχος του εργαστηρίου είναι η εκμάθηση αλλά και η εμβάθυνση σε δηλώσεις SQL
και σε θέματα σχεδιασμού και κανονικοποίησης.
2
Case study: Radiotherapy
Κάθε γιατρός έχει έναν μοναδικό κωδικό, επώνυμο και όνομα, μία ειδικότητα και
ένα τηλέφωνο. Υπάρχουν πολλοί γιατροί για μία συγκεκριμένη ειδικότητα.
Επομένως, για τους γιατρούς του κέντρου στη βάση δεδομένων καταχωρούνται τα
εξής στοιχεία:
d_code=κωδικός γιατρού, μοναδικός για κάθε γιατρό
d_Surname=επώνυμο, d_Name=όνομα
d_speciality=ειδικότητα, d_phone=τηλέφωνο
3
Το κέντρο συνεργάζεται με συγκεκριμένες ασφαλιστικές εταιρείες και ταμεία. Κάθε
εταιρεία ή ασφαλιστικό ταμείο έχει έναν μοναδικό κωδικό και μία επωνυμία. Στο
σύστημα καταχωρούνται:
Health_insurance_accno=κωδικός
Health_insurance=επωνυμία
Code=κωδικός,
Status=οικογενειακή κατάσταση
Κάθε ασθενής έχει ένα μοναδικό κωδικό, επωνυμο, όνομα, ημερομηνία γέννησης,
τόπο γέννησης, εθνικότητα, φύλλο, διεύθυνση, τηλέφωνο. Επισης, για κάθε ασθενή
καταχωρείται η ασφαλιστική εταιρεία ή το ταμείο που τον καλύπτει και η
οικογενειακή του κατάσταση (έγγαμος, άγαμος).
4
Για τους ασθενείς της κλινικής στη βάση δεδομένων καταχωρούνται τα εξής
στοιχεία:
p_code=κωδικός,
p_surname=επωνυμο, p_name=όνομα
p_birthdate=ημερομηνία γέννησης, p_birthplace=τόπος γέννησης
p_nationality=εθνικότητα
p_sex=φύλλο, p_address=διεύθυνση, p_phone=τηλεφωνο
p_profession=επάγγελμα
Health_insurance_accno=κωδικός ασφαλιστικής ή ταμείου στο οποίο ανήκει ο
ασθενής
Marital_Status_code=κωδικός οικογενειακής κατάστασης
5
Σχεδίαση μοντέλου με χρήση συμβολσμού Navathe-Elmasri και
χρήση Mysql Workbench
Υλοποίηση - Ζητούμενα
6
select count(*), Health_Insurance_Accno
from Patient
group by Health_Insurance_Accno
having Health_insurance_accno in(select Health_insurance_accno
from Patient,Test
where Patient.p_code = Test.P_code
and therapy_code = 100)
order by Health_Insurance_Accno;
24. Κατασκευάστε όψη που περιλαμβάνει άγαμους ασφαλισμένους του ΙΚΑ με
διάγνωση καρκίνου του λάρυγγα. Δείξτε τα στοιχεία της όψης.
25. Προσθέστε κύρια κλειδιά στους πίνακες.
26. Προσθέστε ξένα κλειδιά στους πίνακες.
27. Χρησιμοποιήστε mySQL Workbench για να κατασκευάσετε μοντέλο
οντοτήτων συσχετίσεων
28. Χρησιμοποιήστε mySQL Workbench για να εισάγετε στοιχεία στους πίνακες
της βάσης.
29. Διαγράψτε τους πίνακες της βάσης
30. Διαγράψτε τη βάση δεδομένων
7
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 15: Σύνδεση Excel-Mysql
Χ. Σκουρλάς, Α. Τσολακίδης
2
1. Σύνδεση Excel-Mysql
3
Επιλέξτε MySQL ODBC 5.1 Driver και στη συνέχεια Finish . Εάν δεν εμφανίζεται ,
υπάρχει λάθος κατά την εγκατάσταση του driver.
4
Εμφανίζεται η παρακάτω οθόνη:
Επιλέγετε ADD
5
Στην συνέχεια επιλέγετε τον πίνακα π.χ. electionloser
6
Και επιλέγετε Τέλος
7
1. Πίνακας
Εμφανίζονται τα περιεχόμενα του πίνακα.
Συγκεντρωτικού Πίνακα_1
8
Συγκεντρωτικού Πίνακα_2
9
Τέλος, παρέχεται η δυνατότητα στη στήλη Τιμές να κάνετε δεξί κλικ και να
επιλέξετε Ρυθμίσεις πεδίου τιμής. Για παράδειγμα επιλέγετε Μ.Ο. l_votes
Επίσης κάθε φορά που θέλετε να συνδεθείτε με Mysql επιλέγετε τη σύνδεση την
οποία δημιουργήσατε (Δεδομένα> Υπάρχουσες Συνδέσεις)
10
11
Βάσεις Δεδομένων Ι (Ε)
Ενότητα 16: Εξετάσεις – Θέματα και κάποιες ενδεικτικές λύσεις
Χ. Σκουρλάς, Α. Τσολακίδης
2
Θέμα 1
Έστω η παρακάτω βάση δεδομένων Νοσοκομείων
Υποτίθεται ότι το κύριο κλειδί είναι σύνθετο = (H_id, W_id, P_id, Entry_date)
1) Η βάση είναι στην Τρίτη κανονική μορφή; Αν όχι γράψτε την Τρίτη κανονική
μορφή.
3
Αντικαθίσταται από τους πίνακες:
2) Δημιουργήστε την παραπάνω βάση με κύρια και ξένα κλειδιά και γράψτε τις
απαραίτητες εντολές INSERT INTO ώστε να καταχωρηθούν όλες οι
εισαγωγές του ΠΕΤΡΟΥ σε νοσοκομεία.
4
P_id int(5) NOT NULL, Entry_Date DATE NOT NULL,
PRIMARY KEY(H_id, W_id, P_id, Entry_date),
FOREIGN KEY(H_id, W_id)REFERENCES ward(H_id, W_id),
FOREIGN KEY (P_id)REFERENCES patient(P_id));
5
3) Αλλάξτε τον πίνακα Ward (δομή και περιεχόμενο)ώστε να έχει την
παρακάτω μορφή:
UPDATE ward
SET beds=10
WHERE w_id=1000 AND h_id=100;
6
Θέμα 2
Έστω απλοποιημένη βάση δεδομένων Διεύθυνσης Προσωπικού. Οι στήλες των
πινάκων είναι: Empno=Κωδικός υπαλλήλου, Name=όνομα, JobCode/JobNo=κωδικός
θέσης, Job_descr= θέση, Deptno=κωδικός τμήματος, Dname=τμήμα Sal=μισθός,
Comm=προμήθεια. Υποτίθεται ότι κάθε υπάλληλος ανήκει σε ένα τμήμα και ότι ο
μισθός του εξαρτάται από τη θέση του.
Emp
Empno Name JobCode DeptNo Comm
Job
JobNo Job_descr Sal
Dept
DeptNo Dname Loc
50 ΠΩΛΗΣΕΙΣ ΑΘΗΝΑ
60 ΛΟΓΙΣΤΗΡΙΟ ΑΘΗΝΑ
70 ΜΙΣΘΟΔΟΣΙΑ ΒΟΛΟΣ
7
INSERT INTO DEPT(DEPTNO, DNAME, LOC)
VALUES (60, 'ΛΟΓΙΣΤΗΡΙΟ', 'ΑΘΗΝΑ');
INSERT INTO DEPT(DEPTNO, DNAME, LOC)
VALUES (70, 'ΜΙΣΘΟΔΟΣΙΑ', 'ΒΟΛΟΣ');
8
1. Δείξτε (SELECT) name, empno, jobCode, job_descr, sal, deptno, dname των
υπαλλήλων που είναι αναλυτές ή πωλητές. Οι υπάλληλοι θα είναι
ταξινομημένοι ανά θέση (job_descr).
2. Δείξτε (SELECT) name, empno, jobCode, job_descr, sal, deptno, dname των
υπαλλήλων που ανήκουν σε ένα από τα τμήματα: «ΠΩΛΗΣΕΙΣ» ή
«ΛΟΓΙΣΤΗΡΙΟ» (με 2 τρόπους) (select … select, χρήση join)
9
3. Δείξτε name, empno, job_descr, sal των υπαλλήλων με σύνολο αμοιβών
(άθροισμα μισθού και προμήθειας) μεγαλύτερο των 1000 ευρώ και
μικρότερο των 3000 ευρώ.
10
4. Διορθώστε και συμπληρώστε την παρακάτω εντολή SELECT ώστε να δείχνει
στοιχεία πωλητών και αναλυτών που έχουν μισθό μεγαλύτερο των 1500
ευρώ. Πρέπει να έχουμε δύο επίπεδα ταξινόμησης: Οι υπάλληλοι θα
τυπώνονται ανά θέση δηλαδή πρώτα οι αναλυτές, μετά οι πωλητές και οι
υπαλληλοι που έχουν την ίδια θέση θα εμφανίζονται αλφαβητικά.
11
5. Γράψτε εντολή SELECT η οποία υπολογίζει πόσοι υπάλληλοι έχουν κωδικό
θέσης 100 (είναι πωλητές), πόσοι 300 (είναι χειριστές) κ.λπ. Να πως θα
φαίνονται τα αποτελέσματα.
JobCode No_of_employees.
100 2
300 1
JobCode No_of_employees
100 2
SELECT jobcode, COUNT(*)
FROM emp
GROUP BY jobcode
HAVING COUNT(*)>1
ORDER BY jobcode;
12
7. Δείξτε τους υπάλληλους με έδρα 'ΑΘΗΝΑ' ή 'ΒΟΛΟΣ' και θέση σαν του
ΣΠΥΡΟΥ.
9. Εμφάνισε τον εργαζόμενο που έχει τον μεγαλύτερο μισθό στο τμήμα
'ΠΩΛΗΣΕΙΣ'
13
Λύνεται και χωρίς την υποπρόταση deptno IN (SELECT deptno FROM dept WHERE
dname='ΠΩΛΗΣΕΙΣ'). Απλά χρησιμοποιούμε τον κωδικό για dname='ΠΩΛΗΣΕΙΣ' ή
σύνδεση.
SELECT *
FROM EMP
WHERE SUBSTR(name,1, 1) IN ('Ν','Σ');
14
Ανοικτά Ακαδημαϊκά Μαθήματα
Τεχνολογικό Εκπαιδευτικό Ίδρυμα Αθήνας
Στόχος του πρώτου εργαστηρίου είναι μία περιεκτική εστίαση σε σημαντικά θέματα
σχεδιασμού Βάσεων Δεδομένων (μοντελοποίηση, κανονικοποίηση) και υλοποίησης
Βάσεων Δεδομένων με χρήση SQL.
2
1ο. ΘΕΜΑ (σχεδιασμός βάσης δεδομένων)
Περιορισμοί
Υποτίθεται ότι κάθε υπάλληλος έχει μία θέση, ανήκει σε ένα τμήμα, ο μισθός του
εξαρτάται από τη θέση και έχει ή δεν έχει παιδιά.
Employee
Empno Name JobNo Job DeptNo Dname Sal C_no C_Name B_date
10 ΣΠΥΡΟΥ 100 ΠΩΛΗΤΗΣ 50 ΠΩΛΗΣΕΙΣ 2200 2 ΜΑΡΙΑ 10/01/89
10 ΣΠΥΡΟΥ 100 ΠΩΛΗΤΗΣ 50 ΠΩΛΗΣΕΙΣ 2200 2 ΙΩΑΝΝΗΣ 20/03/90
20 ΧΡΗΣΤΟΥ 200 ΑΝΑΛΥΤΗΣ 60 ΛΟΓΙΣΤΗΡΙΟ 2000
30 ΝΙΚΟΥ 300 ΧΕΙΡΙΣΤΗΣ 70 ΜΙΣΘΟΔΟΣΙΑ 1000 1 ΘΩΜΑΣ 10/06/89
Γράψτε Πρώτη, Δεύτερη και Τρίτη Κανονική Μορφή και σχεδιάστε το Μοντέλο
Οντοτήτων–Συσχετίσεων με συμβολισμό Navathe-Elmasri.
Υπόδειξη επίλυσης
Ποιο είναι το κύριο κλειδί στην 1NF; Σίγουρα όχι το σύνθετο (empno, c_name)
(γιατί;)
3
Μοντέλο Οντοτήτων Συσχετίσεων (Entity Relationship model)
Employee
Empno Name JobNo DeptNo C_no
10 ΣΠΥΡΟΥ 100 50 2
20 ΧΡΗΣΤΟΥ 200 60
30 ΝΙΚΟΥ 300 70 1
Κύριο κλειδί: empno
Jobs Dept
JobNo Job Sal DeptNo Dname
100 ΠΩΛΗΤΗΣ 2200 50 ΠΩΛΗΣΕΙΣ
200 ΑΝΑΛΥΤΗΣ 2000 60 ΛΟΓΙΣΤΗΡΙΟ
300 ΧΕΙΡΙΣΤΗΣ 1000 70 ΜΙΣΘΟΔΟΣΙΑ
Κύριο κλειδί: JobNo Κύριο κλειδί: deptno
Child
Empno C_Name B_date
10 ΜΑΡΙΑ 10-JAN-89
10 ΙΩΑΝΝΗΣ 20-MAR-90
30 ΘΩΜΑΣ 10-JUN-89
Κύριο κλειδί: (empno, c_name)
Names
C_Name
ΘΩΜΑΣ
ΙΩΑΝΝΗΣ
ΜΑΡΙΑ
Κύριο κλειδί: (c_name)
4
2ο. ΘΕΜΑ (υλοποίηση βάσης δεδομένων))
Υπόδειξη επίλυσης
Emp
Empno Name JobΝο DeptNo Comm
10 ΣΠΥΡΟΥ 100 50 450
20 ΧΡΗΣΤΟΥ 200 50
30 ΝΙΚΟΥ 300 60
Job
JobCode Job_descr Sal
100 ΠΩΛΗΤΗΣ 2200
200 ΑΝΑΛΥΤΗΣ 2000
300 ΧΕΙΡΙΣΤΗΣ 1000
Dept
DeptNo Dname Loc
50 ΠΩΛΗΣΕΙΣ ΑΘΗΝΑ
60 ΛΟΓΙΣΤΗΡΙΟ ΑΘΗΝΑ
70 ΜΙΣΘΟΔΟΣΙΑ ΒΟΛΟΣ
/* Πρώτη εκδοχή */
5
FOREIGN KEY (JOBNO) REFERENCES JOB(JOBCODE),
FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO));
/* Δεύτερη εκδοχή */
use testing;
/* Πρώτη εκδοχή */
6
(10,'ΣΠΥΡΟΥ',100,50,450);
/* Δεύτερη εκδοχή */
(60,'LOGISTHRIO','ATHENS'),(70,'MISTHODOSIA','VOLOS');
3. Δείξτε (SELECT) name, empno, job_descr, sal, deptno, dname των υπαλλήλων
που είναι αναλυτές ή πωλητές ή χειριστές. Οι υπάλληλοι θα είναι
ταξινομημένοι ανά θέση (job_descr).
/* Πρώτη εκδοχή */
SELECT ENAME,EMPNO,JOB_DESCR,SAL,EMP.DEPTNO,DNAME
FROM EMP,DEPT,JOB
WHERE EMP.DEPTNO=DEPT.DEPTNO
AND JOBNO=JOBCODE
AND JOB_DESCR IN ('ΠΩΛΗΤΗΣ','ΑΝΑΛΥΤΗΣ','ΧΕΙΡΙΣΤΗΣ')
ORDER BY JOB_DESCR;
7
/* Δεύτερη εκδοχή */
select empno,job_descr,sal,emp.deptno,dname
from emp,job,dept
where emp.deptno=dept.deptno
and emp.jobNo=Job.JobCode
order by job_descr;
/* Πρώτη εκδοχή */
SELECT ENAME,EMPNO,JOB_DESCR,SAL
FROM EMP,JOB
WHERE JOBNO=JOBCODE
AND ( (SAL+IFNULL(COMM,0))>=1000 AND (SAL+IFNULL(COMM,0))<=3000 );
SELECT ENAME,EMPNO,JOB_DESCR,SAL
FROM EMP,JOB
WHERE JOBNO=JOBCODE
AND SAL+IFNULL(COMM,0) BETWEEN 1000 AND 3000;
/* Δεύτερη εκδοχή */
select name,empno,job_descr,sal
from emp,job
where Emp.jobNo=Job.jobCode
select name,empno,job_descr,sal
from emp,job
where Emp.jobNo=Job.jobCode
8
5. Διορθώστε και συμπληρώστε την παρακάτω εντολή SELECT ώστε να δείχνει
στοιχεία πωλητών, αναλυτών και χειριστών που έχουν μισθό μεγαλύτερο
των 1500 ευρώ και μικρότερο από 4000 ευρώ. Πρέπει να έχουμε δύο
επίπεδα ταξινόμησης: Οι υπάλληλοι θα τυπώνονται ανά θέση δηλαδή πρώτα
οι αναλυτές, μετά οι πωλητές και μετά οι χειριστές και οι υπάλληλοι που
έχουν την ίδια θέση θα εμφανίζονται αλφαβητικά.
SELECT empno, name, job, sal, comm, deptno, dname
FROM
WHERE
ORDER BY
/* Πρώτη εκδοχή */
/* Δεύτερη εκδοχή */
from emp,job,dept
order by job_descr,name;
6. Γράψτε εντολή SELECT η οποία υπολογίζει ανά κωδικό θέσης (100, 200, …)
πόσοι είναι οι υπάλληλοι που κατέχουν τη θέση. Να πως θα φαίνονται τα
αποτελέσματα στο συγκεκριμμένο παράδειγμα.
JobΝο No_of_employees
100 1
200 1
300 1
/* Πρώτη εκδοχή */
9
/* Δεύτερη εκδοχή */
from emp
group by jobno;
7. Τροποποιήστε την εντολή SELECT έτσι ώστε αν και υπολογίζει πόσοι είναι οι
υπάλληλοι ανά κωδικό θέσης (100, 200, 300, …) να δείχνει μόνο θέσεις που
απασχολούν τουλάχιστον έναν υπαλλήλο:
JobNo No_of_employees.
100 1
200 1
300 1
/* Πρώτη εκδοχή */
/* Δεύτερη εκδοχή */
from emp
group by jobno
having count(*)>=1;
8. Εμφάνισε κάθε εργαζόμενο της εταιρείας που έχει μισθό ίσο με τον
μεγαλύτερο μισθό στο τμήμα 'ΠΩΛΗΣΕΙΣ'
/* Πρώτη εκδοχή */
SELECT ENAME,EMPNO,SAL
FROM EMP,JOB
WHERE JOBNO=JOBCODE
AND SAL=(SELECT MAX(SAL)
FROM EMP,DEPT,JOB
WHERE EMP.DEPTNO=DEPT.DEPTNO
AND JOBNO=JOBCODE
AND DNAME='ΠΩΛΗΣΕΙΣ');
/* Δεύτερη εκδοχή */
10
select empno,name
from emp,dept,job
where emp.deptno=dept.deptno
and emp.jobno=job.jobcode
/* Τρίτη εκδοχή */
FROM emp,job,dept
WHERE dept.deptno=emp.deptno
AND job.jobcode=emp.jobno
FROM job,emp,dept
WHERE dept.deptno=emp.deptno
AND job.jobcode=emp.jobno
AND dname='pwlhseis');
/* Πρώτη εκδοχή */
/* Δεύτερη εκδοχή */
11
select DeptNo,Dname,substring(Dname,1,3)
from dept;
- The entity integrity rule refers to rules the primary key must follow.
The foreign key may be null and may have the same value but:
The foreign key value must match a record in the table it is referring to.
/* Τρίτη εκδοχή */
Πρώτος κανόνας ακεραιότητας: Το κύριο κλειδί ή κάποιο μέρος του (αν έχουμε σύνθετο
κύριο κλειδί) απαγορεύεται να είναι NULL.
Δεύτερος κανόνας ακεραιότητας: Απαγορεύεται να γίνει INSERT μια τιμή σε μία στήλη που
είναι ξένο κλειδί αν αυτή η τιμή δεν υπάρχει εκεί που η αντίστοιχη στήλη της είναι κύριο
κλειδί. Αντίστοιχα ισχύουν για UPDATE, DELETE. Στο σχήμα ο πίνακας Alpha έχει μόνο μία
γραμμή.
12
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 2: Ανασκόπηση χρήσης της Γλώσσας SQL – θέματα υλοποίησης Βάσεων
Δεδομένων - Χρήση περιορισμών (constraints) – Χρήση Views
Στόχος του δεύτερου εργαστηρίου είναι η ανασκόπηση των εντολών της γλώσσας
SQL έτσι ώστε στα επόμενα εργαστήρια ο ενδιαφερόμενος να εστιάσει απρόσκοπτα
σε θέματα υλοποίησης Βάσεων Δεδομένων με χρήση SQL και να προχωρήσει σε
θέματα αποθηκευμένων διαδικασιών (stored procedures), διαχείρισης cursors,
διαχείρισης δοσοληψιών (transactions processing) κ.λπ.
2
1. Δημιουργία βάσης δεδομένων, δημιουργία πινάκων,
ορισμός ευρετηρίων, αλλαγή ορισμού (προσθήκη στηλών,
τροποποίηση στηλών) κ.λπ.
Εντολές
1) CREATE DATABASE
2) ALTER DATABASE
3) CREATE TABLE
4) ALTER TABLE
5) DROP TABLE
6) CREATE INDEX
7) CREATE UNIQUE INDEX
8) DROP INDEX
9) CREATE TRIGGER
10) DROP TRIGGER
11) REPLACE TRIGGER
12) CREATE PROCEDURE
13) DROP PROCEDURE
14) CREATE FUNCTION
15) DROP FUNCTION
Εντολές
1) SELECT
2) UPDATE
3) DELETE
4) INSERT INTO
1) GRANT
2) REVOKE
3
1.2 Διαχείριση δοσοληψιών
1) COMMIT
2) ROLLBACK
);
Εξαρτάται από το προϊόν. Για παράδειγμα, στην περίπτωση του προϊόντος της
ORACLE χρησιμοποιούνται οι τύποι δεδομένων:
4
Στο προϊόν Mysql οι τύποι δεδομένων διαφέρουν λίγο πχ.
number -> numeric, int, float
varchar2->varchar
Βιβλιογραφία
http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm
http://ss64.com/ora/syntax-datatypes.html
http://dev.mysql.com/doc/refman/5.7/en/data-types.html
5
2.5 Αλλαγή ορισμού πίνακα με εντολή ALTER TABLE – Εντολή
RENAME
Προσοχή! Η εντολή ALTER TABLE (όπως και άλλες εντολές στη συνέχεια)
διαφέρει από προϊόν σε προϊόν.
new_table TO old_table;
new_table TO old_table,
tmp_table TO new_table;
alter table
table_name
rename to
new_table_name;
FROM job_history;
6
ALTER TABLE customers
RENAME COLUMN credit TO credit_amount;
Βιβλιογραφία
http://dev.mysql.com/doc/refman/5.0/en/charset-conversion.html
http://docs.oracle.com/cd/E17952_01/refman-5.1-en/alter-table.html
7
3.1 Ευρετήρια για απλές στήλες πίνακα
Για να ορίσουμε το ευρετήριο INAME που θα βασίζεται στη στήλη ENAME στον
πίνακα EMP:
8
Παρατηρήστε ότι για τις στήλες του πίνακα δεν ορίσαμε περιορισμούς.
Όταν μια στήλη ενός πίνακα οριστεί ως NOT NULL δεν μπορεί να δεχτεί NULL
τιμές (values).
Προσθήκη περιορισμού:
Εισαγωγή δεδομένων
insert into persons(p_id,lastname,firstname,address,city) values
(1,'Papadopoulos','Marios','Axarnwn 5','Athens');
Τι θα δούμε;
Action Message
insert into 1 row(s) affected
persons(p_id,lastname,firstname,address,city)
values (1,'Papadopoulos','Marios','Axarnwn
9
5','Athens')
Action Message
insert into Error Code: 1364.
persons(lastname,firstname,address,city) Field 'p_id' doesn't
values ('Petrou','Nikos','Patisiwn 12','Athens') have a default value
Τι συμπέρασμα βγάζετε;
Διαγραφή δεδομένων
delete from persons where p_id=1;
Ακολουθεί παράδειγμα
10
Εισαγωγή δεδομένων
insert into persons(p_id,lastname,firstname,address,city) values
(1,'Papadopoulos','Marios','Axarnwn 5','Athens');
OUTPUT
Action Message
insert into 1 row(s) affected
persons(p_id,lastname,firstname,address,city)
values (1,'Papadopoulos','Marios','Axarnwn
5','Athens')
Action Message
insert into Error Code: 1062.
persons(p_id,lastname,firstname,address,city) Duplicate entry '1' for
values (1,'Petrou','Nikos','Patisiwn key 'p_id_UNIQUE'
12','Athens');
Τι συμπέρασμα βγάζετε;
Διαγραφή δεδομένων
delete from persons where p_id=1;
11
Κατάργηση περιορισμού PRIMARY KEY
Εισαγωγή δεδομένων
Action Message
insert into 1 row(s) affected
persons(p_id,lastname,firstname,address,city)
values (1,'Papadopoulos','Marios','Axarnwn
5','Athens')
Action Message
insert into Error Code: 1062.
persons(p_id,lastname,firstname,address,city) Duplicate entry '1' for
values (1,'Petrou','Nikos','Patisiwn key 'PRIMARY'
12','Athens');
Τι συμπέρασμα βγάζετε;
12
6. Ο περιορισμός Foreign Key
Εισαγωγή δεδομένων
insert into orders values(1,1000,1),(2,1000,1),(3,1000,2);
OUTPUT
Action Message
insert into orders 3 row(s) affected
values(1,1000,1),(2,1000,1),(3,1000,2); Records: 3 Duplicates: 0
Warnings: 0
OUTPUT
Action Message
insert into orders values(5,1000,3); Error Code: 1452. Cannot add or update a
child row: a foreign key constraint fails
(`db2`.`orders`, CONSTRAINT
`orders_ibfk_1` FOREIGN KEY (`P_Id`)
REFERENCES `persons` (`p_id`))
Τι συμπέρασμα βγάζετε;
13
7. Ο περιορισμός DEFAULT
Ο περιορισμός DEFAULT εφαρμόζεται σε μία στήλη του πίνακα και ορίζει μία
προεπιλεγμένη τιμή για τη στήλη. Η δήλωση insert into μπορεί να αλλάξει αυτήν την
τιμή ή να την αφήσει αμετάβλητη.
Ακολουθεί παράδειγμα.
CREATE TABLE dept
(
D_Id int NOT NULL,
department varchar(90) DEFAULT 'Development',
primary key(d_id)
);
Εισαγωγή δεδομένων
insert into dept(d_id, department) values(1,'Marketing');
OUTPUT
Action Message
insert into dept(d_id, department) 1 row(s) affected
values(1,'Marketing')
Action Message
insert into dept(d_id) values(2) 1 row(s) affected
d_Id Department
1 Marketing
2 Development
Τι συμπέρασμα βγάζετε;
14
8. Ο περιορισμός AUTO_INCREMENT (στο προϊόν mySQL)
Ακολουθεί παράδειγμα.
Project varchar(255),
);
Εισαγωγή δεδομένων
insert into project(p_id, Project) values(1,'OTE');
OUTPUT
Action Message
insert into project(p_id, Project) 1 row(s) affected
values(1,'OTE');
OUTPUT
Action Message
insert into project(Project) 1 row(s) affected
values('TEI');
d_Id Department
1 OTE
2 TEI
Τι συμπέρασμα βγάζετε;
15
Δείτε και το παρακάτω παράδειγμα
d_Id department
1 OTE
2 TEI
100 Web Site
Τι συμπέρασμα βγάζετε;
9. Ο περιορισμός Check
Η απάντηση είναι αρνητική μέχρι σήμερα για τις τρέχουσες versions του προιόντος!
Αποδείξτε το με παραδείγματα!
16
Άσκηση
Καταγράψτε στον παρακάτω πίνακα τα συμπεράσματά σας:
Ο περιορισμός Unique σε
στήλη ή στήλες του
πίνακα
Ο περιορισμός Primary
Key
Ο περιορισμός Foreign
Key
Ο περιορισμός DEFAULT
Ο περιορισμός
AUTO_INCREMENT
Ο περιορισμός Check
17
10. Ανασκόπηση των όψεων (VIEW)
Όταν περιλαμβάνει
18
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 3: Διαφορές στην υλοποίηση στην περίπτωση των προϊόντων mySQL και
Oracle. Δημιουργία βάσης δεδομένων. Διαχείριση περιορισμών. Δημιουργία
μοντέλου.
Στόχος του τρίτου εργαστηρίου είναι η επισήμανση των διαφορών στην υλοποίηση
με χρήση των προϊόντων mySQL και Oracle. Το εργαστήριο εστιάζει στις διαφορές
αυτές. Μετά την επεξεργασία του εργαστηρίου ο ενδιαφερόμενος θα έχει
επαναλάβει τα εξής σημαντικά θέματα στα δύο προϊόντα:
- Δημιουργία βάσης δεδομένων
- Διαχείριση περιορισμών
- Διαχείριση ερωτημάτων (queries)
Θα γίνει χρήση δύο παραδειγμάτων: διαχείρισης προσωπικού, διαχείρισης
αμερικανικών εκλογών.
Επιπλέον θα γίνει δημιουργία μοντέλου στα δύο παραδείγματα. Τέλος, ο
ενδιαφερόμενος θα εμπεδώσει διαφορές στην υλοποίηση στην περίπτωση των
προϊόντων mySQL και Oracle.
2
1. Θέμα πρώτο: Διαχείριση βάσης δεδομένων προσωπικού
USE new_personnel;
PRIMARY KEY(DEPTNO));
3
HIREDATE DATE, MGR INT(4), SAL FLOAT(7,2), COMM FLOAT(7,2),
SHOW TABLES;
4
Άσκηση 1
Να υλοποιήσετε τη βάση δεδομένων με χρήση του προϊόντος Oracle. Στη συνέχεια
να κάνετε τα παρακάτω και για τις δύο υλοποιήσεις (Oracle, mySQL):
- Να καταργήσετε τους πίνακες. Να ορίσετε τους πίνακες χωρίς κύρια και ξένα
κλειδιά. Να προσθέσετε περιορισμούς (δείτε Εργαστήριο δεύτερο). Να
εισάγετε τις γραμμές των πινάκων.
Άσκηση 2
Δημιουργήστε το μοντέλο κατά προτίμηση με το εργαλείο mySQL Workbennch.
Άσκηση 3
Αναφέρατε διαφορές για την υλοποίηση στα δύο προϊόντα.
5
2. Θέμα δεύτερο: Διαχείριση βάσης δεδομένων αμερικανικών
εκλογών
Η αναγραφή NULL σε μια θέση του πίνακα σημαίνει ότι το αντίστοιχο πεδίο δεν έχει
τιμή.
6
Γράφουμε περιορισμούς (constraints):
Year χαρακτηρίζει μοναδικά την εκλογική αναμέτρηση
Ο νικητής, ανήκει ισόβια ως υποψήφιος στο ίδιο κόμμα και ξεκινά από
την ίδια πολιτεία.
Στη συνέχεια παραθέτουμε τους τέσσερις (4) πίνακες στους οποίους επιμερίζονται
τα στοιχεία των εκλογών.
PRESIDENTS
7
LOSERS
LOSER L_PARTY
STEVENSON DEM
NIXON REP
GOLDWATER REP
HUMPHREY DEM
WALLACE IND
McGOVERN DEM
FORD DEM
CARTER DEM
ANDERSON IND
MONDALE DEM
DOUKAKIS DEM
BUSH REP
PERAULT IND
ELECTIONWINNER
8
ELECTIONLOSER
1952 STEVENSON 89
1956 STEVENSON 73
1964 GOLDWATER 52
1968 WALLACE 46
1972 McGOVERN 17
1980 CARTER 49
1980 ANDERSON 0
1984 MONDALE 13
1988 DOUKAKIS 41
l_party VARCHAR2(15));
9
- Υλοποίηση
Θα δημιουργήσουμε τέσσερα (4) αρχεία (scripts) που θα περιλαμβάνουν SQL
εντολές:
l_party VARCHAR2(15));
SQL> @CREATE.SQL
10
Εισαγωγή στοιχείων στους πίνακες
/* Εντολές εισαγωγής στοιχείων */
………
/* τέλος εντολών */
SQL> @INSERT.SQL
Αναζητήσεις (queries)
SELECT winner,w_party,w_state
FROM presidents
κ.λπ.
11
Για να εκτελέσουμε το πρόγραμμα πληκτρολογούμε την παρακάτω
εντολή.
SQL> @SELECT.SQL
Διαγραφή πινάκων
/* Εντολές διαγραφής πινάκων */
/* τέλος εντολών */
SQL> @DROP.SQL
Αναζήτηση στοιχείων
/* Δείξτε όλα τα στοιχεία προέδρων */
SELECT *
FROM presidents;
FROM presidents;
12
/* Δείξτε τα ονόματα των προέδρων από τον πίνακα electionwinner μία φορά */
FROM electionwinner;
SELECT *
FROM presidents
/* Δείξτε όλα τα στοιχεία προέδρων που ανήκουν στο κόμμα των ρεπουμπλικάνων
*/
SELECT *
FROM presidents
/* Δείξτε όλα τα στοιχεία προέδρων που ανήκουν στο κόμμα των ρεπουμπλικάνων
με άλλη σειρά */
FROM presidents
FROM presidents
SELECT winner,w_party,w_state
13
FROM presidents
/* τι θα δείξουν οι αναζητήσεις; */
FROM presidents
FROM presidents
FROM presidents
SELECT winner,w_party,w_state
FROM presidents
FROM presidents
14
/* Δείξτε υποψήφιους που έχασαν με ψήφους λιγότερους των 80 */
FROM electionloser
/* Δείξτε υποψήφιους που έχασαν στις εκλογές πάνω απο μία φορά */
FROM electionloser
GROUP BY loser
/* Δείξτε όλα τα στοιχεία των εκλογών για κάθε έτος εκλογικής αναμέτρησης */
w_party, w_votes,
order by electionwinner.election_year;
15
Άσκηση 1
Να υλοποιήσετε τη βάση δεδομένων με χρήση του προϊόντος mySQL. Στη συνέχεια
να κάνετε τα παρακάτω και για τις δύο υλοποιήσεις (Oracle, mySQL):
- Να καταργήσετε τους πίνακες. Να ορίσετε τους πίνακες χωρίς κύρια και ξένα
κλειδιά. Να προσθέσετε περιορισμούς (δείτε Εργαστήριο δεύτερο). Να
εισάγετε τις γραμμές των πινάκων.
Άσκηση 2
Δημιουργήστε το μοντέλο κατά προτίμηση με το εργαλείο mySQL Workbennch.
Άσκηση 3
Αναφέρατε διαφορές για την υλοποίηση στα δύο προϊόντα.
16
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 4: Δημιουργία βάσης δεδομένων και διαχείριση της βάσης με χρήση
εναυσμάτων (triggers). Διαφορές στην υλοποίηση στην περίπτωση των προϊόντων
mySQL και Oracle.
Στόχος του τέταρτου εργαστηρίου είναι η κατανόηση της τεχνολογίας διαχείριση της
βάσης με χρήση triggers. Μετά την επεξεργασία του εργαστηρίου ο
ενδιαφερόμενος θα έχει κατανοήσει και θα έχει εμπεδώσει τον τρόπο χρήσης
αντιπροσωπευτικών triggers για τις εμπορικές εφαρμογές.
Τέλος, ο ενδιαφερόμενος θα εμπεδώσει διαφορές στην υλοποίηση στην περίπτωση
των προϊόντων mySQL και Oracle. Επιπλέον, μάθει πως βλέπουμε πληροφορίες για
τη βάση δεδομένων, τους triggers κ.λπ. στο προϊόν της mySQL
2
1. Υλοποίηση Βάσης με τη χρήση του προϊόντος SQL
3
DROP TABLE IF EXISTS orderlines;
CREATE TABLE orderlines(orderno INT, stockno INT, qty INT NOT NULL,
ptotal DECIMAL(5,2), PRIMARY KEY (orderno, stockno));
SHOW TABLES;
DESCRIBE customers;
DESCRIBE stocks;
DESCRIBE orders;
DESCRIBE orderlines;
Ο trigger orders_trig είναι αποθηκευμένος (stored) και εκτελείται πριν από την
εισαγωγή των γραμμών του πίνακα orders. Εισάγει αυτόματα την ημερομηνία και
ώρα της νέας παραγγελίας.
4
FOR EACH ROW
SET NEW.odate = NOW();
5
Ακολουθούν δοκιμές.
INSERT INTO customers(custno, cname, loc) VALUES(1, 'SMITH', 'ATHENS');
INSERT INTO customers(custno, cname, loc) VALUES(2, 'JONES', 'VOLOS');
INSERT INTO customers(custno, cname, loc) VALUES(3, 'BATES', 'NEW YORK');
Βλέπουμε τα στοιχεία.
SELECT * FROM customers;
SELECT * FROM stocks;
SELECT * FROM orders;
SELECT * FROM orderlines;
6
Άσκηση
Να υλοποιήσετε triggers χρησιμοποιώντας το προϊόν της Oracle. Επισημάνετε
διαφορές με το προϊόν της mySQL.
7
Κάποια στοιχεία για τους triggers που ορίσαμε
8
Ξαναγυρίζουμε στη βάση που δημιουργήσαμε και βλέπουμε τους triggers
Use myorders;
Select * from information_schema.triggers\G
9
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 5: Χρήση stored procedures: cursors, functions, procedures, triggers
2
1. Δημιουργία βάσης δεδομένων training
Lecturer
Course
Course_id course_name
Άσκηση
USE training;
3
Εισαγωγή στοιχείων
FROM lecturer;
4
3. Ορισμός συνάρτησης για τη διαχείριση Cursor
- Declare variables
- DECLARE CONTINUE HANDLER
- Open Cursor
- Fetch Cursor
- Close Cursor
DELIMITER //
CREATE FUNCTION lecturer_list() RETURNS VARCHAR(255)
BEGIN
DECLARE record_not_found INTEGER DEFAULT 0;
DECLARE lecturer_name_var VARCHAR(150) DEFAULT "";
DECLARE lecturer_surname_var VARCHAR(150) DEFAULT "";
DECLARE lect_list VARCHAR(255) DEFAULT "";
DECLARE my_cursor CURSOR FOR SELECT lecturer_name, lecturer_surname
FROM lecturer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET record_not_found =
5
1; OPEN my_cursor;
allLecturers: LOOP
FETCH my_cursor INTO lecturer_name_var, lecturer_surname_var;
IF record_not_found THEN
LEAVE allLecturers;
END IF;
SET lect_list = CONCAT(lect_list, lecturer_surname_var, ", ");
END LOOP allLecturers;
CLOSE my_cursor;
RETURN SUBSTR(lect_list, 1, 70);
END //
DELIMITER ;
SELECT lecturer_list();
6
Κατάργηση της συνάρτησης
FROM lecturer;
7
Πως ορίζεται η βάση δεδομένων, οι πίνακές της.
USE training;
DELIMITER //
Begin
end;
//
DELIMITER ;
8
Εισαγωγή στοιχείων. Επηρεάζεται από τον trigger
FROM lecturer;
9
Δείτε τις τιμές της στήλης course_name
FROM lecturer;
10
6. Ορισμός trigger για τη διαχείριση τιμής στήλης
(course_name)
USE training;
DELIMITER //
begin
end;
//
DELIMITER ;
11
Select * From COURSE;
Να το αποτέλεσμα της εκτέλεσης του trigger κατά την εισαγωγή στοιχείων στον
πίνακα lecturer
FROM lecturer;
12
7. Δοκιμή ορισμού δύο (2) εναυσμάτων (triggers) με την ίδια
συνθήκη ενεργοποίησης
USE training;
DELIMITER //
Begin
end;
//
DELIMITER ;
DELIMITER //
begin
13
select course_name into dnamev from course where course_id = new.course_id;
end;
//
DELIMITER ;
FROM lecturer;
14
8. Πως θα διορθώσουμε το πρόβλημα που προέκυψε κατά τη
δοκιμή ορισμού δύο (2) triggers με την ίδια συνθήκη
ενεργοποίησης
USE training;
DELIMITER //
Begin
15
end;
//
DELIMITER ;
Να τι βλέπουμε
FROM lecturer;
16
9. Ορισμός trigger για την αυτόματη εισαγωγή στοιχείων σε
πίνακα audit
USE training;
DELIMITER //
begin
end;
//
DELIMITER ;
17
SELECT lecturer_surname, lecturer_name, salary, course_id, course_name
FROM lecturer;
18
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 6: Διαχείριση δοσοληψιών στο προϊόν mySQL
2
1. Διαχείριση δοσοληψιών στο προϊόν mySQL
3
Να πως ξεκινάμε και εκτελούμε transaction
START TRANSACTION;
INSERT INTO T (id, s) VALUES (4, 'fourth');
SELECT * FROM T ;
ROLLBACK;
SELECT * FROM T;
4
INSERT INTO T (id, s) VALUES (5, 'fifth');
ROLLBACK;
SELECT * FROM T;
SET AUTOCOMMIT=0;
5
Είναι γνωστές οι εντολές της Data Definition Language (DDL): “CREATE
TABLE…”, “CREATE INDEX…”, “DROP TABLE …” κ.λ.π.
Είναι γνωστές επίσης οι εντολές της Data Manipulation Language (DML): “SELECT
FROM…”, “INSERT INTO…”, “DELETE FROM…”. Επηρεάζουν αυτές οι εντολές
την εντολή ROLLBACK;
6
Τι συμπέρασμα βγάλατε;
Να κάνετε έλεγχο αν ένα σφάλμα (error) σε εντολή SQL οδηγεί ή όχι σε αυτόματο
ROLLBACK στο προϊόν της MySQL. Εκτελέστε τις εντολές στη συνέχεια.
7
INSERT INTO T (id, s) VALUES (2, 'Error test starts here');
-- division by zero should fail
SELECT (1/0) AS dummy FROM DUAL;
-- Now update a non-existing row
UPDATE T SET s = 'foo' WHERE id = 9999 ;
-- and delete an non-existing row
DELETE FROM T WHERE id = 7777 ;
--
INSERT INTO T (id, s) VALUES (2, 'Hi, I am a duplicate');
INSERT INTO T (id, s)
VALUES (3, 'How about inserting too long of a string value?');
INSERT INTO T (id, s, si) VALUES (4, 'Smallint overflow for 32769?', 32769);
INSERT INTO T (id, s) VALUES (5, 'Transaction still active?');
SELECT * FROM T;
COMMIT;
DELETE FROM T WHERE id > 1;
SELECT * FROM T;
8
COMMIT;
ΠΡΟΣΟΧΉ! Η τιμή σφάλματος “23000” είναι η τιμή του SQLSTATE που ορίζεται
στο standard και η τιμή 1062 είναι η τιμή του αντίστοιχου κώδικα σφάλματος του
προϊόντος της MySQL. Συνδέεται με παραβίαση περιορισμού κύριου κλειδιού
(violation of the primary key constraint).
9
Δοκιμάστε SQL transaction για τη μεταφορά 500 euros από το λογαριασμό 101 σε
ανύπαρκτο λογαριασμό πχ στον acctID=777:
UPDATE Accounts SET balance = balance - 500 WHERE acctID = 101;
UPDATE Accounts SET balance = balance + 500 WHERE acctID = 777;
SELECT * FROM Accounts ;
ROLLBACK;
10
SQL Transaction: Unit of Recovery
Ανοίξτε ένα νέο terminal window (νέα MySQL session) και δείτε τι έγινε.
USE TestDB;
SET AUTOCOMMIT=0;
SELECT * FROM T;
COMMIT;
11
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 7: Διαχείριση δοσοληψιών στο προϊόν mySQL – Επίπεδα απομόνωσης
(Transactions – Isolation levels)
2
1. Διαχείριση δοσοληψιών στο προϊόν mySQL – Επίπεδα
απομόνωσης (Transactions – Isolation levels)
use TestDB;
USE TestDB;
);
COMMIT;
3
1.1 Θέμα 1: Προσομοίωση «Τυφλής αντικατάστασης» (Blind
Overwriting)
Σημείωση:
Στο βήμα 4 θυμηθείτε ότι το χρονικό όριο της προκαθορισμένης κλειδαριάς στο
προϊόν της MySQL (MySQL’s default lock timeout) είναι 90 seconds. Επομένως, η
συναλλαγή Α - transaction (client)- πρέπει να προχωρήσει χωρίς καθυστέρηση στο
βήμα 5 αμέσως μετά το βήμα 4 της συναλλαγής Β.
1 SET AUTOCOMMIT=0;
READ COMMITTED;
-- amount to be transfered by A
FROM Accounts
4
SELECT @balanceA;
2 SET AUTOCOMMIT=0;
READ COMMITTED;
-- amount to be transfered by B
SELECT @balanceB;
3 UPDATE Accounts
4 UPDATE Accounts
FROM Accounts
COMMIT;
5
SELECT acctID, balance
FROM Accounts
COMMIT;
6
1.2 Θέμα 2: Επανάλαβε το Θέμα 1 χρησιμοποιώντας απευθείας
“sensitive updates” χωρίς να χρησιμοποιήσεις τοπικές
μεταβλητές -using “sensitive updates” in SELECT-UPDATE
scenarios without local variables-
COMMIT WORK;
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT=0;
SERIALIZABLE;
2 USE TestDB;
SET AUTOCOMMIT=0;
SERIALIZABLE;
7
SELECT balance FROM Accounts
3 UPDATE Accounts
4 UPDATE Accounts
FROM Accounts
COMMIT;
FROM Accounts
COMMIT;
Session A
8
Session B
USE TestDB;
);
COMMIT;
9
εναλλακτικά
COMMIT WORK;
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT=0;
-- amount to be transfered by A
FROM Accounts
SELECT @balanceA;
10
2 USE TestDB;
SET AUTOCOMMIT=0;
-- amount to be transfered by B
SELECT @balanceB;
3 UPDATE Accounts
4 UPDATE Accounts
FROM Accounts
COMMIT;
FROM Accounts
COMMIT;
11
12
1.4 Θέμα 4: Επανάληψη με χρήση isolation level REPEATABLE READ.
USE TestDB;
);
COMMIT;
εναλλακτικά
COMMIT WORK;
13
Repeating exercise, but now using isolation level REPEATABLE READ.
St Session A Session B
ep
1 USE TestDB;
SET AUTOCOMMIT=0;
-- amount to be transfered by A
FROM Accounts
SELECT @balanceA;
2 USE TestDB;
SET AUTOCOMMIT=0;
REPEATABLE READ;
-- amount to be transfered by B
14
SET @amountB = 500;
SELECT @balanceB;
3 UPDATE Accounts
4 UPDATE Accounts
15
5 SELECT acctID, balance
FROM Accounts
COMMIT;
FROM Accounts
COMMIT;
16
1.5 Θέμα 5: Ανταγωνισμός σε δύο “resources” με διαφορετική σειρά
COMMIT WORK;
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT=0;
READ COMMITTED;
UPDATE Accounts
2 USE TestDB;
SET AUTOCOMMIT=0;
READ COMMITTED;
UPDATE Accounts
17
3 UPDATE Accounts
4 UPDATE Accounts
5 COMMIT;
FROM Accounts
COMMIT;
FROM Accounts
Session A
18
Session B
Το Επίπεδο απομόνωσης δεν παίζει κάποιο ρόλο σε αυτό το σενάριο, αλλά είναι μια
καλή πρακτική ο καθορισμός επίπεδου απομόνωσης στην αρχή κάθε συναλλαγής!
COMMIT WORK;
19
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT = 0;
REPEATABLE READ;
UPDATE Accounts
UPDATE Accounts
2 USE TestDB;
SET AUTOCOMMIT = 0;
READ UNCOMMITTED;
COMMIT WORK;
3 ROLLBACK;
COMMIT;
20
Dirty read problem
Session A
Session B
21
Questions
COMMIT WORK;
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT = 0;
READ COMMITTED;
SELECT *
FROM Accounts
2 USE TestDB;
SET AUTOCOMMIT = 0;
22
REPEATABLE READ;
COMMIT WORK;
SELECT *
FROM Accounts
COMMIT;
Session A
23
Session B
Άσκηση
Τι θα συμβεί αν θέσουμε στην transaction A το επίπεδο απομόνωσης (isolation
level) ίσο με REPEATABLE READ;
24
1.8 Θέμα 8: Απόπειρα εμφάνισης insert phantom
COMMIT WORK;
St Session A Session B
e
p
1 USE TestDB;
SET AUTOCOMMIT = 0;
REPEATABLE READ ;
3 USE TestDB;
SET AUTOCOMMIT = 0;
READ COMMITTED;
VALUES (303,3000);
COMMIT;
25
SELECT * FROM Accounts
COMMIT;
Ερωτήσεις
26
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 8: Εισαγωγή στο σχεδιασμό ιστοσελίδων
2
1. Ιστοσελίδες και web sites
Έχετε αναρωτηθεί ποτέ πώς είναι δυνατό να βλέπουμε ιστοσελίδες στο internet; Με
ποιο τρόπο υλοποιείται η διαδικασία αυτή; Για να απαντήσουμε σε αυτό το
ερώτημα πρέπει να εξηγήσουμε πρώτα κάποιες έννοιες.
Τι είναι η ιστοσελίδα;
Η ιστοσελίδα (web page) είναι ένα απλό αρχείο κειμένου (text file). Μπορεί να
είναι μόνο καθαρό κείμενο ASCII. Συνήθως όμως το κείμενο που γράφουμε σε μια
ιστοσελίδα θέλουμε να είναι πιο σύνθετο, με χρώματα, background, bullets κ.τ.λ.
Για το λόγο αυτό, είναι δομημένο σε συγκεκριμένη μορφή, η οποία καθορίζεται από
μια γλώσσα, γνωστή ως HTML (HyperText Markup Language). Με την HTML
περιγράφουμε πώς θα μορφοποιηθεί το κείμενο ώστε να το εμφανίσει ο web
browser στη μορφή που θέλουμε. Κάθε ιστοσελίδα είναι ένα αρχείο που έχει
κατάληξη .html ή .htm.
Γιατί όμως πρέπει να γράφουμε ιστοσελίδες σε HTML και όχι σε απλό κείμενο; Αν
θέλουμε να εμφανίζεται στην ιστοσελίδα μας απλά ένα κείμενο μη μορφοποιημένο,
τότε δε χρειάζεται να γράψουμε HTML. Κάντε το εξής παράδειγμα:
3
Παράδειγμα 1:
Δημιουργήστε ένα αρχείο test.txt με το notepad. Γράψτε το
παρακάτω κείμενο:
Αποθηκεύστε το κείμενο και σώστε το ως test.html. Κάντε δυο κλικ και ανοίξτε το με
τον web browser σας. Όπως βλέπετε, έχετε φτιάξει την πρώτη σας ιστοσελίδα. Το
κείμενο που γράψατε εμφανίζεται ως σελίδα στον browser.
Παράδειγμα 2:
Γράψτε το εξής κείμενο στο notepad και αποθηκεύστε το ως
test3.html:
<HTML>
<BODY>
<I>Hello, this is my first web page !!!</I>
</BODY>
</HTML>
Ανοίξτε το με το web browser σας. Τώρα εμφανίζεται αυτό που θέλουμε. Με τον
παραπάνω τρόπο γράψαμε ένα κείμενο ώστε να είναι κατανοητή η μορφοποίηση
από τον web browser. Φυσικά η HTML είναι πιο περίπλοκη και παρέχει διάφορες
δυνατότητες, τις οποίες μπορείτε να τις δείτε ανοίγοντας μια ιστοσελίδα στο
internet. Περισσότερα για την HTML θα πούμε σε επόμενη ενότητα.
4
Ένα web site είναι ένα σύνολο από ιστοσελίδες και άλλα αρχεία,
αποθηκευμένα στο σκληρό δίσκο ενός μηχανήματος που συνδέεται σε
δίκτυο, και είναι ορατά από τους χρήστες που συνδέονται στο ίδιο δίκτυο.
Πώς όμως ένα web site είναι ορατό στους τερματικούς υπολογιστές των χρηστών
που συνδέονται στο internet;
Αν δηλαδή κάποιος φτιάξει τρεις σελίδες HTML, τις αποθηκεύσει στο σκληρό δίσκο
του και μπει στο internet, οι υπόλοιποι θα μπορούν να τις προσπελάσουν; Όχι
βέβαια. Η προσπέλαση των web sites γίνεται με τη βοήθεια ειδικών εφαρμογών
που ονομάζονται HTTP servers ή web servers.
2. Web servers
Ένας HTTP server ή web server, χρησιμεύει για να παρέχει τις ιστοσελίδες ενός web
site στους browsers των χρηστών, όταν αυτοί ζητούν να τις δουν. Οι ιστοσελίδες
είναι αποθηκευμένες στο σκληρό δίσκο ενός μηχανήματος που παίζει το ρόλο του
server.
Πολλοί νομίζουν ότι ο web server είναι ένα μηχάνημα σε μέγεθος ντουλάπας, με
500 επεξεργαστές. Στην πραγματικότητα ο web server είναι ένα μικρό
«προγραμματάκι» που τρέχει σαν service σε έναν υπολογιστή. Πολλές φορές ως
web server εννοούμε τον υπολογιστή που τρέχει αυτό το «προγραμματάκι».
Υπάρχουν πολλοί διαθέσιμοι web servers. Οι πιο γνωστοί είναι ο Apache web
server (open source), ο IIS της Microsoft, Glassfish,...
Εγκαθιστώντας τα NetBeans θα εγκατασταθεί και ο Glassfish
5
Δεξί κλικ>Start
Από τη στιγμή που ο Glassfish τρέχει, ο υπολογιστής σας έχει γίνει ένας web server.
Δηλαδή μπορείτε να γράψετε εφαρμογές web (σελίδες html, web sites, portals) και
οι χρήστες να συνδέονται στον υπολογιστή σας από τον browser και να βλέπουν
σελίδες web (εφόσον ο υπολογιστής είναι συνδεδεμένος στο internet).
Δημιουργήστε έναν καινούριο project:
1. File> New Project
2. Java Web> Web Application
3. Next {Project Name: WebApplication1 } > Next
4. Finish
Μέσα στο project WebApplication1 και το φάκελο Web Pages θα βάζετε τις Web
σελίδες, images, pdf,…
Κατ’ αυτόν τον τρόπο βάλτε το αρχείο test3.html που φτιάξατε μέσα στο φάκελο
Web Pages.
6
Αν όλα πήγαν καλά, στο browser σας θα έχει εμφανιστεί το περιεχόμενο του
αρχείου σας.
http://localhost:8080/WebApplication1/test3.html
Αντιγράψτε αυτά τα αρχεία μέσα στο φάκελο Web Pages και γράψτε στον browser
τις εξής διευθύνσεις:
http://localhost:8080/myDir/myzip.zip
http://localhost:8080/myDir/myexe.exe
Αν όλα πήγαν καλά, και στις δυο περιπτώσεις θα σας ζητηθεί να κατεβάσετε το
αρχείο, όπως θα σας ζητούσε ένα site στο internet.
Δυο παράμετροι χαρακτηρίζουν τα στοιχεία ενός server (είτε αυτός είναι web/HTTP
server, είτε database server, είτε ftp server, είτε mail server...):
• Η διεύθυνση IP του μηχανήματος στο οποίο είναι εγκατεστημένος ο web
server.
7
• H πόρτα (port) της υπηρεσίας που αντιπροσωπεύει ο server (HTTP, FTP,
email, database).
Η πρώτη παράμετρος (IP) είναι μια διεύθυνση ξεχωριστή για κάθε υπολογιστή
συνδεδεμένο στο internet (η κατάσταση είναι λίγο πιο περίπλοκη, αλλά ας έχουμε
αυτό στο νου μας). Η διεύθυνση αυτή αποτελείται από τέσσερα bytes, δηλαδή
τέσσερις αριθμούς από 1 ως 255. Σε δεκαδική μορφή η διεύθυνση IP γράφεται ως
Α.Β.C.D, για παράδειγμα 192.168.69.17 ή 10.0.0.11 ή 172.16.5.254.
Η δεύτερη παράμετρος (PORT) είναι ένας αριθμός που χρησιμεύει για τον εξής
σκοπό: Σκεφτείτε ότι σε έναν υπολογιστή (ο οποίος συνήθως έχει μόνο μια
διεύθυνση IP) τρέχουν δυο servers: Ο tomcat για HTTP1 και η MySQL για database.
Αν η μόνη παράμετρος που είχαμε ήταν η διεύθυνση IP του υπολογιστή, πώς θα
ξεχωρίζαμε σε ποιον server θα συνδεθούμε; Έχοντας όμως ως παράμετρο την
πόρτα, μπορούμε να ξεχωρίσουμε και το server στον οποίο θα συνδεθούμε. Έτσι,
δεδομένου ότι η port του tomcat είναι η 8080 ενώ η port της MySQL είναι η 3306,
μπορούμε να ξεχωρίσουμε σε ποιον server θα συνδεθούμε.
Για να συνδεθούμε σε έναν web server μέσω του browser μας γράφουμε την
ακόλουθη διεύθυνση:
http://ServerIP:ServerPort
Για παράδειγμα:
http://192.168.1.2:8080
Γράφοντας στην αρχή της διεύθυνσης http://, ο browser καταλαβαίνει ότι ζητάμε να
δούμε ιστοσελίδες και η επικοινωνία θα γίνει μέσω του πρωτοκόλλου HTTP.
Ας σημειώσουμε βέβαια εδώ ότι ο αριθμός 8080 της πόρτας που χαρακτηρίζει τον
Glassfish / tomcat, μπορεί να αλλάξει, με παραμετροποίηση του configuration του
Glassfish/tomcat. Αυτό δε θα μας απασχολήσει στο εργαστήριο και θα θεωρήσουμε
ότι η πόρτα που χαρακτηρίζει τον Glassfish/tomcat είναι η 8080.
Πόσες φορές έχετε επισκεφτεί ένα site στο internet και γράψατε τη διεύθυνση IP
του server που το φιλοξενεί; Σχεδόν καμία. Τις περισσότερες φορές επισκέπτεστε
ένα site γράφοντας το όνομά του. Αυτό γίνεται μέσω της υπηρεσίας DNS (Domain
Name Service). Όταν θέλουμε να φτιάξουμε έναν web server και να τον κάνουμε
διαθέσιμο στο internet για να φιλοξενήσει κάποιο site, επικοινωνούμε με κάποια
αρμόδια αρχή ή εταιρία η οποία αναλαμβάνει δυο πράγματα:
• Να δώσει ένα όνομα στο server που θα φιλοξενεί το site μας.
8
• Να αντιστοιχίζει τη διεύθυνση ΙΡ του server μας με το όνομα που του
δώσαμε.
Έτσι, για παράδειγμα, ο web server που φιλοξενεί το eclass έχει όνομα
eclass.cs.teiath.gr και διεύθυνση IP 195.130.109.27. Η αντιστοίχιση των ονομάτων
των servers σε διευθύνσεις IP γίνεται μέσω της υπηρεσίας DNS, που είναι ένα
πρωτόκολλο που μεταφράζει τις διευθύνσεις IP των υπολογιστών σε ονόματα και το
αντίστροφο. Για την επιτέλεση αυτής της διαδικασίας, υπάρχουν servers στο
internet οι οποίοι έχουν καταχωρημένα τα ονόματα και τις διευθύνσεις IP των
διαφόρων υπολογιστών. Οι servers αυτοί, που είναι υπολογιστές που τρέχουν
ασταμάτητα, ονομάζονται DNS servers. Συνήθως κάθε δίκτυο έχει και το δικό του
DNS server που μεταφράζει τα ονόματα των υπολογιστών στους οποίους ζητείται
πρόσβαση σε διευθύνσεις IP. Για να γίνει αυτό καλύτερα αντιληπτό, κάντε το εξής
παράδειγμα:
nslookup eclass.cs.teiath.gr
Οι δυο πρώτες γραμμές δείχνουν το όνομα και τη διεύθυνση IP του DNS server που
έκανε τη μετάφραση. Οι δυο τελευταίες δείχνουν τη διεύθυνση ΙΡ για το όνομα του
site που ζητήσαμε.
Κάντε το ίδιο και για τα sites www.cs.teiath.gr και www.teiath.gr.
Από το παραπάνω είναι προφανές ότι δε χρειάζεται απαραίτητα να έχει το site μας
ένα όνομα. Μπορούν οι χρήστες να το προσπελάσουν και μέσω της διεύθυνσης IP,
αν φυσικά την ξέρουν. Είναι όμως προφανής και η ευχρηστία που παρέχει ένα
αντιπροσωπευτικό όνομα για κάθε site…
Πόρισμα: Για να τεστάρουμε τις εφαρμογές web που έχουμε φτιάξει, συνδεόμαστε
από το μηχάνημά μας, χρησιμοποιώντας ως διεύθυνση ΙΡ τη localhost ή 127.0.0.1.
9
H port 80
Έχετε γράψει πολλές φορές το όνομα του port στη διεύθυνση ενός web site που
επισκέπτεστε; Μάλλον όχι. Με βάση όσα είπαμε σε προηγούμενη ενότητα, πώς
ξεχωρίζει ο browser σε ποια πόρτα θα συνδεθεί; Αυτό γίνεται μέσω μιας συμφωνίας
που έγινε μεταξύ web browsers και web servers, ορίζοντας μια κοινή πόρτα, την
port με νούμερο 80. Αυτό που συμφωνήθηκε είναι το εξής: Αν είναι επιθυμητό να
γίνεται προσπέλαση ενός site χωρίς να γράφεται ο αριθμός του port στη διεύθυνση
ΙΡ, τότε θα πρέπει να τηρούνται τα εξής:
• Ο web server που θα φιλοξενεί το site θα πρέπει να ακούει στην port 80.
Έτσι, για παράδειγμα στον tomcat, θα πρέπει να αλλάξουμε το
configuration, ώστε να τον προσπελαύνουμε μέσω της port 80, αντί της
8080.
• Οι web browsers θα πρέπει να είναι έτσι φτιαγμένοι ώστε, αν ο χρήστης δεν
πληκτρολογήσει το όνομα της πόρτας μετά τη διεύθυνση IP, τότε η σύνδεση
να γίνει στην port 80.Τα δυο παραπάνω τηρούνται σήμερα και από τις δυο
πλευρές, για ευκολία των χρηστών. Αυτό δε σημαίνει φυσικά ότι δε
μπορούμε να φτιάξουμε έναν web server σε διαφορετική πόρτα. Αρκεί
αυτοί που θα συνδεθούν να ξέρουν το νούμερό της. Για το σκοπό του
εργαστηρίου, δε θα αλλάξουμε το configuration του tomcat και θα
συνδεόμαστε στην default port 8080 που παρέχει, γράφοντάς τη στη
γραμμή διευθύνσεων του web browser μας.
Αν γράψουμε τη διεύθυνση IP του server (μαζί με την port) και στη συνέχεια
γράψουμε τη διαδρομή για ένα αρχείο (directory\subdirectory\file.html) ο server θα
λάβει τη συγκεκριμένη αίτηση, θα ψάξει στον κατάλογο του project για να βρει το
αρχείο file.html και θα εμφανίσει την πληροφορία του στο browser. Φυσικά, αν το
αρχείο αυτό δεν υπάρχει, ή αν το path directory\subdirectory είναι λάθος, τότε o
server θα απαντήσει ότι δε μπορεί να βρει το συγκεκριμένο αρχείο στους
καταλόγους του.
Πόρισμα: Αν φτιάξουμε έναν κατάλογο μέσα στο project και τον φάκλεο Web
Pages, τότε όλα τα αρχεία αυτού του καταλόγου θα μπορούμε να τα
προσπελάσουμε από έναν web browser.
11
κάθε αρχείο ή ιστοσελίδα που απαρτίζει ένα web site. Η συγκεκριμένη αυτή
διεύθυνση ονομάζεται URL (Universal Resource Locator). Αποτελείται από τρία
χαρακτηριστικά:
• Τη διεύθυνση IP και την πόρτα του server στον οποίο ανήκει το αρχείο αυτό.
• Τη διαδρομή του αρχείου στο server.
• Το όνομα του αρχείου.
Παράδειγμα URL.1: Έχουμε το αρχείο myFile.html που βρίσκεται μέσα στο project
(myDir) και τον φάκελο Web Pages
Η διεύθυνση ΙΡ του μηχανήματος που τρέχει ο Glassfish είναι η 192.168.1.2. Τότε το
URL του συγκεκριμένου αρχείου είναι:
http:// 192.168.1.2:8080/myDir/myFile.html
Ξεκινήστε τον Glassfish/tomcat αν δεν τρέχει ήδη. Φτιάξτε δυο καταλόγους dir1 και
dir2. Φτιάξτε το αρχείο file1.html και αποθηκεύστε το στον κατάλογο dir1:
<HTML>
<BODY>
You are now in HEAVEN.
<a href="http://localhost:8080/
WebApplication1/dir2/file2.html">GO TO HELL</a>
</BODY>
</HTML>
<HTML>
<BODY>
You are now in HELL.
<a href="
http://localhost:8080/WebApplication1/dir1/file1.html">GO
TO HEAVEN</a>
</BODY>
</HTML>
Γράψτε το URL του πρώτου ή του δεύτερου αρχείου στο browser σας, π.χ.:
http://localhost:8080/WebApplication1/dir1/file1.html
Ακολουθήστε τα links στα αρχεία. Παρατηρήστε ότι τα URLs των αρχείων που
βρίσκεστε φαίνονται στη γραμμή διευθύνσεων του browser. Παρατηρήστε επίσης
ότι τα URL των links φαίνονται στο status bar όταν ακουμπάτε το ποντίκι πάνω.
Τα links δημιουργούνται με τη βοήθεια εντολών HTML. Μπορεί να είναι απόλυτα
(absolute links) ή σχετικά (relative links):
12
Τα absolute links παρέχουν όλο το URL της σελίδας που δείχνουν. Χρησιμοποιούνται
συνήθως για σελίδες που δεν ανήκουν στον ίδιο web server. Absolute links είναι
όλα αυτά που είδαμε παραπάνω.
Τα relative links παρέχουν μόνο το URL που έχει σχέση με τη διαδρομή του
καταλόγου στο σκληρό δίσκο του server. Χρησιμοποιούνται συνήθως για σελίδες
που ανήκουν στον ίδιο web server. Για να καταλάβετε καλύτερα την έννοια των
absolute links κάντε το εξής:
Στα αρχεία file1.html και file2.html που φτιάξατε παραπάνω, αντικαταστήστε την
τέταρτη γραμμή με τις εξής, αντίστοιχα:
<a href="../dir1/file1.html">GO TO HELL</a>
<a href="../dir2/file2.html">GO TO HEAVEN</a>
Παρατηρήστε ότι η εφαρμογή δουλεύει. Εδώ αφαιρέσαμε εντελώς το τμήμα που
δηλώνει τη διεύθυνση του server, αφού και οι δυο σελίδες βρίσκονται στο ίδιο
μηχάνημα. Δηλώσαμε τα links με βάση την τοποθεσία των σελίδων στο σκληρό
δίσκο. Προσοχή όμως, υποθέτουμε ότι ανήκουν στο ίδιο project
Βρείτε ένα αρχείο .exe και αντιγράψτε το στον κατάλογο dir1 που φτιάξατε πριν.
Μετονομάστε το σε setup.exe. Βρείτε ένα αρχείο .pdf και αντιγράψτε το στον
κατάλογο dir1 που φτιάξατε πριν. Μετονομάστε το σε readme.pdf.
http://localhost:8080/WebApplication1/dir1/MyApplication.html
Προσοχή στα κεφαλαία και στα μικρά γράμματα. Τα URL είναι case sensitive.
http://localhost:8080/WebApplication1/Dir1/MyApplication.html
http://localhost:8080/WebApplication1/dir1/myapplication.html
13
Έχοντας υπόψη τα παραπάνω, γίνεται αντιληπτό ότι, όταν σχεδιάζουμε ένα site, δεν
παραπέμπουμε το χρήστη να πληκτρολογεί ξεχωριστά το URL της κάθε ιστοσελίδας
που θέλει να επισκεφτεί, αλλά φτιάχνουμε links σε συγκεκριμένες ιστοσελίδες οι
οποίες τον παραπέμπουν στη συνέχεια στις υπόλοιπες ιστοσελίδες και αρχεία που
θέλει να επισκεφτεί. Και πάλι όμως, ποτέ δεν πληκτρολογούμε το όνομα κάποιου
αρχείου στο browser όταν θέλουμε να επισκεφτούμε ένα site. Πληκτρολογούμε το
URL του site μόνο. Ο τρόπος με τον οποίο γίνεται αυτό εξηγείται στην επόμενη
ενότητα.
Για τους παραπάνω λόγους, κάθε web server παρέχει έναν τρόπο ώστε, όταν ο
χρήστης πληκτρολογήσει το URL ενός site, χωρίς κατάληξη στο τέλος, τότε
φορτώνεται ένα προκαθορισμένο αρχείο.
Ειδικά για τον tomcat υπάρχει η εξής πολιτική: Αν, μέσα στον κατάλογο του site που
φτιάξαμε βάλουμε ένα αρχείο με όνομα index.html, το συγκεκριμένο αρχείο είναι
αυτό που θα εμφανιστεί στο χρήστη αν αυτός πληκτρολογήσει στον browser του
μόνο τη διεύθυνση του site, χωρίς το όνομα κάποιου αρχείου στο τέλος. Για να
γίνει πιο καλά αντιληπτό αυτό, κάντε το εξής παράδειγμα:
14
εξής tags: <html> και <html>. Ο τίτλος της σελίδας (που εμφανίζεται στην κορυφή
του παραθύρου του browser) περικλείεται ανάμεσα στα tags <title> και </title>.
Τα δυο αυτά tags με τη σειρά τους περικλείονται ανάμεσα στα tags <head> και
</head>. Έτσι, μια απλή σελίδα είναι η ακόλουθη:
<html>
<head>
<title>Test page</title>
</head>
<body>
This is a test web page with simple HTML tags.
</body>
</html>
Αντιγράψτε τον κώδικα στο αρχείο simple.html και ανοίξτε το με έναν web
browser.
Γενικά tags
Κάποια άλλα επιπλέον χρήσιμα tags είναι τα ακόλουθα:
15
Tags για hyperlink
Το tag που χρησιμοποιούμε για να φτιάξουμε ένα hyperlink είναι το εξής:
<a href="filename.html">Go to file</a>
Προσθέστε την παραπάνω γραμμή πάνω από το tag </body> του αρχείου που
φτιάξατε πριν. Ανοίξτε το νέο αρχείο στο browser για να δείτε το link που φτιάξατε.
Κάντε κλικ στο link. Δε θα δουλέψει διότι το αρχείο filename.html δεν υπάρχει.
16
Τα στοιχεία που φτιάχνουμε μέσα σε μια φόρμα μπορούμε να τα στοιχίσουμε όπως
ακριβώς θα στοιχίζαμε ένα κείμενο, χρησιμοποιώντας τα γενικά tags που είδαμε
παραπάνω. Για να καταλάβετε την έννοια της φόρμας αντιγράψτε τον παρακάτω
κώδικα σε ένα αρχείο και ονομάστε το form.html.
<html>
<head>
<title>Simple Forms</title>
</head>
<body>
These are two simple forms.<p><p>
This is the first form with horizontal alignment.<p>
<form name="form1" method="post" action="register1.html">
<p>Username: <input type="text" name="username1">
Password: <input type="text" name="password1">
<input type="submit" value="Register 1">
</form>
<p><p>
Πρέπει να πούμε ότι η HTML χρησιμοποιείται σήμερα κατά κόρο. Βέβαια, η εύκολη
σύνταξή της έχει επιτρέψει την ανάπτυξη προγραμμάτων που γράφουν αυτόματα
HTML. Τέτοια προγράμματα είναι το MS Front Page και το Macromedia
Dreamweaver. Ακόμη και το MS Word γράφει σελίδες HTML.
Γράψτε ένα κείμενο, μορφοποιήστε το όπως θέλετε και σώστε το σαν αρχείο HTML
(επιλέξτε save as και στο type επιλέξτε .html). Ανοίξτε το αρχείο με έναν browser.
Θα δείτε ότι φαίνεται το κείμενο που φτιάξατε σε μορφή ιστοσελίδας. Παρ’ όλ’
αυτά, μην προσπαθήσετε να καταλάβετε τον κώδικα HTML που έγραψε το Word,
διότι τα γράφει με τον δικό του, ιδιαίτερο τρόπο.
Απ’ όλα τα παραπάνω γίνεται κατανοητό ότι σχεδόν κανένας σχεδιαστής σελίδων
σήμερα δε γράφει καθαρή HTML μόνος του. Οι περισσότεροι χρησιμοποιούν
προγράμματα όπως τα παραπάνω. Φυσικά, η γνώση της HTML είναι απαραίτητη για
το σχεδιασμό μιας καλής ιστοσελίδας, είτε γράφουμε τον κώδικα μόνοι μας, είτε
μέσω κάποιου προγράμματος.
17
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 9: Στατικές και δυναμικές σελίδες (JSP)
2
1. Στατικές και δυναμικές σελίδες (JSP)
Μέχρι στιγμής είδαμε σελίδες HTML με τις οποίες μπορούμε να γράφουμε κείμενο
και να το μορφοποιούμε όπως εμείς θέλουμε. Το κείμενο όμως που θα εμφανίζει η
ιστοσελίδα μας δεν αλλάζει. Παραμένει πάντα το ίδιο. Τέτοιο κείμενο λέγεται
στατικό και μια ιστοσελίδα που έχει στατικό κείμενο ονομάζεται στατική ιστοσελίδα
(static web page).
Πώς όμως θα φτιάξουμε μια ιστοσελίδα που κάνει την παραπάνω δουλειά;
Ιστοσελίδες που εμφανίζουν στατικό αλλά και δυναμικό κείμενο ονομάζονται
δυναμικές ιστοσελίδες. Η εργασία αυτή δε μπορεί να γίνει μόνο με HTML.
Χρειάζεται να ενσωματώσουμε και κάποια άλλη τεχνολογία για να γράφουμε
δυναμικό κείμενο. Ο πιο διαδεδομένος τρόπος σήμερα για να γράφουμε δυναμικό
κείμενο σε ιστοσελίδες είναι οι script γλώσσες προγραμματισμού ASP (Active Server
Pages), JSP (Java Server Pages) και PHP (Hypertext PreProcessor). Οι παραπάνω
script γλώσσες μας παρέχουν τον τρόπο να γράφουμε δυναμικό κείμενο και,
γενικότερα, να επιτελούμε κάποιες διεργασίες που θα μπορούσαμε να εκτελέσουμε
με γλώσσες προγραμματισμού. Έτσι, μπορούμε να γράψουμε και να διαβάσουμε
από αρχεία, να ορίσουμε και να μεταβάλλουμε μεταβλητές, να εμφανίσουμε την
τιμή μεταβλητών σε ιστοσελίδες (αντίστοιχα, στις γλώσσες προγραμματισμού θα
εμφανίζαμε την τιμή τους στην οθόνη ή σε ένα παράθυρο, αν επρόκειτο για visual
γλώσσες), να συνδεθούμε σε βάσεις δεδομένων κ.α.
Ερώτηση: Μπορεί ένα αρχείο που έχει μόνο κώδικα HTML να έχει κατάληξη .jsp;
Απάντηση: ΝΑΙ. Αφού είπαμε ότι ένα αρχείο JSP έχει κώδικα HTML και JSP. Αν δεν
έχει κώδικα JSP παραμένει ακόμη ένα αρχείο JSP, αφού η HTML είναι αναφαίρετο
κομμάτι της γλώσσας JSP. Ένα παράδειγμα JSP είναι το ακόλουθο:
3
Άσκηση 1
<HTML>
<BODY>
<% int x = 3; %>
Hello! The value of the variable x is: <%= x %>.<p>
<% x=x+3; %>
The value of the variable x is changed: <%= x %>.
</BODY>
</HTML>
Στο παραπάνω αρχείο, ορίσαμε μια μεταβλητή x. Ο ορισμός έγινε με κώδικα Java,
που περικλείεται ανάμεσα σε ειδικά σύμβολα που ονομάζονται tags. (<% και %>).
Γράφουμε κώδικα HTML και, στο σημείο που θέλουμε να εμφανίσουμε την τιμή της
μεταβλητής, γράφουμε τη μεταβλητή και την περικλείουμε στα tags <%= και %>. Το
υπόλοιπο μέρος του κώδικα καταλαβαίνετε προφανώς τι κάνει. Όπως βλέπουμε,
τον κώδικα Java τον διαχωρίζουμε από τον κώδικα HTML μέσω ειδικών tags. Ο
ρόλος των tags είναι για να καταλαβαίνει ο compiler ότι δεν πρόκειται για κείμενο
HTML, αλλά για κώδικα Java. Ο κώδικας JSP δεν περιορίζεται σε tags που
εσωκλείουν κώδικα Java. Υπάρχουν πάρα πολλά διαφορετικά tags που τα
χρησιμοποιούμε για να κάνουμε συγκεκριμένες διεργασίες. Στην παρούσα ενότητα
θα δούμε μόνο δυο απλά tags.
Βρείτε ένα αρχείο .html που έχετε φτιάξει. Κάντε διπλό κλικ πάνω του για να ανοίξει
με έναν browser. Έχετε κάποιο πρόβλημα να το δείτε; Μάλλον όχι.
4
web server, αλλά πρέπει να εγκαταστήσουμε και έναν web container. Οι
περισσότεροι μεγάλοι application servers έρχονται σήμερα με ενσωματωμένο web
container (π.χ. Inspire, iPlanet, WebSphere). Υπάρχουν ωστόσο plugins που
εγκαθιστούν web containers σε υπάρχοντες web servers ώστε να τρέχουν τα JSP
(π.χ. JRun, ServletExec). O πιο διαδεδομένος web container είναι ο Apache Tomcat,
o οποίος είναι open source και έχει ενσωματωμένο και web server. Τον Tomcat, ως
γνωστό, τον έχετε ήδη εγκαταστήσει στον υπολογιστή σας.
Ένα τμήμα κώδικα Java που περικλείεται μέσα σε ένα αρχείο JSP ονομάζεται
scriptlet. To scriptlet το περικλείουμε ανάμεσα σε scriptlet tags (<% και %>) ως εξής:
html code
<% Java code %>
html code
Html
text <%= paramName %>
text
html
Άσκηση 2
Ακολουθεί ένα παράδειγμα που εμφανίζει την ημερομηνία.
5
κώδικα HTML και, στο σημείο που θέλουμε να μας εμφανίσει την ημερομηνία
παρεμβάλλουμε expression tags όπου εσωκλείουμε τη μεταβλητή που ορίσαμε πιο
πριν.
Άσκηση 3
Ας δούμε ένα πιο σύνθετο παράδειγμα. Αντιγράψτε τον παρακάτω κώδικα σε ένα
αρχείο και ονομάστε το game.jsp. Δημιουργείστε το project baseis_x. Δείτε το
αποτέλεσμα στο web browser πληκτρολογώντας το κατάλληλο URL. Κάντε reload τη
σελίδα για επανάληψη.
<%
int dice1 = (int)(6*Math.random()+1);
int dice2 = (int)(6*Math.random()+1);
String answer;
if( dice1==dice2 )
answer ="Congradulations. You won!!!";
else
answer = "You are GADEMIS. Please try again...";
%>
<html>
<body>
Let's play <p>
You scored <%= dice1 %> and <%= dice2 %>.<p>
The System says: <%= answer %>
</body>
</html>
Το παραπάνω αρχείο JSP ενσωματώνει ένα κομμάτι κώδικα Java (scriptlet) που
παράγει δυο τυχαίους αριθμούς (dice1 και dice2, καθώς και ένα string (answer), με
βάση το αποτέλεσμα. Στη συνέχεια, με κώδικα HTML και με το expression tag <%=,
φτιάχνουμε το περιεχόμενο της ιστοσελίδας, εμφανίζοντας τα αποτελέσματα στο
χρήστη.
Έχετε υπόψη ότι μπορούμε να γράψουμε τον κώδικα Java οπουδήποτε μέσα στο
αρχείο. Αρκεί να τον ενσωματώνουμε στα scriptlet tags. Για παράδειγμα, στο
παραπάνω, αρχείο θα μπορούσαμε να σπάσουμε τον κώδικα Java σε δυο scriptlets
όπως παρακάτω, και να τα αναμείξουμε με τον κώδικα HTML:
Άσκηση 3.1
<%
int dice1 = (int)(6*Math.random()+1);
int dice2 = (int)(6*Math.random()+1);
String answer;
%>
<html>
<body>
<%
if( dice1==dice2 )
6
answer ="Congradulations. You won!!!";
else
answer = "You are GADEMIS. Please try again...";
%>
Let's play <p>
You scored <%= dice1 %> and <%= dice2 %>.<p>
The System says: <%= answer %>
</body>
</html>
Μέσω των επαναληπτικών βρόχων που προσφέρει η Java (while, for, do-while)
μπορούμε να εμφανίσουμε επαναληπτικά κείμενο HTML στο browser. Η φιλοσοφία
είναι απλή, αρκεί να καταλάβουμε το παρακάτω παράδειγμα. Δημιουργείστε το
αρχείο loop.jsp και δείτε το αποτέλεσμα στον browser.
Άσκηση 4
<body>
LOOP EXAMPLE:<p>
<%
for (int i=1; i<=5; i++)
{
%>
Loop executed <%= i %> times.<br>
<%
}
%>
</body>
</html>
Όπως βλέπετε, γράψαμε ένα scriptlet όπου ορίζουμε την αρχή του βρόχου. Μέσα
στο scriptlet γράφουμε κώδικα HTML (και αν θέλουμε κάποια JSP tags, όπως το
expression tag που γράψαμε παραπάνω). Κλείνουμε το βρόχο γράφοντας ένα
scriptlet που περιέχει μόνο το άγκιστρο ( } ) που κλείνει το βρόχο. Το κείμενο HTML
που περικλείεται μέσα στο βρόχο θα εκτελεστεί όσες φορές γίνει η επανάληψη.
Προσοχή στη χρήση των scriptlet tags. Η αρχή του βρόχου for είναι ένα κομμάτι
κώδικα Java, οπότε τον περικλείουμε στα tags <% και %>. Το κείμενο HTML που
γράφουμε στο browser και βρίσκεται μέσα στο βρόχο δεν είναι κώδικας Java, οπότε
δεν το περικλείουμε σε scriptlet tags. Ο βρόχος όμως δεν έκλεισε. Μας μένει ένα
άγκιστρο. Ακόμη όμως κι αυτό το αγκιστράκι είναι από μόνο του ένα κομμάτι
κώδικα Java, οπότε πρέπει να το περικλείσουμε σε tags.
7
Τρόπος ανάπτυξης αρχείων JSP
Γενικότερα, η πιο απλή φιλοσοφία για την ανάπτυξη (υλοποίηση) αρχείων JSP είναι
η
εξής:
• Γράφουμε μια στατική σελίδα HTML η οποία θα είναι η δυναμική σελίδα που
θέλουμε να φτιάξουμε, απλά το δυναμικό κομμάτι του κειμένου θα έχει κάποιες
ενδεικτικές τιμές στις παραμέτρους. Στο παραπάνω παράδειγμα στην αρχική
στατική σελίδα που φτιάξαμε, βάλαμε κάποιες ενδεικτικές τιμές για τα χρώματα και
το μέγεθος της γραμματοσειράς. Η παραπάνω διαδικασία είναι εξαιρετικά εύκολη,
αν αναλογιστούμε την πληθώρα προγραμμάτων που γράφουν HTML.
• Αποθηκεύουμε την παραπάνω σελίδα με κατάληξη jsp.
• Προσθέτουμε το τμήμα της προγραμματιστικής λογικής (κώδικας java ή κάτι άλλο,
όπως θα δούμε παρακάτω).
• Αντικαθιστούμε τα δυναμικά μέρη του κειμένου (που, προς το παρόν,
εμφανίζονται στατικά) με τις παραμέτρους των οποίων η τιμή θέλουμε να
εμφανίζεται.
Άσκηση 5
<html>
<font size="+2">
With dynamic pages you can have different color on each visit
!!! <p>
</font>
</body>
</html>
8
Ο παραπάνω κώδικας απλά θέτει το background και το text color σε γκρι και μαύρο
αντίστοιχα (υπάρχουν συγκεκριμένοι κωδικοί όπως βλέπετε στη γραμμή 2), αυξάνει
το φόντο κατά το διπλάσιο του default και γράφει ένα απλό μήνυμα. Πώς μπορούμε
να έχουμε διαφορετικό background color, text color και font size κάθε φορά που
φορτώνουμε την ιστοσελίδα; Αρκεί να ορίζονται δυναμικά τρεις τιμές: Η #CCCCCC
που ορίζει το bgcolor, η #000000 που ορίζει το text color και ο αριθμός 2 που ορίζει
το μέγεθος της γραμματοσειράς. Τις τρεις αυτές τιμές πρέπει να τις παράγουμε
τυχαία. Ιδού ο τρόπος. Τροποποιήστε το αρχείο που φτιάξατε πριν όπως παρακάτω
και δείτε το αποτέλεσμα στο browser, κάνοντας refresh τη σελίδα.
<%
String textColor = Integer.toHexString((int)(16777215*Math.random()));
String backgrColor = Integer.toHexString((int)(16777215*Math.random()));
int fontSize = ((int)(4*Math.random()+1));
%>
<html>
<body bgcolor=<%= backgrColor%> text=<%= textColor%>>
<font size="+<%= fontSize%>">
With dynamic pages you can have different color on each visit !!! <p>
You can also have different font size!!!
</font>
</body>
</html>
Μέχρι στιγμής είδαμε αρχεία JSP που παράγουν δυναμικό κείμενο HTML στο
browser, με βάση κάποιες τυχαίες μεταβλητές ή με κάποιο επαναληπτικό βρόχο.
Στην πλειονότητα των περιπτώσεων όμως, η χρησιμότητα των JSP και, κατ’
επέκταση, των δυναμικών σελίδων, έγκειται στο ότι μπορούν να παράγουν
δυναμικό κείμενο, με βάση πληροφορία που δίνει ο χρήστης. Για παράδειγμα, σε
9
ιστοσελίδες για καταστήματα υπολογιστών, ο χρήστης έχει τη δυνατότητα να δει
όλα τα μοντέλα μιας
συγκεκριμένης μάρκας μόνο, ή όλα τα μοντέλα με συγκεκριμένο τύπο επεξεργαστή.
Ένα αρχείο JSP που θα κληθεί από την ανωτέρω φόρμα το οποίο θα κάνει τα
ακόλουθα:
Έχουμε ήδη δει πώς φτιάχνουμε μια φόρμα και πώς καλούμε ένα άλλο αρχείο (σε
μορφή link), όταν πατηθεί το κουμπί submit της φόρμας. Το πιο βασικό που πρέπει
να θυμόμαστε είναι το εξής:
Στον ορισμό της φόρμας δηλώνουμε και το αρχείο που θα φορτωθεί μόλις πατηθεί
το κουμπί της. Το αρχείο αυτό θα πάρει τις παραμέτρους που έδωσε ο χρήστης.
Η δήλωση αυτή γίνεται ως εξής:
<form name="formName" method="post" action="file.jsp">
10
Όπως βλέπουμε, ο ρόλος του JSP είναι τριπλός. Παίρνει τις παραμέτρους από το
αρχείο HTML, επιτελεί το προγραμματιστικό έργο μέσω Java και παράγει το κείμενο
που θα εμφανιστεί στο browser μέσω HTML.
Το παρακάτω παράδειγμα παίρνει τις τιμές που έδωσε ο χρήστης σε μια φόρμα και
τις εμφανίζει στο browser.
Άσκηση 6
Αντιγράψτε τον παρακάτω κώδικα σε ένα αρχείο, ονομάστε το yourself.html.
<html>
<body>
Tell me about yourself...<p>
<form name="yourself" method="post"
action="yourself.jsp">
What is your name?: <input type="text"
name="yourName"><p>
How old are you?: <input type="text" name="yourAge"><p>
Where are you from?: <input type="text"
name="yourCity"><p>
What is your favorite pet?: <input type="text"
name="yourPet"><p>
May I have your email?: <input type="text"
name="yourEmail"><p>
<input type="submit" value="Thank you!">
</form>
</body>
</html>
11
Αντιγράψτε τώρα τον παρακάτω κώδικα σε ένα αρχείο yourself.jsp και αποθηκεύστε
το στον ίδιο φάκελο.
<%
String userName = request.getParameter("yourName");
String userAge = request.getParameter("yourAge");
String userCity = request.getParameter("yourCity");
String userPet = request.getParameter("yourPet");
String userEmail = request.getParameter("yourEmail");
%>
<html>
<body>
This is what I learned from you:<p>
Your name is <%=userName%>.<p>
You are <%=userAge%> years old.<p>
You are from <%=userCity%>.<p>
Your favorite pet is <%=userPet%>.<p>
I can find you in the following address: <%=userEmail%>.<p>
Have a nice day!!!<p>
<a href="yourself.html">Go Back</a>
</body>
</html>
Το αρχείο yourself.html έχει μια φόρμα με 5 text boxes καθένα από τα οποία
δέχεται τιμή για μια παράμετρο: yourName, yourAge, yourCity, yourPet, yourEmail.
Μόλις πατηθεί το κουμπί “Thank You” θα φορτωθεί το αρχείο yourself.jsp.
Στο αρχείο yourself.jsp γίνονται τα εξής: Αρχικά παίρνουμε τις τιμές από τις
παραμέτρους της φόρμας και τις καταχωρούμε σε τοπικές μεταβλητές: userName,
userAge, userCit, userPet, userEmail. Η φόρμα δε μας απασχολεί πλέον καθόλου.
Δουλεύουμε με τις μεταβλητές που έχουμε ορίσει, οι οποίες κρατούν την
πληροφορία του χρήστη. Στη συνέχεια γράφουμε το κείμενο που θα εμφανιστεί
στον browser. Γράφουμε HTML και, όπου χρειάζεται, παρεμβάλλουμε κάποια
μεταβλητή κλεισμένη σε expression tags.
12
Άσκηση 7
Αντιγράψτε τον παρακάτω κώδικα στο αρχείο input.html και αποθηκεύστε το στο
φάκελο baseis_x.
<html>
<body>
What is your sex?<br>
Type 1 for boy or 2 for girl.<p>
<form name="mySelf" method="post" action="respond.jsp">
<input type="text" name="sex">
<input type="submit" value="Continue">
</form>
</body>
</html>
Αντιγράψτε τον παρακάτω κώδικα στο αρχείο respond.jsp και αποθηκεύστε το στο
φάκελο baseis_x.
<%
String userSex = request.getParameter("sex");
String resp;
if(userSex.equals("1")) resp = "Let's talk about cars.";
else if(userSex.equals("2")) resp = "Let's talk about
fashion.";
else resp = "Invalid choice. Try again.";
%>
<html>
<body>
<%= resp%><p>
<a href="input.html">Go Back</a>
</body>
</html>
Στο αρχείο HTML έχουμε μια φόρμα όπου ο χρήστης δίνει τιμή σε μια παράμετρο
sex. Μόλις πατηθεί το κουμπί της φόρμας καλείται το αρχείο respond.jsp. Το αρχείο
JSP παίρνει την τιμή της παραμέτρου που του έδωσε η φόρμα και την καταχωρεί σε
μια δική του μεταβλητή με όνομα userSex. Στη συνέχεια παράγει ένα κείμενο στη
μεταβλητή resp, ανάλογα με την τιμή που έδωσε ο χρήστης. Το κείμενο αυτό είναι
μια πρόταση από το κείμενο που θα εμφανιστεί στο browser. Στη συνέχεια
γράφουμε το κείμενο HTML που θα εμφανιστεί στο browser, το οποίο φυσικά
εξαρτάται από την τιμή της μεταβλητής resp.
13
Πέρασμα πληροφορίας σε αρχείο JSP μέσω URL
Πολλές φορές είναι επιθυμητό να περνάμε τις παραμέτρους σε ένα αρχείο JSP μέσω
του URL του, χωρίς να τις έχει δώσει ο χρήστης σε φόρμα. Τέτοιες περιπτώσεις
έχουμε όταν ένα αρχείο JSP ή HTML έχει πάρει ήδη κάποιες παραμέτρους και θέλει
να τις δώσει σε κάποιο άλλο αρχείο JSP. Αυτό γίνεται εύκολα, αν ορίσουμε το όνομα
και την τιμή των παραμέτρων αυτών στο URL του αρχείου JSP που θα τις πάρει. Η
μορφή του URL του αρχείου JSP που θα πάρει τις παραμέτρους θα έχει τότε την
εξής μορφή:
http://server_IP:port/path/file.jsp?param1=value1¶m2=value2
Για να γίνει το παραπάνω πιο αντιληπτό, γράψτε στο browser το εξής URL:
http://localhost:8080/baseis_x/respond.jsp?sex=1
Άσκηση 7.1
Αντιγράψτε τον παρακάτω κώδικα σε ένα αρχείο, ονομάστε το input2.html.
<html>
<body>
What is your sex?<p>
<a href="respond.jsp?sex=1" > Boy </a><br>
<a href="respond.jsp?sex=2" > Girl </a><br>
</body>
</html>
Παρατηρήστε ότι έχουμε ακριβώς το ίδιο αποτέλεσμα όπως και στο προηγούμενο
παράδειγμα. Παρατηρήστε επίσης ότι τώρα, μόλις φορτώνεται το αρχείο JSP
φαίνονται και οι παράμετροι που δώσαμε.
Το παραπάνω αρχείο HTML απλά δημιουργεί δυο hyperlinks στο αρχείο JSP,
περνώντας διαφορετική τιμή για την παράμετρο sex κάθε φορά. Δεν έχουμε γράψει
όλο το path του URL (absolute path) αλλά μόνο το όνομα του αρχείου (relative path)
αφού τα δυο αρχεία βρίσκονται στον ίδιο server.
ΠΡΟΣΟΧΗ: Έχετε υπόψη κάτι σημαντικό. Δεν περικλείουμε τις τιμές των
παραμέτρων σε quotes, τις αφήνουμε όπως είναι. Ακόμη και για τα strings. Αν ένα
string έχει και κενά, τότε τα κενά τα αντικαθιστούμε με το σύμβολο ‘ % ’.
Τώρα μπορούμε να καταλάβουμε γιατί όταν σε κάποια sites κάνουμε κλικ σε ένα
link, προκύπτει στο browser ένα URL με μήκος κάποιων χιλιομέτρων και με διάφορα
σύμβολα όπως ‘ ? ‘, ‘ = ‘, ‘ % ‘ κ.α.
14
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 10: Σύνδεση με Βάση Δεδομένων MySql
Στόχος του εργαστηρίου είναι η εξοικείωση με το JDBC API το οποίο μας παρέχει τη
δυνατότητα να διαχειριστούμε μια βάση δεδομένων χρησιμοποιώντας εντολές Java.
Μετά την επεξεργασία του εργαστηρίου ο ενδιαφερόμενος θα είναι σε θέση να
δημιουργήσει μια εφαρμογή διαχείρισης των δεδομένων μιας βάσης κάνοντας
χρήση εντολών jsp.
2
1. Εισαγωγή
Το JDBC API
Η μια μας παρέχει τις απαραίτητες κλάσεις και μεθόδους ώστε να μπορούμε
να συνδεθούμε στη συγκεκριμένη βάση δεδομένων. Η συγκεκριμένη ομάδα
βιβλιοθηκών είναι ξεχωριστή για κάθε βάση δεδομένων (π.χ. Oracle, MySQL,
Access) και παρέχεται από τον εκάστοτε κατασκευαστή της βάσης. Είναι
γνωστή ως JDBC driver.
Στο παρόν κεφάλαιο θα εμβαθύνουμε στις ειδικές συναρτήσεις που μας παρέχει η
Java για να γράφουμε εντολές SQL. Συγκεκριμένα, θα ασχοληθούμε με την εντολή
myStatement.methodName(sqlString) και με τους διάφορους τρόπους που μας
παρέχει για να διαχειριζόμαστε πληροφορία από βάση δεδομένων.
3
2. Σύνδεση στη βάση δεδομένων MySQL μέσω Java
Για να συνδεθούμε στη βάση δεδομένων MySQL και να γράψουμε εντολές SQL
απαιτούνται οι εξής ενέργειες:
O JDBC driver για MySQL παρέχεται στη σελίδα της MySQL. Είναι ένα μικρό αρχείο
jar με όνομα mysql-connector-java- 5.1.13 -bin.jar ή mysql.jar(e-class). Το αρχείο
αυτό πρέπει να το βάλουμε στους καταλόγους jre_Home/lib/ext και
jdk_Home/jre/lib/ext ή να το δηλώσουμε στην εφαρμογής μας libraries>δεξί κλικ>
Add Jar/Folder και επιλέγουμε το αρχείο mysql-connector-java- 5.1.13 -bin.jar ή
mysql.jar
import java.sql.*;
4
Φόρτωμα του JDBC driver
Το φόρτωμα του JDBC driver γίνεται φορτώνοντας την κλάση Driver από το
Class.forName(“ClassName”);
Class.forName(“com.mysql.jdbc.Driver”);
Παρατηρήστε ότι γράψαμε ολόκληρο το path της κλάσης Driver, καθώς αυτή
περιέχεται σε package. Θα μπορούσαμε να γράψουμε μόνο το όνομα της κλάσης,
αλλά να είχαμε πριν συμπεριλάβει το αντίστοιχο package στο πρόγραμμά μας,
μέσω της εντολής
import com.mysql.jdbc
“jdbc:mysql://ServerName:ServerPort/DatabaseName?user=myUsername&passwor
d=myPassword";
5
ServerName είναι το όνομα ή η διεύθυνση ΙΡ του database server.
String testDatabase =
“jdbc:mysql://localhost:3306/mydb1?user=teiath&password=aigaleo";
6
Εγγραφή και εκτέλεση SQL statements
myStatement.methodName(sqlString);
Για την εντολή insert που γράψαμε παραπάνω, η μέθοδος θα είχε ως εξής:
myStatement.executeUpdate(sqlString);
myStatement.executeQuery(sqlString);
Τις διάφορες μεθόδους των αντικειμένων τύπου Connection για να εκτελούμε SQL
statements θα τις δούμε αναλυτικά σε επόμενα κεφάλαια.
Αφού έχουμε τελειώσει με την εκτέλεση των SQL statements πρέπει να κλείσουμε
το αντικείμενο εγγραφής SQL statements. Αυτό γίνεται απλά με την εντολή
myStatement.close();
7
Κλείσιμο της σύνδεσης
myConnection.close();
myStatement.methodName(sqlString);
όπου myStatement είναι ένα αντικείμενο τύπου Statement και methodName είναι
μια από τις πολλές μεθόδους που παρέχει η κλάση Statement. Θα ασχοληθούμε
λίγο παραπάνω με τις διάφορες μορφές της μεθόδου methodName.
Όπως είδαμε στο προηγούμενο μάθημα, για να κάνουμε εισαγωγή δεδομένων στη
myStatement.executeUpdate(sqlString);
εντολής:
myStatement.executeUpdate(sqlString);
8
Ανανέωση δεδομένων (update statement)
εντολής:
myStatement.executeUpdate(sqlString);
εντολής:
ResultSet rs = myStatement.executeQuery(sqlString);
9
Το rs (ως αντικείμενο της κλάσης ResultSet) μας παρέχει μεθόδους για να
επεξεργαζόμαστε τις εγγραφές που τραβήξαμε από τη βάση δεδομένων. Οι πιο
σημαντικές μέθοδοι ναφέρονται παρακάτω:
Για να πάρουμε τώρα πληροφορία που είναι καταχωρημένη στο αντικείμενο rs,
10
Άσκηση1. Παράδειγμα χρήσης embedded select statement.
Θα δούμε ένα τυπικό παράδειγμα χρήσης της executeQuery, καθώς και του τρόπου
που χρησιμοποιούμε τις διάφορες μεθόδους της κλάσης ResultSet.
mysql –u root
use mydb1
ID Int
Name Text
describe myTable
11
Δημιουργείστε ένα αρχείο test.jsp και γράψτε τον παρακάτω κώδικα:
<%
int j=0;
Class.forName("com.mysql.jdbc.Driver");
ResultSet rs=myStatement.executeQuery(sqlString);
while(rs.next()){
m[j]=rs.getInt("id");
s[j]=rs.getString("name");
j++;
myStatement.close();
myConnection.close();
12
out.println(i+"___"+m[i]+"<br>");
out.println(i+"___"+s[i]+"<br>");
%>
2. Στις παραμέτρους αυτές θα καταχωρήσουμε τις τιμές των δυο πεδίων του
πίνακα mytable1.
7. Μέχρι στιγμής έχουμε καταφέρει όλο τον πίνακα να τον καταχωρήσουμε στο
αντικείμενο rs. Μένει να πάρουμε τα στοιχεία του rs. Αυτό γίνεται με έναν
βρόχο while.
13
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 11: Σύνδεση Οντολογιών με Βάσεις Δεδομένων
2
1. Σύνδεση Οντολογιών με Βάσεις Δεδομένων
3
1) Αποφασίστε ποια δεδομένα θα διαχειρισθείτε. Δώστε παραδείγματα των
δεδομένων αυτών. Χρησιμοποιήστε τα παραδείγματά μας και εμπλουτίστε.
2) Γράψτε σύντομα τι είναι το ISSN.
3) Σχεδιάστε τη βάση σας και υλοποιήστε χρησιμοποιώντας mySQL και Oracle
Express.
4) Να χρησιμοποιήσετε το εργαλείο mySQL Workbench για να δημιουργήσετε
αυτόματα το μοντέλο οντοτήτων συσχετίσεων από τους πίνακες της βάσης.
Δείτε το ίδιο διάγραμμα σε UML κ.λπ.
5) Δείτε τη δυνατότητα να σχεδιάσετε το μοντέλο και το περιβάλλον mySQL
Workbench να σας δημιουργήσει αυτόματα τους πίνακες (προαιρετικό) σε
παράδειγμα της επιλογής σας.
6) Εισάγετε στοιχεία στους πίνακες και δημιουργήστε εντολές αναζήτησης σε
γλώσσα SQL
7) Γράψτε σύντομα τι είναι οντολογία και που χρησιμοποιείται, τι είναι RDF, τι
είναι XML, τι είναι SPARQL
8) Εγκαταστήστε το λογισμικό Protégé και ότι άλλο χρειασθείτε για οπτικοποίηση
της οντολογίας (βλέπε και υποδείξεις παρακάτω)
9) Δημιουργήστε οντολογία βασιζόμενη στους πίνακες που δημιουργήσατε.
10) Γράψτε queries μέσα από το περιβάλλον του Protégé και με SPARQL.
4
Υποδείξεις
5
INSERT INTO author VALUES
(1, 'Petros','Belsis'),
(2, 'Nikitas', 'Karanikolas'),
(3, 'Christos', 'Skourlas'),
(4,'Tasos','Tsolakidis'),
(5,'Dimitris','Vassis');
Import Backup.sql
Για να φορτώσουμε τα δεδομένα ενός αρχείου (script) τύπου Backup.sql, επιλέγουμε
Manage Import / Export .
6
Α. Ανοίγουμε το Workbench. Εμφανίζεται η παρακάτω οθόνη στην οποία επιλέγουμε create
ΕΕR model from existing Database. Εναλλακτικά μπορούμε να βασίσουμε τη δημιουργία σε
script με τις εντολές CREATE TABLE.
7
Γ. Επιλέγουμε το όνομα της βάσης για το οποίο θέλουμε να δημιουργήσουμε το ΕΕR model
8
Χρησιμοποιώντας το μενού του περιβάλλοντος μόλις κατασκευάσουμε το διάγραμμα
μπορούμε να δούμε εναλλακτικά το ίδιο διάγραμμα και με άλλους συμβολισμούς πχ σε
UML
9
SELECT * FROM publications.paper;
10
Γράψτε Queries του τύπου:
«Δείξτε τα επίθετα των συγγραφέων μαζί με τους τίτλους papers, journals στα οποία
συμμετείχαν"
11
1.2 Protégé
12
Επιλέγουμε OWL/RDF Files
13
Για να μπορέσουμε να φορτώσουμε τη βάση από τη mysql αλλά και να εκτελέσουμε κάποια
queries στην οντολογία χρειαζόμαστε 2 επιπλέον tabs. Για να τα εμφανίσουμε επιλέγουμε
OWL> Preferences
14
Στη συνέχεια και αφού έχουμε ολοκληρώσει την προσθήκη των παραπάνω tabs,
επιλέγουμε το tab-DataMaster και συμπληρώνουμε τα αντίστοιχα πεδία. Πατάμε ok και
αριστερά εμφανίζονται τα περιεχόμενα (οι πίνακες) της βάσης publications.
Επιλέγουμε select all tables, import table contents και στην συνέχεια import
15
Για να εκτελέσουμε Queries επιλέγουμε το tab Queries
…….
Για να εκτελέσουμε κάποιο ερώτημα θα πρέπει να επιλέξουμε την κλάση στην οποία θα
εφαρμόσουμε το ερώτημα, το property (slot), τη συνθήκη και τέλος μια τιμή (ένα
δεδομένο).
Επιλέγουμε class.
16
Επιλέγουμε slot
Επιλέγουμε συνθήκη
17
Επιλέγουμε δεδομένο και πατάμε find. Δεξιά εμφανίζονται τα δεδομένα.
Visualisation
Το protege παρέχει τη δυνατότητα να οπτικοποιήσουμε τα περιεχόμενα της οντολογίας.
Προκειμένου να το επιτύχουμε αυτό θα πρέπει να ενεργοποιήσουμε το tab-OWLVizTab
Προσοχή! Μπορεί να εμφανίσει ότι δεν μπορεί να το εκτελέσει. Σε αυτήν την περίπτωση
κατεβάζετε το πρόγραμμα (graphviz) από τον δικτυακό τόπο http://graphviz.org/ και στην
συνέχεια επιλέγετε από τα options το path που είναι εγκατεστημένο το dot.exe του graphviz
18
19
Για να απεικονίσετε την οντολογία επιλέγετε κάποια κλάση, και πατάτε το show classes.
20
Sparql
Στις οντολογίες μπορεί να χρησιμοποιηθεί και η γλώσσα Sparql για να εκτελέσουμε
αναζητήσεις.
Ερώτημα "Δείξτε τα επίθετα και τον κωδικό όλων των συγγραφέων των οποίων ο κωδικός
είναι μεγαλύτερος του 2 και μικρότερος του 4"
21
PREFIX db1: <http://biostorm.stanford.edu/db_table_classes/DSN_jdbc.mysql.//localhost.3306/publications#>
SELECT ?Surname ?d
WHERE
{
?x db1:author.Surname ?Surname.
?x db1:author.A_id ?d
FILTER (
?d > "2"^^xsd:int &&
?d < "4"^^xsd:int
)
}
Στην παρακάτω οθόνη βλέπουμε την εκτέλεση της εντολής και το αποτέλεσμά της.
Βιβλιογραφία-σύνδεσμοι
1. http://www.mysql.com/products/workbench/
2. http://protege.stanford.edu/doc/owl/getting-started.html
3. http://protegewiki.stanford.edu/wiki/Main_Page
22
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 12: Εφαρμογή Android με χρήση Sqlite
2
1. Εφαρμογή Android με χρήση Sqlite
3
3. Finish.
src/
όλα τα Java αρχεία της εφαρμογής μας τα οποία εκτελούν κάποιες
διαδικασίες( stub Activity) .
res/
Σε αυτό τον φάκελο περιέχονται τα resources της εφαρμογής όπως,drawable
files, layout files,string values, κ.α.
Students
Id Integer
Name Text
Surname Text
Email Text
4
Δημιουργούμε τα αντίστοιχα String
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w("HelpDb","Upgrading database from version"+ oldVersion
+ "to" + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE);
onCreate(db);
}
}
Τέλος ακολουθούν οι μέθοδοι διαχείρισης των δεδομένων.
5
initialValues.put("surname", surname);
initialValues.put("email", email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
6
Αφού ολοκληρώσαμε όλες τις μεθόδους διαχείρισης της βάσης, θα
συμπληρώσουμε και το Database.java
Όπως προείπαμε η μέθοδος η οποία είναι υπεύθυνη για την εμφάνιση των
δεδομένων είναι η onCreate οπότε μέσα στην μέθοδο αυτή θα συμπληρώσουμε τις
λειτουργίες που θέλουμε να εκτελεστούν.
//---add 2 titles---
db.open();
db.insertTitle(
"CHRISTOS",
"SKOURLAS",
"CSKOURLAS@TEIATH.GR");
db.insertTitle(
"ANASTASIOS",
"TSOLAKIDIS",
"ATSOLAKID@TEIATH.GR");
db.close();
db.open();
Cursor c = db.getTitle(2);
if (c.moveToFirst())
DisplayTitle(c);
else
Toast.makeText(this, "No title found",
Toast.LENGTH_LONG).show();
db.close();
7
Δημιουργία AVD
4. Create AVD.
5. Εν συνεχεία επιλέγουμε το AVD που έχουμε δημιουργήσει και πατάμε start και
μετά launch
8
Πατώντας DDMS πάνω και δεξιά στο παράθυρο(eclipse)
9
Εάν θέλουμε να δουλέψουμε με την βάση που μόλις δημιουργήσαμε τότε.
1. Τρέχουμε το command line(cmd) θέτοντας ως τρέχων φάκελο τον φάκελο
tools του android-sdk.
2. Γράφουμε adb shell
3. Πηγαίνουμε στο φάκελο του βρίσκετε η βάση μας π.χ για το παράδειγμα που
μόλις φτιάξαμε
Παράρτημα
Database.java
package com.example;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.Toast;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
HelpDb db = new HelpDb(this);
//---add 2 titles---
db.open();
10
db.insertTitle(
"CHRISTOS",
"SKOURLAS",
"CSKOURLAS@TEIATH.GR");
db.insertTitle(
"ANASTASIOS",
"TSOLAKIDIS",
"ATSOLAKID@TEIATH.GR");
db.close();
db.open();
Cursor c = db.getTitle(12);
if (c.moveToFirst())
DisplayTitle(c);
else
Toast.makeText(this, "No title found",
Toast.LENGTH_LONG).show();
db.close();
}
public void DisplayTitle(Cursor c)
{
Toast.makeText(this,
"id: " + c.getString(0) + "\n" +
"NAME: " + c.getString(1) + "\n" +
"SURNAME: " + c.getString(2) + "\n" +
"EMAIL: " + c.getString(3),
Toast.LENGTH_LONG).show();
}
}
HelpDb.java
package com.example;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class HelpDb {
11
private final Context context;
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int
oldVersion,
int newVersion)
{
Log.w("HelpDb", "Upgrading database from version "
+ oldVersion
+ " to "
+ newVersion + ", which will destroy all
old data");
db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE);
onCreate(db);
}
}
12
initialValues.put("name", name);
initialValues.put("surname", surname);
initialValues.put("email", email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
13
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 13: Επισκόπηση της χρήσης του jdbc API
Στόχος του εργαστηρίου είναι η επισκόπηση της χρήσης του jdbc API για τη
δημιουργία εφαρμογών – jsp pages και τη διαχείριση βάσεων δεδομένων. Μετά την
επεξεργασία του εργαστηρίου ο ενδιαφερόμενος θα έχει κατανοήσει τα θέματα
δημιουργίας μιας εφαρμογής jsp pages.
2
1. Επισκόπηση της χρήσης jdbc API
Στο σχήμα (Martii Leiho) προσφέρεται μία οπτική υπενθύμιση για μία σειρά από
σημαντικές κλάσεις, αντικείμενα, μεθόδους (class, objects, methods) του jdbc API
και με τα βέλη περιγράφεται η επικοινωνία / σύνδεσή / διάταξή τους.
String testDatabase =
“jdbc:mysql://localhost:3306/mydb?user=admin&password=1234";
3
Προσοχή! Η παρακάτω εντολή είναι λανθασμένη
String sqlString = "INSERT INTO USERS VALUES ('user1', 'password1')";
Αυτό προϋποθέτει ότι έχουμε ορίσει ένα αντικείμενο testDatabase τύπου string που
«ορίζει» τον driver που χρησιμοποιούμε, το URL, τη βάση μας, username και
password. Άρα θα έχουμε:
String testDatabase =
“jdbc:mysql://localhost:3306/mydb?user=admin&password=1234";
Connection myConnection = DriverManager.getConnection(testDatabase);
myStatement.executeUpdate(sqlString);
Η συγγραφή της SQL δήλωσης γίνεται σε ένα αντικείμενο τύπου string, για
παράδειγμα στο αντικείμενο με όνομα sqlString.
4
('user1', 'password1')";
Έτσι για να εκτελέσουμε μία SQL δήλωση:
Επίσης, παρέχει μία σειρά από μεθόδους κάθε μία από τις οποίες μπορεί να
χρησιμοποιηθεί για να πάρουμε πληροφορία από μια στήλη:
Για να συνδεθούμε στη βάση δεδομένων στην περίπτωση τoυ προϊόντος MySQL και
να γράψουμε δηλώσεις SQL (SQL statements) απαιτούνται οι εξής ενέργειες:
Class.forName(“com.mysql.jdbc.Driver”);
5
// Φορτώνουμε την κλάση Driver από το package com.mysql.jdbc.
String testDatabase =
“jdbc:mysql://localhost:3306/mydb?user=admin&password=1234";
// Ορίζουμε για τη βάση δεδομένων μας (‘εστω ότι την ονομάζουμε mydb) ένα
αντικείμενο testDatabase τύπου συμβολοσειράς (string) της μορφής:
“jdbc:mysql://ServerName:ServerPort/DatabaseName?user=myUsername&password=myP
assword";
// Ορίζουμε ένα αντικείμενο sqlString τύπου string για να γράψουμε τη δήλωση SQL
(που θέλουμε να εκτελεστεί στη συνέχεια).
myStatement.executeUpdate(sqlString);
Αν η sqlString αφορούσε μια SQL statement τύπου select, η μέθοδός μας θα ήταν:η
executeQuery:
myStatement.executeQuery(sqlString);
6
8. Κλείσιμο του αντικειμένου «αναγραφής» SQL statements
myStatement.close();
myConnection.close();
myStatement.methodName(sqlString);
όπου myStatement είναι ένα αντικείμενο τύπου Statement και methodName είναι
μια από τις μεθόδους που παρέχει η κλάση Statement.
myStatement.executeUpdate(sqlString);
myStatement.executeUpdate(sqlString);
8
String sqlString = "DELETE FROM MYTABLE WHERE PARAM = 'paramValue'";
myStatement.executeUpdate(sqlString);
Η Java παρέχει μια εύχρηστη δομή μέσω της κλάσης ResultSet. Πιο συγκεκριμένα, η
μέθοδος ExecuteQuery μας επιστρέφει ένα αντικείμενο τύπου ResultSet. Ας
ονομάσουμε το συγκεκριμένο αντικείμενο rs. Μέσα στο αντικείμενο αυτό
αποθηκεύονται προσωρινά όλες οι γραμμές δεδομένων που επιστρέφει η δήλωση
SELECT που εκτελέσαμε. Μέσω του αντικειμένου αυτού μπορούμε να
επεξεργαστούμε τις γραμμές στο πρόγραμμά μας
Το αντικείμενο rs μας παρέχει και έναν δείκτη ο οποίος αρχικά δείχνει πρίν από την
πρώτη γραμμή αποτελεσμάτων που είναι αποθηκευμένα στο αντικείμενο rs.
9
Πρακτικός κανόνας για τη συγγραφή δήλωσης SQL στα προγράμματά μας:
Τοποθετούμε την εντολή σε " " και αντικαθιστούμε κάθε συγκεκριμένη τιμή, για
παράδειγμα την τιμή 'ANALYST'με το όνομα της μεταβλητής γραμμένο με "+ +",
ως εξής: '"+job+"'
Ακολουθεί παράδειγμα χρήσης της executeQuery που βοηθά στην κατανόηση του
τρόπου που χρησιμοποιούμε τις διάφορες μεθόδους της κλάσης ResultSet.
myTable,
ID Int
Name Text
10
Δημιουργείστε ένα αρχείο test.jsp και γράψτε τον παρακάτω κώδικα
<%--
Document : test
Created on : April 31, 2014, 8:24:04 AM
Author :
--%>
// Import the package java.sql – all the classes
<%@page import="java.sql.*" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%
int j=0;
// Define parameters for retrieving database results
int m[] = new int[5000];
String s[] = new String[5000];
// Load the driver
Class.forName("com.mysql.jdbc.Driver");
// Define the connection parameters
String myDatabase =
"jdbc:mysql://localhost:3306/personnel?user=root";
// Connect to the database
Connection myConnection = DriverManager.getConnection(myDatabase);
// Create object to execute statements
Statement myStatement = myConnection.createStatement();
// Select everything from the database table
String sqlString = "SELECT * FROM myTable ";
ResultSet rs=myStatement.executeQuery(sqlString);
// Store the results in vectors in order to pass them to the JSP
while(rs.next()){
m[j]=rs.getInt("id");
s[j]=rs.getString("name");
j++;
}
// Close the connection to the database
myStatement.close();
myConnection.close();
// Print
out.println("j="+j+"<br>");
for(int i=0; i<j; i++)
{
out.println(m[i]+"");
out.println(s[i]+"<br>");
}
%>
11
Στη συνέχεια τρέξτε το πρόγραμμα.
j=3
11
1 ann
1 tom
Σύνοψη – Επισκόπηση
12
6. Case Study «Διαχείριση βάσης προσωπικού»
1. Προβολή όλων των τμημάτων της εταιρείας μαζί με τα στοιχεία εργαζομένων που
ανήκουν σε αυτά.
2. Εισαγωγή ενός νέου εργαζόμενου.
3. Διαγραφή ενός εργαζόμενου
4. Ενημέρωση των στοιχείων των εργαζομένων.
13
DROP DATABASE personnel_db;
USE personnel;
NO_OF_EMPLOYEES INT(3),
PRIMARY KEY(DEPTNO));
SAL FLOAT(7,2),
14
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SMITH', 'CLERK', 800, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ALLEN', 'SALESMAN', 1600, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'WARD', 'SALESMAN', 1250, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JONES', 'MANAGER', 2975, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MARTIN', 'SALESMAN', 1250, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BLAKE', 'MANAGER', 2850, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'CLARK', 'MANAGER', 2450, 10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SCOTT', 'ANALYST', 3000, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'KING', 'PRESIDENT', 5000, 10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'TURNER', 'SALESMAN', 1500, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ADAMS', 'CLERK', 1100, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JAMES', 'CLERK', 950, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'FORD', 'ANALYST', 3000, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MILLER', 'CLERK', 1300, 10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BATES', 'ANALYST', 1300, NULL);
UPDATE dept
SET no_of_employees =
(SELECT COUNT(*)
FROM emp
15
CREATE TABLE user(
uname text,
upass text,
Uid int(11),
16
Χρήση Cursor
DELIMITER $$
BEGIN
SET no_more_depts = 1;
OPEN cur_dept;
REPEAT
FROM dept
END IF;
UNTIL no_more_depts = 1
END REPEAT;
17
CLOSE cur_dept;
END$$
DELIMITER ;
CALL CURSORPROC();
18
7. Υλοποίηση εφαρμογής
Ip:localhost
Port:3306
Database: personnel
User=root
Password=
User=root
Password=1234
Στάδια:
I. Διαχείριση Σύνδεσης
Υλοποιείται με χρήση δύο (2) σελίδων: index.jsp, check.jsp
Index.jsp
19
<%--
Document : index
Author :
--%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
WELCOME<p></p>
LOGIN<p></p>
<p></p>
</form>
</body>
</html>
20
<%--
Document : check
Author :
--%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
Boolean found;
String x =request.getParameter("y");
String p = request.getParameter("k");
String URL;
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
ResultSet rs=SMT.executeQuery(sql);
found= rs.first();
if (found){
URL = "home.jsp?p1="+x+"";
21
response.sendRedirect(URL);
else
SMT.close();
myConnection.close();
%>
</body>
</html>
Σημαντική σημείωση
Ip:localhost
Port:3306
Database: personnel
User=root
Password=1234
String DB = "jdbc:mysql://localhost:3306/personnel?user=root";
String DB =
"jdbc:mysql://localhost:3306/personnel_db?user=root&password=1234";
22
II. Προβολή όλων των εργαζομένων και των τμημάτων στα οποία ανήκουν.
Υλοποιείται με χρήση της σελίδας (home.jsp)
κ.λπ.
23
<%--
Document : home
Author :
--%>
<!DOCTYPE html>
<%
int i;
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
%>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
24
ResultSet rs=SMT.executeQuery(sql);
String dname;
int count=0;
while (rs.next())
i=rs.getInt("deptno");
ResultSet rs1=SMT1.executeQuery(sql1);
dname=rs.getString("dname");
%>
ONCLICK="window.location.href='insert.jsp?deptno=<%= i%>'">
<%
while(rs1.next())
name[count]=rs1.getString("ename");
job[count]=rs1.getString("job");
empno[count]=rs1.getInt("empno");
%> <br>
ONCLICK="window.location.href='update.jsp?empno=<%=
empno[count]%>'">
ONCLICK="window.location.href='delete.jsp?empno=<%=
empno[count]%>'">
25
<br>
}}%>
<%
SMT.close();
SMT1.close();
myConnection.close();
%>
</body>
</html>
Για παράδειγμα
26
κ.λπ.
Αλλάζουμε τα στοιχεία
Επιλέγουμε update οπότε ενημερώνεται η γραμμή και επιστρέφουμε στην αρχική φόρμα:
27
V. Διαγραφή ενός εργαζομένου (delete.jsp)
κ.λπ.
28
<%--
Document : insert
Author :
--%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
</form>
</body>
</html>
29
<%--
Document : ins_submit
Author :
--%>
<%@page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
String name=request.getParameter("ename");
String job=request.getParameter("job");
String sal=request.getParameter("sal");
int deptno=Integer.parseInt(request.getParameter("deptno"));
SMT.executeUpdate(sql);
response.sendRedirect(URL);
%>
30
<%
SMT.close();
myConnection.close();
%>
</body>
</html>
31
<%--
Document : update
Author :
--%>
<!DOCTYPE html>
<%@page import="java.sql.*"%>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
String job="",sal="",ename="";
int empno=Integer.parseInt(request.getParameter("empno"));
while(rs.next()){
32
job=rs.getString("job");
sal=rs.getString("sal");
ename=rs.getString("ename");
%>
</form>
</body>
</html>
33
<%--
Document : up_submit
Author :
--%>
<%@page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
String name=request.getParameter("ename");
String job=request.getParameter("job");
String sal=request.getParameter("sal");
int empno=Integer.parseInt(request.getParameter("empno"));
SMT.executeUpdate(sql);
34
sql="update emp set job ='"+job+"' where empno="+empno;
SMT.executeUpdate(sql);
SMT.executeUpdate(sql);
response.sendRedirect(URL);
SMT.close();
myConnection.close();
%>
</body>
</html>
35
<%--
Document : delete
Author :
--%>
<%@page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Page</title>
</head>
<body>
<%
Class.forName("com.mysql.jdbc.Driver");
String DB =
"jdbc:mysql://localhost:3306/personnel?user=root";
int empno=Integer.parseInt(request.getParameter("empno"));
SMT.executeUpdate(sql);
response.sendRedirect(URL);
SMT.close();
myConnection.close();
%>
</body>
</html>
36
Δημιουργία βάσης δεδομένων
USE personnel;
NO_OF_EMPLOYEES INT(3),
PRIMARY KEY(DEPTNO));
SAL FLOAT(7,2),
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SMITH', 'CLERK', 800, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ALLEN', 'SALESMAN', 1600, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'WARD', 'SALESMAN', 1250, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JONES', 'MANAGER', 2975, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MARTIN', 'SALESMAN', 1250, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BLAKE', 'MANAGER', 2850, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'CLARK', 'MANAGER', 2450, 10);
37
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SCOTT', 'ANALYST', 3000, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'KING', 'PRESIDENT', 5000, 10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'TURNER', 'SALESMAN', 1500, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ADAMS', 'CLERK', 1100, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JAMES', 'CLERK', 950, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'FORD', 'ANALYST', 3000, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MILLER', 'CLERK', 1300, 10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BATES', 'ANALYST', 1300, NULL);
UPDATE dept
SET no_of_employees =
(SELECT COUNT(*)
FROM emp
uname text,
upass text,
Uid int(11),
38
Βάσεις Δεδομένων ΙΙ (Ε)
Ενότητα 14: Επισκόπηση της Διαχείρισης triggers στο περιβάλλον mySQL και σε
Oracle
Στόχος του εργαστηρίου είναι η επισκόπηση της χρήσης triggers για τη δημιουργία
εφαρμογών στο περιβάλλον mySQL αλλά και τη διαχείριση βάσεων δεδομένων.
Μετά την επεξεργασία του εργαστηρίου ο ενδιαφερόμενος θα έχει κατανοήσει τα
θέματα της χρήσης triggers και δημιουργίας εφαρμογής βάσεων δεδομένων. Τέλος,
ο ενδιαφερόμενος θα έχει κατανοήσει τα θέματα της χρήσης triggers και
δημιουργίας εφαρμογής βάσεων δεδομένων και στο περιβάλλον της Oracle.
2
1. Επισκόπηση της Διαχείρισης triggers στο περιβάλλον mySQL
και σε Oracle
USE personnel;
NO_OF_EMPLOYEES INT(3),
PRIMARY KEY(DEPTNO));
SAL FLOAT(7,2),
uname text,
upass text,
Uid int(11),
3
INSERT INTO `user` VALUES ('admin','1234',1,NULL,NULL);
DEPTN NO_OF_EMPLOYEES
O DNAME LOC
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
4
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SMITH', 'CLERK', 800, 20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ALLEN', 'SALESMAN', 1600,
30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'WARD', 'SALESMAN', 1250,
30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JONES', 'MANAGER', 2975,
20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MARTIN', 'SALESMAN',
1250, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BLAKE', 'MANAGER', 2850,
30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'CLARK', 'MANAGER', 2450,
10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'SCOTT', 'ANALYST', 3000,
20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'KING', 'PRESIDENT', 5000,
10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'TURNER', 'SALESMAN',
1500, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'ADAMS', 'CLERK', 1100,
20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'JAMES', 'CLERK', 950, 30);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'FORD', 'ANALYST', 3000,
20);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'MILLER', 'CLERK', 1300,
10);
INSERT INTO Emp( ENAME, JOB, SAL, DEPTNO) VALUES ( 'BATES', 'ANALYST', 1300,
NULL);
5
Select * from emp;
6
DROP TRIGGER emp_insert;
DELIMITER //
BEGIN
UPDATE dept
END //
DELIMITER ;
DELIMITER //
BEGIN
UPDATE dept
END //
DELIMITER ;
7
DELIMITER //
BEGIN
UPDATE dept
UPDATE dept
END //
DELIMITER ;
8
Ακολουθούν δοκιμές / έλεγχοι.
UPDATE emp
SET deptno = 11
UPDATE dept
9
SET no_of_employees = (SELECT COUNT(*)
FROM emp
Σημείωση
10
SELECT * FROM DEPT
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
PRIMARY KEY(DEPTNO));
11
INSERT INTO Dept(DEPTNO, DNAME, LOC)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
12
VALUES (7900, 'JAMES', 'CLERK', 7698, '03/12/1981', 950, NULL, 30);
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
INSERT INTO Emp(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
/* τέλος εντολών */
ename VARCHAR2(10),
deptno NUMBER(2));
Αν θέλετε με την επόμενη εντολή μπορείτε να «φορτώσετε» από τον πίνακα emp
δεδομένα στον νέο πίνακα.
dname VARCHAR2(14));
13
Ο επόμενος trigger, είναι αποθηκευμένος (stored) και εκτελείται πριν από την
εισαγωγή / ενημέρωση των στοιχείων του πίνακα my_dept και μεταγράφει τα
στοιχεία αυτά με κεφαλαία γράμματα.
BEGIN
:NEW.dname := UPPER(:NEW.dname);
END;
Ακολουθούν δοκιμές.
UPDATE my_dept
14
Στη συνέχεια βλέπουμε τα στοιχεία του πίνακα my_emp και προσθέτουμε στον
πίνακα my_dept στήλη που έχει τον αριθμό των υπαλλήλων για κάθε τμήμα.
UPDATE my_dept
FROM my_emp
BEGIN
UPDATE my_dept
15
WHERE deptno = :NEW.deptno;
END;
BEGIN
UPDATE my_dept
END;
BEGIN
16
UPDATE my_dept
UPDATE my_dept
END;
UPDATE my_emp
SET deptno = 11
17
1.4 Κάποιες άλλες χρήσιμες υποδείξεις για τη διαχείριση των triggers
στο προϊόν της Oracle
DESCRIBE USER_TRIGGERS;
SELECT trigger_name,triggering_event,trigger_type
FROM USER_TRIGGERS
ORDER BY trigger_name;
SELECT trigger_name,trigger_body
FROM USER_TRIGGERS
ORDER BY trigger_name;
BEGIN
DBMS_OUTPUT.PUT_LINE('only_during_my_hours trigger');
IF TO_NUMBER(TO_CHAR(SYSDATE,'hh24')) < 8
18
OR TO_NUMBER(TO_CHAR(SYSDATE,'hh24')) >= 5
/* nothing on Sunday */
RAISE_APPLICATION_ERROR(-20000,
END IF;
END;
19