Esempi di risoluzione delle prove scritte dell’esame di Stato Tutte le prove scritte di Informatica dell’esame di Stato successive all’anno 2000 condividono richieste simili a fronte di una situazione da analizzare e modellizzare mediante un database relazionale: • progettazione logica e fisica del database; • realizzazione del DB-schema del database in linguaggio SQL; • codifica in linguaggio SQL di alcune interrogazioni; •realizzazione di un sito web (o, in alcuni casi, di un’applicazione software) che renda disponibili alcune funzionalità di interazione con il database; la scelta della tecnologia e del linguaggio di programmazione è sempre lasciata libera. L’ultima richiesta implica normalmente la codifica in un linguaggio di programmazione noto di alcune parti significative del sito o dell’applicazione. Spesso l’analisi della situazione proposta è resa difficoltosa dall’ambiguità dell’esposizione e delle richieste e in molti casi la progettazione del database può essere effettuata solo interpretando il significato delle interrogazioni richieste. Le tracce delle prove prevedono sempre esplicitamente la definizione di «ipotesi aggiuntive» che il candidato può formulare al fine di circoscrivere il contesto della situazione da modellizzare, o per puntualizzare alcuni aspetti relativi alle richieste o alla soluzione tecnologica individuata. Nel seguito sono proposte le soluzioni alle prove scritte che il Ministero dell’Istruzione ha proposto per le sessioni di esami negli anni 2002, 2003, 2008 e 2011; per la prova dell’anno 2011 erano previste 8 ore di tempo, mentre per le precedenti erano previste 6 ore di tempo. In tutti i casi la soluzione è stata strutturata secondo uno schema predeterminato: • testo della prova; • analisi della situazione proposta e/o ipotesi aggiuntive; • diagramma grafico del database; •descrizione delle tabelle del database con specificazione dei singoli campi; • DB-schema SQL per la generazione del database; • query SQL che implementano le interrogazioni richieste; •descrizione del sito web o dell’applicazione software richiesta e codifica di una sua componente significativa. Introduzione Formichi, Meini, Corso di informatica, © Zanichelli Editore 1 Le soluzioni proposte sono sempre complete – per esempio viene fornita la codifica di due componenti significative del sito web o dell’applicazione software, anziché di una – e alcune parti, come gli esempi di istanze delle tabelle, sono state inserite al solo scopo di chiarire al lettore le scelte progettuali operate; la risoluzione di una prova di esame potrà quindi essere considerata corretta anche in presenza di uno sviluppo molto più contenuto di quello qui presentato. Le prove di esame si prestano a numerose soluzioni alternative, anche in dipendenza delle ipotesi aggiuntive eventualmente formulate dal candidato: quelle proposte nel seguito sono coerenti per metodologia e per adozione delle soluzioni tecnologiche e per scelta del linguaggio di programmazione ai contenuti dell’ultimo volume del Corso di informatica. In particolare per la soluzione della prova del 2011 viene proposto il codice Java per l’importazione/esportazione di dati in formato XML dal database in alternativa alla più tradizionale applicazione web realizzata il linguaggio PHP. 2 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore 1 Anno 2002 - Informatica ABACUS Testo Un’associazione «Banca del Tempo» vuole realizzare una base di dati per registrare e gestire le attività dell’associazione. La «Banca del Tempo» (BdT) indica uno di quei sistemi organizzati di persone che si associano per scambiare servizi e/o saperi, attuando un aiuto reciproco. Attraverso la BdT le persone mettono a disposizione il proprio tempo per determinate prestazioni (effettuare una piccola riparazione in casa, preparare una torta, conversare in lingua straniera, …) aspettando di ricevere prestazioni da altri. Non circola denaro, tutte le prestazioni sono valutate in tempo, anche le attività di segreteria. Le prestazioni sono suddivise in categorie (lavori manuali, tecnologie, servizi di trasporto, bambini, attività sportive, …). Chi dà un’ora del suo tempo a qualunque socio, riceve un’ora di tempo da chiunque faccia parte della BdT. La base di dati dovrà mantenere le informazioni relative a ogni prestazione (quale prestazione, da chi è stata erogata, quale socio ha ricevuto quella prestazione, per quante ore e in quale data) per consentire anche interrogazioni di tipo statistico. Il territorio di riferimento della BdT è limitato (un quartiere in una grande città o un piccolo comune) ed è suddiviso in zone; la base di dati dovrà contenere la mappa del territorio e delle singole zone, in forma grafica. Si consideri la realtà di riferimento sopra descritta e si realizzino: 1la progettazione concettuale della realtà indicata attraverso la produzione di uno schema (ad esempio ER, Entity-Relationship) con gli attributi di ogni entità, il tipo di ogni relazione e i suoi eventuali attributi; 2una traduzione dello schema concettuale realizzato in uno schema logico (ad esempio secondo uno schema relazionale); 3le seguenti interrogazioni espresse in algebra relazionale e/o in linguaggio SQL: aprodurre l’elenco dei soci (con cognome, nome e telefono) che hanno un «debito» nella BdT (coloro che hanno usufruito di ore di prestazioni in numero superiore a quelle erogate); bdata una richiesta di prestazione, visualizzare la porzione di mappa del territorio nel quale si trova il socio richiedente e l’elenco di tutti i soci che si trovano in quella zona in grado di erogare quella prestazione, visualizzandone il nome, cognome, indirizzo e numero di telefono; cvisualizzare tutti i soci che fanno parte della segreteria e che offrono anche altri tipi di prestazione; dprodurre un elenco delle prestazioni ordinato in modo decrescente secondo il numero di ore erogate per ciascuna prestazione. 4(Facoltativo) Sviluppare il problema posto scegliendo una delle due seguenti proposte descrivendone le problematiche e le soluzioni tecniche adottabili: 4.1l’associazione BdT vuole realizzare un sito Web per rendere pubbliche le sue attività consentendo anche di effettuare online le interrogazioni della base di dati previste nel punto 3; 4.2l’associazione BdT vuole realizzare un sito Web attraverso il quale possa raccogliere l’adesione online di altri associati, attraverso il riempimento di un modulo da inviare via Internet all’associazione. 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 3 1.1 Ipotesi aggiuntive •La BdT opera su un territorio suddiviso in zone e per ognuna di esse ogni socio della BdT può operare su più categorie di prestazione censite. •Per ogni prestazione sono coinvolti due soci, uno come prestatore del servizio (erogatore) e l’altro come beneficiario del medesimo (fruitore); le ore su cui viene conteggiata la prestazione saranno computate a debito per il fruitore e a credito per l’erogatore. •Per questioni di omogeneità nella gestione delle prestazioni, la segreteria viene considerata come un socio che non effettua alcuna prestazione ma che ne riceve dai soci che si rendono disponibili a operare per essa nel controllare le attività della BdT: essa figurerà pertanto come un socio sempre a debito. •Le prestazioni sono contabilizzate per unità orarie indivisibili, ovvero nel caso di prestazioni inferiori all’ora o che eccedano un numero intero di ore, la durata delle medesime viene arrotondata all’unità superiore. •Per quanto riguarda le mappe si ipotizza una soluzione in cui ogni mappa rappresenta tutto il territorio di interesse che è suddiviso in zone e dove la zona specifica viene individuata evidenziandone il perimetro tramite una bordatura colorata: tutti i file delle mappe – una per ogni zona – sono memorizzati in una specifica directory, mentre nella tabella relativa alle zone viene registrato il pathname dei file immagine (ad esempio «BdT\Img\Centro.jpg»). 1.2 Diagramma database Soci Zone PK Id_Zona PK Id_Socio FK1 Nominativo Indirizzo Telefono Id_Zona Descrizione Mappa Categorie PK Id_Categoria Categorie_Soci PK,FK2 Id_Socio PK,FK1 Id_Categoria Descrizione Prestazioni PK FK1 4 Id_Prestazione Id_Categoria Data Ore Note Ruoli PK,FK2 Id_Socio PK,FK1 Id_Prestazione Ruolo Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore 1.3 Tabelle database Categorie È la tabella in cui sono censite le categorie di prestazione che la BdT prevede e che i soci sono in grado di espletare: Campo Id_Categoria R PK Descrizione Tipo Dim. Descrizione Carattere 5 Codice identificativo categoria di prestazione Carattere 20 Descrizione categoria di prestazione Chiave Primaria: Id_Categoria La seguente è una possibile istanza della tabella Categorie: Id_Categoria Descrizione ASA Assistenza anziani CPT Carpenteria ELT Elettronica/tecnica FLG Falegnameria IDR Idraulica INF Informatica MCN Meccanica PLZ Pulizie PST Pasticceria SGR Segreteria Categorie_Soci È la tabella in cui sono definite le possibili categorie di prestazione cui ogni singolo socio si è dichiarato disponibile a espletare: Campo R Tipo Id_Socio PK FK Intero Id_Categoria PK FK Carattere Dim. Descrizione Codice identificativo socio 5 Codice identificativo categoria prestazione Chiave Primaria: Id_Socio, Id_Categoria Chiave Esterna: Id_Categoria → Categorie.Id_Categoria Chiave Esterna: Id_Socio → Soci.Id_Socio La seguente è una possibile istanza della tabella Categorie_Soci: 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 5 Id_Socio Id_Categoria 1 FLG 1 MCN 2 PLZ 2 PST 2 SGR 3 ASA 3 MCN 4 ELT 4 INF 4 SGR 5 SGR 6 CPT 6 IDR 6 MCN 7 CPT 7 FLG 7 MCN Prestazioni È la tabella che costituisce il vero e proprio registro delle prestazioni effettuate: Campo R Tipo Id_Prestazione PK Intero Id_Categoria FK Carattere Dim. Descrizione Codice identificativo prestazione 5 Codice identificativo categoria prestazione Data Data/Ora Data esecuzione prestazione Ore Intero Ore impiegate per espletare la prestazione Note Carattere 50 Note sull’esecuzione prestazione Chiave Primaria: Id_Prestazione Chiave Esterna: Id_Categoria → Categorie.Id_Categoria La seguente è una possibile istanza della tabella Prestazioni: 6 Id_Prestazione Id_Categoria Data Ore Note 1 SGR 10/05/2002 10:30:00 1 Revisione archivio prati­ che 2 MCN 10/05/2002 12:00:00 2 Sostituiti freni auto 3 IDR 11/06/2002 08:45:00 2 Sostituito flessibile lavan­ dino 4 ASA 20/03/2002 20:00:00 1 Compagnia pensionato 5 PLZ 01/02/2002 07:30:00 3 Pulizia appartamento 6 PST 01/01/2002 12:00:00 2 Preparata torta per com­ pleanno 7 SGR 15/02/2002 14:00:00 3 Revisione agenda 8 INF 06/04/2002 23:30:00 5 Ripristino database BdT 9 SGR 22/03/2002 01:00:00 1 Caricamento dati BdT Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Ruoli In questa tabella viene registrato per ogni prestazione il ruolo che ogni socio ha rivestito (erogatore/fruitore); pertanto per ogni prestazione effettuata questa tabella conterrà due righe, quella relativa al socio erogatore e quella relativa al socio fruitore: Campo R Tipo Id_Socio PK Intero Id_Prestazione PK Intero Ruolo Carattere Dim. Descrizione Codice identificativo socio Codice identificativo prestazione 1 Ruolo del socio nella prestazione (E: Erogato­ re, F: Fruitore) Chiave Primaria: Id_Socio, Id_Prestazione Chiave Esterna: Id_Prestazione → Prestazioni.Id_Prestazione Chiave Esterna: Id_Socio → Soci.Id_Socio La seguente è una possibile istanza della tabella Ruoli: Id_Socio Id_Prestazione Ruolo 1 5 F 2 1 E 2 3 F 2 5 E 3 4 E 3 8 F 4 2 F 4 8 E 5 7 E 5 9 E 6 2 E 6 3 E 6 4 F 99 1 F 99 7 F 99 9 F Soci È la tabella in cui sono memorizzati i dati dei soci della BdT: Campo R Tipo Id_Socio PK Intero Dim. Descrizione Codice identificativo socio (valore numerico auto­incrementante) Nominativo Carattere 30 Cognome e nome Indirizzo Carattere 30 Indirizzo Telefono Carattere 15 Telefono Id_Zona FK Intero Identificativo zona di appartenenza Chiave Primaria: Id_Socio Chiave Esterna: Id_Zona → Zone.Id_Zona 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 7 La seguente è una possibile istanza della tabella Soci: Id_Socio Nominativo Indirizzo Telefono Id_Zona 1 Rossi Marco Via del Mare, 10 578164 10 2 Giannini Maria Via di Colline, 14 854224 3 3 Martelli Roberto Via Degli Avvalorati, 1 803161 1 4 Bellini Giovanni Via Guerrazzi, 52 863044 5 5 Bianchi Paolo Via Giovanni XXIII,18 576144 11 6 Tedeschi Mario Viale Marconi, 65 857112 3 7 Testi Marco Via del Fagiano, 100 857123 3 99 Segreteria BdT P.zza Roma, 45 863128 5 Zone È la tabella in cui sono memorizzati i dati delle zone in cui opera la BdT. La sua struttura è definita come segue. Campo R Tipo Id_Zona PK Intero Dim. Descrizione Codice identificativo zona Descrizione Carattere 50 Descrizione zona Mappa Testo 100 Pathname immagine zona Chiave Primaria: Id_Zona La seguente è una possibile istanza della tabella Zone: Id_Zona Descrizione Mappa 1 Centro Img\Centro.jpg 2 Venezia Img\Venezia.jpg 3 Colline Img\Colline.jpg 4 Sorgenti Img\Sorgenti.jpg 5 Fabbricotti Img\Fabbricotti.jpg 6 S. Marco Img\SMarco.jpg 7 Corea Img\Corea.jpg 8 Shangai Img\Shangai.jpg 9 Ardenza Img\Ardenza.jpg 10 Antignano Img\Antignano.jpg 11 Montenero Img\Montenero.jpg 12 Scopaia Img\Scopaia.jpg 1.4 DB-schema CREATE TABLE Categorie( Id_Categoria VARCHAR(5) NOT NULL, Descrizione VARCHAR(20) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Categoria) ); 8 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore CREATE TABLE Prestazioni( Id_Prestazione INTEGER NOT NULL, Id_Categoria VARCHAR(5) NOT NULL, Data DATETIME NOT NULL, Ore INTEGER NOT NULL, Note VARCHAR(50), CONSTRAINT Categorie_Prestazioni FOREIGN KEY(Id_Categoria) REFERENCES Categorie(Id_Categoria), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Prestazione) ); CREATE TABLE Zone( Id_Zona INTEGER NOT NULL, Descrizione VARCHAR(50) NOT NULL, Mappa VARCHAR(100) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Zona) ); CREATE TABLE Soci( Id_Socio INTEGER NOT NULL AUTO_INCREMENT, Nominativo VARCHAR(30) NOT NULL, Indirizzo VARCHAR(30) NOT NULL, Telefono VARCHAR(15) NOT NULL, Id_Zona INTEGER NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Socio), CONSTRAINT Zone_Soci FOREIGN KEY(Id_Zona) REFERENCES Zone(Id_Zona) ); CREATE TABLE Categorie_Soci( Id_Socio INTEGER NOT NULL, Id_Categoria VARCHAR(5) NOT NULL, CONSTRAINT CategorieSoci_Categorie FOREIGN KEY(Id_Categoria) REFERENCES Categorie(Id_Categoria), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Socio, Id_Categoria), CONSTRAINT CategorieSoci_Soci FOREIGN KEY(Id_Socio) REFERENCES Soci(Id_Socio) ); CREATE TABLE Ruoli( Id_Socio INTEGER NOT NULL, Id_Prestazione INTEGER NOT NULL, Ruolo VARCHAR(1) NOT NULL, CONSTRAINT Prestazioni_Ruoli FOREIGN KEY(Id_Prestazione) REFERENCES Prestazioni(Id_Prestazione), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Socio, Id_Prestazione), CONSTRAINT Soci_Ruoli FOREIGN KEY(Id_Socio) REFERENCES Soci(Id_Socio) ); 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 9 1.5 Query a SELECT Soci.Id_Socio, Nominativo, D.Debito-C.Credito AS DebitoOre FROM Soci, (SELECT Id_Socio, SUM(Ore) AS Credito FROM Prestazioni, Ruoli WHERE Prestazioni.Id_Prestazione = Ruoli.Id_Prestazione AND Ruolo='E' GROUP BY Id_socio) AS C, (SELECT Id_Socio, SUM(Ore) AS Debito FROM Prestazioni, Ruoli WHERE Prestazioni.Id_Prestazione = Ruoli.Id_Prestazione AND Ruolo='F' GROUP BY Id_socio) AS D WHERE Soci.Id_Socio = C.Id_Socio AND Soci.Id_Socio = D.Id_Socio AND D.Debito > C.Credito; b La richiesta è stata risolta tramite una query nidificata in cui non sono stati indicati i valori del socio richiedente e della categoria di servizio: la query più interna seleziona il codice della zona a cui appartiene il socio richiedente, mentre quella più esterna seleziona, tra i soci di tale zona, quelli in grado di fornire il servizio richiesto (la visualizzazione grafica della zona è realizzata nel seguito mediante uno script PHP). SELECT Soci.*, Zone.Mappa FROM Soci, Categorie_Soci, Zone WHERESoci.Id_Socio = Categorie_Soci.Id_Socio ANDZone.Id_Zona = Soci.Id_Zona ANDCategorie_Soci.Id_Categoria = '…' ANDZone.Id_Zona IN ( SELECT Zone.Id_zona FROM Soci, Zone WHEREZone.Id_Zona = Soci.Id_Zona AND Soci.Id_Socio = …); c SELECT Soci.Id_Socio, Nominativo FROM Soci, Categorie_Soci WHERESoci.Id_Socio = Categorie_Soci.Id_Socio ANDSoci.Id_Socio IN ( SELECT Id_Socio FROM Categorie_Soci WHERE Id_Categoria='SGR') GROUP BY Soci.Id_Socio, Nominativo HAVING COUNT(*) > 1; 10 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore d Soluzione 1 (tutte le prestazioni) SELECT * FROM Prestazioni ORDER BY Ore DESC, Data; Soluzione 2 (per categoria di prestazione) SELECT Id_Categoria, SUM(Ore) AS Ore_Spese FROM Prestazioni GROUP BY Id_Categoria ORDER BY SUM(Ore) DESC; 1.6 Sito web Date le caratteristiche e la natura dell’associazione che probabilmente non dispone di personale specializzato per la gestione di un server per ospitare il sito web, la soluzione più indicata è quella di acquistare un servizio di hosting del sito da un fornitore di servizi web (spesso è possibile acquistare il servizio di hosting del sito insieme alla registrazione del dominio che in questo caso potrebbe essere www.bancadeltempo.org): questa soluzione è senz’altro la migliore, tenuto conto che il sito deve essere operativo 24 ore su 24 e 7 giorni su 7, ed è anche economica. È necessario acquistare, oltre allo spazio web per ospitare il sito, l’integrazione dell’interprete PHP nel server web e la disponibilità di un database My-SQL per la gestione del database: si tratta in ogni caso di un pacchetto molto comune nell’offerta dei fornitori di servizi web. Come esempio di pagina web dinamica che costituisce il sito della BdT presentiamo 2 script PHP (il primo per inserire la richiesta e il secondo per visualizzare la relativa risposta) che realizzano il comportamento richiesto per la query (b). Si è ipotizzato che il server My-SQL sia in esecuzione sullo stesso computer del web server e che l’accesso al database «BdT» venga effettuato come utente «root» privo di password; inoltre le pagine web sono completamente prive di struttura grafica. <html> <head> <title>Individuazione soci</title> </head> <body> Selezionare socio richiedente e categoria di prestazione richiesta: <?php $connection = mysqli_connect("localhost", "root", "", "BdT"); if (mysqli_connect_errno($connection)) 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 11 { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> <form action="risposta.php" method="GET"> <select name="socio"> <?php $query = "SELECT Id_Socio, Nominativo FROM Soci;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessun socio presente." ; die(); } while ($row = mysqli_fetch_array($result)) { echo "<option value=\"$row[0]\">$row[1]</option>"; } mysqli_free_result($result); ?> </select> <br> <select name="categoria"> <?php $query = "SELECT Id_categoria, Descrizione FROM Categorie;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL."; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessuna categoria registrata." ; die(); } while ($row = mysqli_fetch_array($result)) { echo "<option value=\"$row[0]\">$row[1]</option>"; } 12 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore mysqli_free_result($result); mysqli_close($connection); ?> </select> <br> <input type="submit" value="Cerca"> <br> </form> </body> </html> <html> <head> <title>Elenco soci</title> </head> <body> <?php $connection = mysqli_connect("localhost", "root", "", "BdT"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } $query = " SELECT Soci.*, Zone.Mappa FROM Soci,Zone WHERE Zone.Id_Zona = Soci.Id_Zona AND Soci.Id_Socio = $_GET[socio];"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessuna mappa trovata." ; die(); } else { $row = mysqli_fetch_assoc($result); $mappa = $row['Mappa']; mysqli_free_result($result); } $query = " SELECT Soci.*, Zone.Descrizione FROM Soci, Categorie_Soci, Zone 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 13 WHERE Soci.Id_Socio = Categorie_Soci.Id_Socio AND Zone.Id_Zona = Soci.Id_Zona AND Categorie_Soci.Id_Categoria = '$_GET[categoria]' AND Soci.Id_Socio <> $_GET[socio] AND Zone.Id_Zona IN ( SELECT Zone.Id_zona FROM Soci, Zone WHERE Zone.Id_Zona = Soci.Id_Zona AND Soci.Id_Socio = $_GET[socio]);"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessun socio trovato." ; die(); } ?> <table border> <caption><b>Soci per Zona</b></caption> <thead> <tr> <th>ID socio</th> <th>Nominativo</th> <th>Indirizzo</th> <th>Telefono</th> <th>ID zona</th> <th>Zona</th> </tr> </thead> <tbody> <?php while ($row = mysqli_fetch_assoc($result)) { ?> <tr> <td><?php echo ($row['Id_Socio']); ?></td> <td><?php echo ($row['Nominativo']); ?></td> <td><?php echo ($row['Indirizzo']); ?></td> <td><?php echo ($row['Telefono']); ?></td> <td><?php echo ($row['Id_Zona']); ?></td> <td><?php echo ($row['Descrizione']); ?></td> </tr> <?php } 14 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore mysqli_free_result($result); echo "</tbody>\n"; echo "</table>\n"; echo "<br>\n"; echo "Mappa socio richiedente\n"; echo "<br>\n"; echo "<img src=\"$mappa\">"; echo "<br>\n"; mysqli_close($connection); ?> </body> </html> Sono riportate di seguito le pagine web dinamiche create dai due script PHP: Come esempio di pagina web dinamica che consente di aggiungere un nuovo socio al database della BdT presentiamo 2 script PHP (il primo per visualizzare il modulo di richiesta dei dati e il secondo per inserire i dati nel database). Si è ipotizzato che il server My-SQL sia in esecuzione sullo stesso computer del web server e che l’accesso al database «BdT» venga effettuato 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 15 come utente «root» privo di password; anche in questo caso le pagine web sono completamente prive di struttura grafica. <html> <head> <title>Dati</title> </head> <body> Selezionare la zona di residenza, la categoria di servizio offerto e inserire i propri dati: <?php $connection = mysqli_connect("localhost", "root", "", "BdT"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> <form action="iscrizione.php" method="POST"> <label for="zona">Zona</label> <select id="zona" name="zona"> <?php $query = "SELECT ID_zona, Descrizione FROM Zone;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL."; die(); } while ($row = mysqli_fetch_array($result)) echo "<option value=\"$row[0]\">$row[1]</option>"; mysqli_free_result($result); ?> </select><br> <label for="category">Categoria</label> <select id="category" name="categoria"> <?php $query = "SELECT ID_categoria, Descrizione FROM Categorie;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL."; die(); } while ($row = mysqli_fetch_array($result)) echo "<option value=\"$row[0]\">$row[1]</option>"; mysqli_free_result($result); 16 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore mysqli_close($connection); ?> </select><br> <label for="name">Nominativo</label> <input id="name" name="nominativo" type="text" required><br> <label for="address">Indirizzo</label> <input id="address" name="indirizzo" type="text" required><br> <label for="telephone">Telefono</label> <input id="telephone" name="telefono" type="text" required><br> <input type="submit" value="Iscriviti"> </form> </body> </html> <html> <head> <title>Iscrizione</title> </head> <body> <?php $nominativo = $_POST['nominativo']; $indirizzo = $_POST['indirizzo']; $telefono = $_POST['telefono']; $ID_zona = $_POST['zona']; $ID_categoria = $_POST['categoria']; if ( strlen($nominativo) != 0 && strlen($indirizzo) != 0 && strlen($telefono) != 0) { $connection = mysqli_connect("localhost","root","","BdT"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL."; die(); } $query = " INSERT INTO Soci (nominativo, indirizzo, telefono, ID_zona) VALUES('$nominativo','$indirizzo','$telefono','$ID_zona');"; if (!mysqli_query($connection, $query)) { echo "Errore esecuzione comando SQL."; die(); } $query = " SELECT ID_Socio FROM Soci WHERE nominativo = '$nominativo' AND indirizzo = '$indirizzo' AND telefono = '$telefono';"; $result = mysqli_query($connection, $query); if (!$result) 1 Anno 2002 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 17 { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Errore esecuzione query SQL."; die(); } $row = mysqli_fetch_array($result); $ID_socio = $row[0]; $query = " INSERT INTO Categorie_Soci (ID_socio, ID_categoria) VALUES ($ID_socio, '$ID_categoria');"; if (!mysqli_query($connection, $query)) { echo "Errore esecuzione comando SQL." ; die(); } mysqli_free_result($result); mysqli_close($connection); echo " L’utente $nominativo &egrave stato aggiunto al database con identificativo $ID_socio."; } else echo "Dati inseriti non validi."; ?> </body> </html> È riportato di seguito il modulo web di iscrizione di un nuovo utente: 18 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore 2 Anno 2003 - Informatica ABACUS Testo Un vivaio vuole realizzare una base di dati per gestire le sue attività di vendita di piante e le sue attività esterne. Si vogliono memorizzare, oltre alle informazioni generali sulle diverse specie di piante, anche quelle relative alle specifiche piante presenti nel vivaio. Di ogni specie deve essere registrato il nome, un’immagine, una breve descrizione, informazioni relative al modo di coltivazione e alle caratteristiche dell’esposizione e infine se si tratta di pianta da interno o da esterno. Si vogliono inoltre registrare i dati relativi alle piante effettivamente presenti nel vivaio, raggruppate per specie, eventualmente suddivise in diversi tipi in base al prezzo di vendita. Per ogni specie (o per ogni tipo, se la specie è suddivisa in tipi), è necessario registrare il numero di esemplari presenti nel vivaio e il costo di ogni esemplare. Si vogliono inoltre gestire le informazioni relative al personale che lavora nel vivaio (agronomi, operai, amministrativi) registrando i dati anagrafici, la qualifica e, per gli agronomi, l’anno di assunzione nel vivaio. Ogni singola specie del vivaio è sotto la responsabilità di un agronomo. Le attività esterne del vivaio, quali ad esempio la potatura o la manutenzione dei giardini, sono svolte dal personale in base alla qualifica (in generale ogni lavoratore è in grado di svolgere più di un’attività) e sono caratterizzate da un codice, da un nome, da un costo orario. Per le attività esterne si vogliono mantenere tutte le informazioni relative ai clienti che richiedono le attività, in particolare se si tratta di privati o di aziende, la data di prenotazione e quella di effettuazione dell’intervento richiesto e se per l’intervento sono necessarie piante del vivaio. Il candidato consideri la situazione sopra descritta, precisi eventuali ipotesi aggiuntive e realizzi: •un’analisi della realtà di riferimento che illustri le premesse per i successivi passi della progettazione della base di dati; •uno schema concettuale della base di dati; •uno schema logico della base di dati; •la definizione delle relazioni della base di dati in linguaggio SQL; •le seguenti interrogazioni espresse in linguaggio SQL: 1dato il nome di una pianta, riportare quanti esemplari di quella pianta sono presenti nel vivaio; 2dato il nome di una stagione, visualizzare il nome delle piante che fioriscono in quella stagione; 3dato il nome di un intervento esterno, tra quelli previsti dal vivaio, riportare il nome e il telefono dei soggetti che hanno richiesto quell’intervento nel corso di un determinato anno solare; 4dato il nome di un agronomo, riportare quanti esemplari di piante sono sotto la sua responsabilità; 5visualizzare nome, descrizione e quantità di esemplari presenti nel vivaio, della pianta più economica da interno; 6 riportare nome degli interventi richiesti non ancora evasi con il nome e il telefono del richiedente. Il candidato sviluppi inoltre, a scelta, uno dei seguenti moduli: •Si vuole realizzare un sito Internet che presenti al pubblico il vivaio illustrandone i prodotti e le diverse attività. •Si vuole consentire la gestione delle attività esterne del vivaio attraverso una prenotazione online da parte dei clienti. Illustrare le modalità di realizzazione di questa funzione e gli strumenti tecnici adottabili. 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 19 2.1 Ipotesi aggiuntive •Per specie di pianta si è inteso uno specifico tipo di pianta (per esempio: Ficus Benjamin). •La classificazione delle piante presenti nel vivaio è stata fatta in base alla specie e al prezzo, che può variare, per esempio, in funzione della dimensione della pianta. •Le attività esterne sono espletate da un solo operatore alla volta. •Si registra solo l’utilizzo di piante del vivaio nelle prestazioni esterne, senza mantenere traccia di quali piante sono state eventualmente effettivamente utilizzate. •Un operatore può espletare più attività e un certo tipo di attività può essere espletato da più operatori. •La data di assunzione è prevista indistintamente per tutti i dipendenti, ma sarà avvalorata solo per gli agronomi. •È stata prevista, solo per gli agronomi, un’associazione di tipo 1:N tra l’entità che rappresenta il personale e l’entità che rappresenta le specie di piante. •Le prestazioni sono contabilizzate per unità orarie indivisibili, ovvero nel caso di prestazioni inferiori all’ora o che eccedano un numero intero di ore, la durata delle medesime viene arrotondata all’unità superiore. •Per registrare i dati relativi alle piante effettivamente presenti nel vivaio suddivise in tipi in base al prezzo di vendita, si è provveduto a identificare i diversi tipi di ogni specie tramite il codice della specie unitamente al prezzo di vendita. •Per quanto riguarda le fotografie delle piante si ipotizza una soluzione in cui i file delle fotografie – una per ogni specie – sono memorizzati in una specifica directory, mentre nella tabella relativa alle specie viene registrato il pathname dei file immagine (per esempio «Vivaio\Img\Ortensia.jpg»). 20 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore 2.2 Diagramma database Attività Qualifiche PK PK Id_Qualifica Clienti Id_Attività PK Descrizione_attività Costo_Orario FK1 Id_Qualifica E_I Descrizione Nominativo Indirizzo Telefono P_A Personale PK Prestazioni Id_Dipendente Personale_Prestazioni Nominativo FK1 Id_Qualifica Data_Assunzione PK,FK2 Id_Prestazione PK,FK1 Id_Dipend N_Ore Personale PK FK1 Id_Cliente PK Id_Prestazione FK1 Id_Attività FK2 Id_Cliente Data_Prenotazione Data_Prestazione Prestazioni_Piante Id_Specie PK,FK1 PK,FK2 PK Nome_Specie Immagine Descrizione Fioritura Coltivazione Esposizione Id_Agronomo E_I Id_Prestazione Id_Specie Prezzo Quantità Vivaio PK,FK1 Id_Specie PK Prezzo Quantità 2.3 Tabelle database Attività È la tabella in cui sono memorizzate le attività espletate e i servizi offerti dal personale del vivaio: Campo Id_Attivita R Tipo PK Intero Dim Descrizione Codice identificativo attività Descrizione_attivita Carattere Costo_Orario Singola precisione Costo orario attività Intero Qualifica abilitata all’espletamento dell’attività Id_Qualifica E_I FK 50 Carattere 1 Descrizione attività E: attività esterna, I: attività interna Chiave Primaria: Id_Attivita Chiave Esterna: Id_Qualifica → Qualifiche.Id_Qualifica 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 21 La seguente è una possibile istanza della tabella Attivita: Id_Attivita Descrizione_Attivita Costo_Orario Id_Qualifica E_I 1 Allestimento aiuole 50.00 2 E 2 Dosi concimazione 30.00 1 I 3 Cure anticrittogamiche 20.00 1 I 4 Sviluppo nuove specie 30.00 1 I 5 Potatura alberi 25.00 3 E 6 Allestimento prato 30.00 2 E 7 Rasatura prato 10.00 4 E 8 Potatura siepi 10.00 5 E 9 Allestimento impianto irrigazione 15.00 4 E 50 Gestione contabilità 10.00 5 I 51 Gestione lavori esterni 5.00 5 I Clienti In questa tabella sono censiti i clienti che richiedono prestazioni all’azienda relativa al vivaio: Campo Id_Cliente R Tipo PK Intero Nominativo Dim. Descrizione Codice cliente Carattere 30 Nominativo cliente Indirizzo Carattere 50 Indirizzo cliente Telefono Carattere 20 Telefono cliente P_A Carattere 1 Privato/Azienda Chiave Primaria: Id_Cliente La seguente è una possibile istanza della tabella Clienti: Id_Cliente Nominativo Indirizzo Telefono P_A 1 Rossi Giovanni Via del Mare, 12 0586611244 P 2 Verdi S.r.l. P.zza Matteotti, 32 0586421265 A 3 Martini Maria Via dell’Indipendenza, 2 0586854701 P Personale_Prestazioni Questa tabella stabilisce la relazione che sussiste tra le prestazioni effettuate e il personale che le ha espletate; essa serve a dividere in due associazioni 1:N l’associazione M:N che sussiste tra l’entità Prestazioni e l’entità Personale: Campo R Tipo Id_Prestazione PK Intero Codice identificativo prestazione Id_Dipendente PK Intero Codice identificativo dipendente Intero N. ore intervento N_Ore Dim. Descrizione Chiave Primaria: Id_Prestazione, Id_Dipendente Chiave Esterna: Id_Dipendente → Personale.Id_Dipendente Chiave Esterna: Id_Prestazione → Prestazioni.Id_Prestazione 22 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore La seguente è una possibile istanza della tabella Personale_Prestazioni: Id_Prestazione Id_Dipendente N_Ore 1 2 5 1 3 5 2 6 8 3 3 12 4 5 6 5 4 10 Personale In questa tabella sono censiti i dipendenti che lavorano nel vivaio: Campo Id_Dipendente R Tipo PK Intero Nominativo Dim. Codice identificativo dipendente Carattere Id_Qualifica FK Data_Assunzione Descrizione 50 Nominativo dipendente Intero Codice identificativo qualifica dipendente Data Data assunzione (valorizzato solo per i di­ pendenti con qualifica di «agronomo») Chiave Primaria: Id_Dipendente Chiave Esterna: Id_Qualifica → Qualifiche.Id_Qualifica La seguente è una possibile istanza della tabella Personale: Id_Dipendente Nominativo Id_Qualifica Data_Assunzione 1 Neri Giovanni 1 12/02/2001 2 Marcucci Alfredo 1 14/10/1998 3 Giannetti Marco 2 4 Barbieri Marta 5 5 Giannetti Giuseppe 4 6 Alfredini Mauro 3 7 Zani Mario 1 8 Landi Francesco 2 24/11/1999 Prestazioni_Piante In questa tabella sono definite le relazioni che sussistono tra le prestazioni effettuate per conto dei clienti e le eventuali piante fornite contestualmente a esse; la tabella serve a dividere in due associazioni 1:N l’associazione M:N che sussiste tra l’entità Prestazioni e l’entità Specie: Campo R Tipo Id_Prestazione PK Intero Codice identificativo prestazione Id_Specie PK Intero Codice identificativo pianta (specie) Prezzo PK Singola precisione Prezzo del tipo di pianta (specie) Intero Numero di esemplari di pianta impiegati Quantita Dim. Descrizione Chiave Primaria: Id_Prestazione, Id_Specie, Prezzo Chiave Esterna: Id_Prestazione → Prestazioni.Id_Prestazione Chiave Esterna: Id_Specie → Specie.Id_Specie 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 23 La seguente è una possibile istanza della tabella Prestazioni_Piante: Id_Prestazione Id_Specie Prezzo Quantita 1 11 10 3 1 12 30 5 Prestazioni Questa tabella rappresenta il registro cronologico delle prestazioni che il vivaio ha offerto ai suoi clienti nel tempo: Campo R Tipo Dim. Descrizione Id_Prestazione PK Intero Codice identificativo prestazione (valore numerico auto-incrementante) Id_Attivita FK Intero Codice identificativo attività Id_Cliente FK Intero Codice identificativo cliente Data_Prenotazione Data Data prenotazione Data_Prestazione Data Data intervento (non valorizzata per presta­ zioni non ancora effettuate) Chiave Primaria: Id_Prestazione Chiave Esterna: Id_Attivita → Attivita.Id_Attivita Chiave Esterna: Id_Cliente → Clienti.Id_Cliente La seguente è una possibile istanza della tabella Prestazioni: Id_Prestazione Id_Attivita Id_Cliente Data_Prenotazione Data_Prestazione 1 1 1 12/10/2002 22/10/2002 2 5 2 12/12/2002 12/01/2003 3 6 3 22/04/2003 30/04/2003 4 7 1 22/05/2003 5 9 2 12/06/2003 Qualifiche In questa tabella sono memorizzate le varie tipologie di qualifica dei dipendenti del vivaio: Campo Id_Qualifica R Tipo PK Intero Descrizione Carattere Dim. Descrizione Codice identificativo qualifica 50 Descrizione qualifica Chiave Primaria: Id_Qualifica La seguente è una possibile istanza della tabella Qualifiche: 24 Id_Qualifica Descrizione 1 Agronomo 2 Operaio giardini 3 Operaio potatura 4 Operaio generico 5 Amministrativo Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Specie In questa tabella sono memorizzate le varie specie di piante catalogate: Campo Id_Specie R Tipo PK Intero Dim. Descrizione Codice identificativo pianta (specie) Nome_Specie Carattere Immagine Carattere 100 Pathname immagine pianta Descrizione Carattere 1000 Descrizione pianta Fioritura Carattere 15 Stagione fioritura Coltivazione Carattere 2000 Descrizione dettagli coltivazione Esposizione Carattere 20 Tipologia di esposizione pianta Id_Agronomo FK E_I 50 Intero Nome pianta (specie) Codice identificativo dipendente (agronomo) esperto della specie Carattere 1 E: pianta da esterno, I: pianta da interno Chiave Primaria: Id_Specie Chiave Esterna: Id_Agronomo → Personale.Id_Dipendente La seguente è una possibile istanza della tabella Specie: Id Specie Nome Specie Immagine 1 Ficus Benjamin 2 Descrizione Fioritura Coltivazione Esposizione Id Agronomo E_I Da appartamento Mezza ombra 1 I Dracena Da appartamento Piena luce 1 I 3 Yucca Da appartamento Piena luce 1 I 4 Pino Da esterno Pieno sole 1 E 5 Buganvillea Da esterno Estate Pieno sole 2 E 6 Margherita Da esterno Primavera Pieno sole 2 E 7 Lavanda Da esterno Primavera Pieno sole 2 E 8 Ibisco Da esterno Estate Pieno sole 2 E 9 Ortensia Da esterno Estate Mezza ombra 7 E 10 Dieffen-bachia Da appartamento Piena luce 7 I 11 Rosa rossa Da esterno Primavera Pieno sole 2 E 12 Rosa tea Da esterno Primavera Pieno sole 2 E Vivaio In questa tabella sono memorizzati i dati dei vari esemplari di pianta presenti nel vivaio, suddivisi in funzione della specie di appartenenza e del prezzo di vendita (quest’ultimo definito, per esempio, in base alla dimensione della pianta): Campo R Tipo Id_Specie PK Intero Codice identificativo pianta (specie) Prezzo PK Singola precisione Prezzo del tipo di pianta (specie) Intero Numero di esemplari di pianta di un certo tipo Quantita Dim. Descrizione Chiave Primaria: Id_Specie, Prezzo Chiave Esterna: Id_Specie → Specie.Id_Specie 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 25 La seguente è una possibile istanza della tabella Vivaio: Id_Specie Prezzo Quantita 1 10.00 50 1 20.00 100 1 30.00 80 2 30.00 100 2 40.00 200 3 10.00 50 3 20.00 150 5 80.00 60 5 100.00 20 6 10.00 50 6 20.00 80 6 40.00 10 9 5.00 100 9 10.00 110 9 20.00 120 10 30.00 50 11 10.00 30 11 20.00 50 12 30.00 60 2.4 DB-schema CREATE TABLE Clienti( Id_Cliente INTEGER NOT NULL, Nominativo VARCHAR(30) NOT NULL, Indirizzo VARCHAR(50) NOT NULL, Telefono VARCHAR(20) NOT NULL, P_A VARCHAR(1) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Cliente) ); CREATE TABLE Qualifiche( Id_Qualifica INTEGER NOT NULL, Descrizione VARCHAR(50) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Qualifica) ); CREATE TABLE Attivita( Id_Attivita INTEGER NOT NULL, Descrizione_attivita VARCHAR(50) NOT NULL, Costo_Orario REAL NOT NULL, Id_Qualifica INTEGER NOT NULL, E_I VARCHAR(1) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Attivita), 26 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore CONSTRAINT Q ualificheAttivita FOREIGN KEY(Id_Qualifica) REFERENCES Qualifiche(Id_Qualifica) ); CREATE TABLE Personale( Id_Dipendente INTEGER NOT NULL, Nominativo VARCHAR(50) NOT NULL, Id_Qualifica INTEGER NOT NULL, Data_Assunzione DATE, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Dipendente), CONSTRAINT QualifichePersonale FOREIGN KEY(Id_Qualifica) REFERENCES Qualifiche(Id_Qualifica) ); CREATE TABLE Prestazioni( Id_Prestazione INTEGER NOT NULL AUTO_INCREMENT, Id_Attivita INTEGER NOT NULL, Id_Cliente INTEGER NOT NULL, Data_Prenotazione DATE NOT NULL, Data_Prestazione DATE, CONSTRAINT AttivitaPrestazioni FOREIGN KEY(Id_Attivita) REFERENCES Attivita(Id_Attivita), CONSTRAINT ClientiPrestazioni FOREIGN KEY(Id_Cliente) REFERENCES Clienti(Id_Cliente), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Prestazione) ); CREATE TABLE Specie( Id_Specie INTEGER NOT NULL, Nome_Specie VARCHAR(50) NOT NULL, Immagine VARCHAR(100), Descrizione VARCHAR(1000), Fioritura VARCHAR(15), Coltivazione VARCHAR(2000), Esposizione VARCHAR(20), Id_Agronomo INTEGER, E_I VARCHAR(1) NOT NULL, CONSTRAINT PersonaleSpecie FOREIGN KEY(Id_Agronomo) REFERENCES Personale(Id_Dipendente), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Specie) ); CREATE TABLE Vivaio( Id_Specie INTEGER NOT NULL, Prezzo REAL NOT NULL, Quantita INTEGER NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Specie, Prezzo), CONSTRAINT SpecieVivaio FOREIGN KEY(Id_Specie) REFERENCES Specie(Id_Specie) ); 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 27 CREATE TABLE Personale_Prestazioni( Id_Prestazione INTEGER NOT NULL, Id_Dipendente INTEGER NOT NULL, N_Ore INTEGER NOT NULL, CONSTRAINT PersoanalePersonale_Prestazioni FOREIGN KEY(Id_Dipendente) REFERENCES Personale(Id_Dipendente), CONSTRAINT PrestazioniPersonale_Prestazioni FOREIGN KEY(Id_Prestazione) REFERENCES Prestazioni(Id_Prestazione), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Prestazione, Id_Dipendente) ); CREATE TABLE Prestazioni_Piante( Id_Prestazione INTEGER NOT NULL, Id_Specie INTEGER NOT NULL, Prezzo REAL NOT NULL, Quantita INTEGER NOT NULL, CONSTRAINT PrestazioniPrestazioni_Piante FOREIGN KEY(Id_Prestazione) REFERENCES Prestazioni(Id_Prestazione), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Prestazione, Id_Specie, Prezzo), CONSTRAINT SpeciePrestazioni_Piante FOREIGN KEY(Id_Specie) REFERENCES Specie(Id_Specie) ); 2.5 Query 1 SELECT Nome_Specie, SUM(Quantita) AS Numero_Esemplari FROM Specie INNER JOIN Vivaio ON Specie.Id_Specie = Vivaio.Id_Specie WHERE Nome_Specie = '…' GROUP BY Nome_Specie; 2 SELECT Specie.Nome_Specie FROM Specie WHERE Fioritura = '…'; 3 SELECT Clienti.Nominativo, Clienti.Telefono FROM Clienti INNER JOIN ( Attivita INNER JOIN Prestazioni ON Attivita.Id_attivita = Prestazioni.Id_attivita) ON Clienti.Id_Cliente = Prestazioni.Id_Cliente 28 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore WHERE YEAR(Prestazioni.Data_Prenotazione) = … AND Attivita.Descrizione_attivita = '…'; 4 SELECT SUM(Vivaio.Quantita) AS N_Esemplari FROM Qualifiche INNER JOIN ( Personale INNER JOIN ( Specie INNER JOIN Vivaio ON Specie.Id_Specie = Vivaio.Id_Specie) ON Personale.Id_Dipendente = Specie.Id_Agronomo) ON Qualifiche.Id_Qualifica = Personale.Id_Qualifica WHERE Qualifiche.Descrizione = 'Agronomo' AND Personale.Nominativo = '…'; 5 SELECT Specie.Nome_Specie, Specie.Descrizione, Vivaio.Quantita FROM Specie INNER JOIN Vivaio ON Specie.Id_Specie = Vivaio. Id_Specie WHERE Specie.E_I = 'I' AND Vivaio.Prezzo IN (SELECT MIN(Prezzo) FROM Specie, Vivaio WHERE Specie.E_I = 'I' AND Specie.Id_Specie = Vivaio.Id_Specie ); 6 SELECT A ttivita.Descrizione_attivita, Clienti.Nominativo, Clienti.Telefono FROM Clienti INNER JOIN ( Attivita INNER JOIN Prestazioni ON Attivita.Id_Attivita = Prestazioni.Id_Attivita) ON Clienti.Id_Cliente = Prestazioni.Id_Cliente WHERE Prestazioni.Data_Prestazione IS NULL; 2.6 Sito web Un sito web di presentazione del vivaio dovrebbe fornire informazioni relative alle piante in vendita; a questo scopo i due script PHP che seguono consentono rispettivamente di selezionare una delle specie di pianta e di visualizzarne la fotografia e le notizie relative. Si è ipotizzato che il server My-SQL sia in esecuzione sullo stesso computer del web server e che l’accesso al database «Vivaio» venga effettuato come utente «root» privo di password; inoltre le pagine web sono completamente prive di struttura grafica. 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 29 <html> <head> <title>Richiesta informazioni pianta</title> </head> <body> Selezionare la specie di interesse: <?php $connection = mysqli_connect("localhost", "root", "", "Vivaio"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> <form action="informazioni.php" method="GET"> <select name="pianta"> <?php $query = "SELECT Id_Specie, Nome_Specie FROM Specie;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessun socio presente." ; die(); } while ($row = mysqli_fetch_array($result)) echo "<option value=\"$row[0]\">$row[1]</option>"; mysqli_free_result($result); mysqli_close($connection); ?> </select> <br> <input type="submit" value="Visualizza informazioni"> </form> </body> </html> <html> <head> <title>Informazioni pianta</title> </head> <body> 30 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore <?php $specie = $_GET['pianta']; if (strlen($specie) == 0) { echo "Errore passaggio parametro." ; die(); } $connection = mysqli_connect("localhost", "root", "", "Vivaio"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } $query = "SELECT Specie.Nome_Specie, Specie.Immagine, Specie.Descrizione, Specie.Fioritura, Specie.Coltivazione, Specie.Esposizione, Vivaio.Prezzo, Vivaio.Quantita FROM Specie INNER JOIN Vivaio ON Specie.Id_specie = Vivaio.Id_specie WHERE Specie.Id_specie = $specie;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Pianta non trovata." ; die(); } else { $row = mysqli_fetch_array($result); $pianta = $row[0]; if (!is_null($pianta)) echo "<b>Pianta: </b>$pianta<br><br>"; $foto = $row[1]; if (!is_null($foto)) echo "<b>Immagine:</b><br><img src=\"$foto\"><br><br>"; $descrizione = $row[2]; if (!is_null($descrizione)) echo "<b>Descrizione: </b>$descrizione<br><br>"; $fioritura = $row[3]; if (!is_null($fioritura)) echo "<b>Fioritura: </b>$fioritura<br><br>"; $coltivazione = $row[4]; if (!is_null($coltivazione)) echo "<b>Coltivazione: </b>$coltivazione<br><br>"; 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 31 $esposizione = $row[5]; if (!is_null($esposizione)) echo "<b>Esposizione: </b>$esposizione<br><br>"; $prezzo = $row[6]; if (!is_null($prezzo)) echo "<b>Prezzo: </b>$prezzo Euro<br><br>"; $quantita = $row[7]; if (!is_null($quantita)) echo "<b>Esemplari disponibili: </b>$quantita<br><br>"; } mysqli_free_result($result); mysqli_close($connection); ?> <br> <a href="http://localhost/vivaio/richiesta.php"> Ricerca informazioni su un’altra pianta. </a> </body> </html> Sono riportate di seguito le pagine web dinamiche create dai due script PHP: 32 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Relativamente alla possibilità di prenotare online le prestazioni da parte dei clienti già registrati, date le caratteristiche e la natura dell’azienda di gestione del vivaio che probabilmente non dispone di personale specializzato per la gestione di un server per ospitare il sito web, la soluzione più indicata è quella di acquistare un servizio di hosting del sito da un fornitore di servizi web (spesso è possibile acquistare il servizio di hosting del sito insieme alla registrazione del dominio): questa soluzione è senz’altro la migliore tenuto conto che il sito deve essere operativo 24 ore su 24 e 7 giorni su 7, ed è anche economica. È necessario acquistare, oltre allo spazio web per ospitare il sito, l’integrazione dell’interprete PHP nel server web e la disponibilità di un database My-SQL per la gestione del database: si tratta in ogni caso di un pacchetto molto comune nell’offerta dei fornitori di servizi web. I due script PHP che seguono consentono rispettivamente di selezionare il cliente1 che richiede la prestazione e la prestazione richiesta e di effettuarne la prenotazione visualizzando il codice generato automaticamente. Si è ipotizzato che il server My-SQL sia in esecuzione sullo stesso computer del web server e che l’accesso al database “Vivaio” venga effettuato come utente “root” privo di password; inoltre le pagine web sono completamente prive di struttura grafica. 1. In un’applicazione reale il cliente sarà automaticamente identificato al momento che accede alla sezione riservata del sito web mediante le credenziali (username/password) generate al momento della registrazione. <html> <head> <title>Richiesta prestazione</title> </head> <body> Selezionare il cliente e la prestazione richiesta: <?php $connection = mysqli_connect("localhost", "root", "", "Vivaio"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> <form action="prenotazione.php" method="POST"> <label for="cliente">Cliente</label> <select id="cliente" name="cliente"> <?php $query = "SELECT ID_Cliente, Nominativo FROM Clienti;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } while ($row = mysqli_fetch_array($result)) 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 33 echo "<option value=\"$row[0]\">$row[1]</option>"; mysqli_free_result($result); ?> </select><br> <label for="prestazione">Prestazione</label> <select id="prestazione" name="prestazione"> <?php $query = "SELECT ID_Attivita, Descrizione_attivita FROM Attivita;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } while ($row = mysqli_fetch_array($result)) echo "<option value=\"$row[0]\">$row[1]</option>"; mysqli_free_result($result); mysqli_close($connection); ?> </select><br> <input type="submit" value="Prenota"> </form> </body> </html> <html> <head> <title>Prenotazione</title> </head> <body> <?php $ID_attivita = $_POST['prestazione']; $ID_cliente = $_POST['cliente']; $connection = mysqli_connect("localhost","root","","Vivaio"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } $query = " INSERT INTO Prestazioni (Id_attivita, Id_Cliente, Data_Prenotazione) VALUES ($ID_attivita, $ID_cliente, CURRENT_DATE());"; if (!mysqli_query($connection, $query)) { echo "Errore esecuzione comando SQL." ; die(); } 34 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore $query = " SELECT ID_Prestazione FROM Prestazioni WHERE Id_Attivita = $ID_attivita AND Id_Cliente = $ID_cliente ORDER BY Data_prenotazione DESC;”; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } if (mysqli_num_rows($result) == 0) { echo "Errore esecuzione query SQL."; die(); } $row = mysqli_fetch_array($result); $ID_prestazione = $row[0]; mysqli_free_result($result); mysqli_close($connection); echo "La prestazione &egrave stata prenotata con codice $ID_prestazione."; ?> </body> </html> È riportato di seguito il modulo web per la prenotazione di una prestazione da parte di un cliente: 2 Anno 2003 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 35 3 Anno 2008 - Informatica ABACUS Testo In occasioni delle Olimpiadi Internazionali di Informatica 2008, la società organizzatrice desidera realizzare un sistema informatico per la gestione delle gare e degli «atleti». La base di dati deve consentire la memorizzazione delle informazioni •degli atleti, che possono partecipare alle gare sia singolarmente sia raggruppati in squadre; •delle gare nelle varie fasi; •delle sedi di gara. Le Olimpiadi prevedono una fase scolastica (in ciascun istituto scolastico partecipante), una fase regionale, una finale nazionale e la gara internazionale che designerà il vincitore e la squadra vincitrice. Il candidato, fatte le opportune ipotesi aggiuntive, realizzi: 1un’analisi della realtà di riferimento individuando le possibili soluzioni e scelga quella che a suo motivato giudizio è la più idonea a rispondere alle specifiche indicate; 2uno schema concettuale della base di dati; 3uno schema logico della base di dati; 4la definizione delle relazioni della base di dati in linguaggio SQL; 5le seguenti interrogazioni espresse in linguaggio SQL: • stampare l’elenco degli atleti raggruppati per squadre per ogni singola fase; • dato il nome di un atleta stampare i risultati ottenuti nelle diverse gare alle quali ha partecipato; • stampare il calendario delle gare; • stampare una scheda informativa (cognome, nome, istituto scolastico di provenienza, nazionalità) del vincitore e della squadra vincitrice; • stampare la classifica per ciascuna gara (a parità di punteggio vengono privilegiati gli atleti più giovani); • aggiornare, per ciascuna fase (scolastica, regionale, nazionale, internazionale) gli eventuali punteggi record; • calcolare il punteggio medio ottenuto durante la prima selezione per ciascun istituto scolastico; • stampare per ciascuna squadra il numero di «atleti» partecipanti e l’età media; 6l’interfaccia utente che il candidato intende proporre per interagire con la base di dati e codificare in un linguaggio di programmazione a scelta un segmento significativo del progetto realizzato; 7un sito Internet che presenti al pubblico le classifiche delle diverse gare. 3.1 Ipotesi aggiuntive •Nella fase scolastica ogni atleta partecipa a titolo personale e non fa parte di nessuna squadra. 36 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore 3.2 Diagramma database Sedi PK Fasi PK Fase Id_Sede Scuole PK Denominazione Indirizzo Città Regione Nazione Record_Singolo Record_Squadre Id_Scuole Denominazione Indirizzo Città Nazione Atleti Squadre PK Gare Squadre_Gare Id_Squadre PK,FK2 PK,FK1 Denominazione Nazione Id_Squadra Id_Gara Punteggio PK Id_Gara FK1 Fase Data Id_Sede FK2 PK Id_Atleta FK1 Cognome Nome Luogo_nascita Data_nascita Id_Scuola Atleti_Gare PK,FK1 PK,FK2 Atleti_Squadre PK,FK1 PK,FK2 Id_Atleta Id_Gara Punteggio Id_Atleta Id_Squadra 3.3 Tabelle database Atleti È la tabella in cui sono censiti gli atleti partecipanti alle olimpiadi: Campo R Tipo Id_Atleta PK Intero Dim. Descrizione Identificativo atleta Cognome Carattere 50 Cognome Nome Carattere 50 Nome Luogo_nascita Carattere 50 Luogo di nascita Data_nascita Data Data di nascita Intero Identificativo scuola di appartenenza Id_Scuola FK Chiave Primaria: Id_Atleta Chiave Esterna: Id_Scuola → Scuole.Id_Scuola La seguente è una possibile istanza della tabella Atleti: 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 37 Id_Atleta Cognome Nome Luogo_nascita Data_nascita Id_Scuola 1 Rossi Mario Livorno 1991-10-21 1 2 Grieco Samantha Pisa 1990-11-02 10 3 Bianchi Filippo Cecina 1990-6-06 3 4 Bernardini Elena Pavia 1990-6-04 1 5 Pulowski Rodion Mosca 1992-8-03 5 6 Poli Marco Firenze 1992-5-13 10 7 Seri Antonio Mestre 1991-1-1 7 8 Biasci Riccardo Milano 1992-7-8 4 10 Scott Philip New York 1990-7-29 13 11 Kyoky Rachél Tokyo 1992-10-24 9 Atleti_Gare È la tabella in cui sono fissate le associazioni tra gli atleti e le gare a cui essi hanno partecipato a titolo individuale con il punteggio conseguito: Campo R Tipo Id_Atleta PK Intero Identificativo atleta Id_Gara PK Intero Identificativo gara Intero Punteggio riportato Punteggio Dim. Descrizione Chiave Primaria: Id_Atleta, Id_Gara Chiave Esterna: Id_Atleta → Atleti.Id_Atleta Chiave Esterna: Id_Gara → Gare.Id_Gara La seguente è una possibile istanza della tabella Atleti_Gare: 38 Id_Atleta Id_Gara Punteggio 1 1 180 2 10 146 3 3 254 4 1 186 5 5 24 6 10 273 7 7 279 8 4 8 10 13 268 11 9 17 12 2 263 13 12 60 14 4 272 15 13 128 16 13 21 17 5 180 18 9 295 19 10 200 20 3 164 21 4 181 22 13 0 23 1 141 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Atleti_Squadre È la tabella che permette di definire la composizione delle varie squadre che partecipano all’Olimpiade: Campo R Tipo Id_Atleta PK Intero Dim. Descrizione Identificativo atleta Id_Squadra PK Intero Identificativo squadra di appartenenza Chiave Primaria: Id_Atleta, Id_Squadra Chiave Esterna: Id_Atleta → Atleti.Id_Atleta Chiave Esterna: Id_Squadra → Squadre.Id_Squadra La seguente è una possibile istanza della tabella Atleti_Squadre: Id_Atleta Id_Squadra 2 10 3 3 4 6 5 1 6 10 7 7 8 5 10 13 11 9 13 12 14 5 15 13 16 13 18 9 20 3 21 5 22 13 23 5 26 1 27 11 28 3 29 5 Fasi In questa tabella sono censite le varie fasi in cui si articola l’Olimpiade (scolastica, regionale, nazionale e internazionale) con il record riportato sia a livello di singolo partecipante sia di squadra in ognuna di esse: Campo Fase R PK Tipo Carattere Dim. 50 Descrizione Fase Olimpiadi Record_Singolo Intero Punteggio record per partecipante singolo Record_Squadra Intero Punteggio record per gare a squadre Chiave Primaria: Fase 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 39 La seguente è una possibile istanza della tabella Fasi: Fase Record_Singolo Record_Squadra INTERNAZIONALE 0 0 NAZIONALE 0 0 REGIONALE 0 0 SCOLASTICA 0 0 Gare È la tabella che fissa il calendario (luogo, data, …) delle varie gare su cui si articola l’Olimpiade: Campo R Tipo Id_Gara PK Intero Fase FK Carattere Data Id_Sede FK Dim. Descrizione Identificativo gara 50 Fase Data Data gara Intero Identificativo sede di svolgimento Chiave Primaria: Id_Gara Chiave Esterna: Fase → Fasi.Fase Chiave Esterna: Id_Sede → Sedi.Id_Sede La seguente è una possibile istanza della tabella Gare: 40 Id_Gara Fase Data Id_Sede 1 SCOLASTICA 2007-10-20 1 2 SCOLASTICA 2007-10-20 2 3 SCOLASTICA 2007-10-20 3 4 SCOLASTICA 2007-10-20 4 5 SCOLASTICA 2007-10-20 5 7 SCOLASTICA 2007-10-20 7 8 SCOLASTICA 2007-10-20 8 9 SCOLASTICA 2007-10-20 9 10 SCOLASTICA 2007-10-20 10 11 SCOLASTICA 2007-10-20 11 12 SCOLASTICA 2007-10-20 12 13 SCOLASTICA 2007-10-20 13 14 REGIONALE 2008-4-12 1 15 REGIONALE 2008-4-12 7 16 REGIONALE 2008-4-12 4 17 REGIONALE 2008-4-12 11 18 REGIONALE 2008-4-12 9 19 REGIONALE 2008-4-12 12 20 REGIONALE 2008-4-12 13 21 NAZIONALE 2008-7-3 11 22 NAZIONALE 2008-7-3 12 23 NAZIONALE 2008-7-3 13 24 NAZIONALE 2008-7-3 9 25 INTERNAZIONALE 2008-11-21 12 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Scuole Contiene l’anagrafica delle scuole a cui appartengono i vari atleti partecipanti: Campo Id_Scuola R Tipo PK Intero Dim. Descrizione Identificativo scuola Denominazione Carattere 50 Denominazione scuola Indirizzo Carattere 50 Indirizzo Citta Carattere 50 Città Nazione Carattere 50 Nazione Chiave Primaria: Id_Scuola La seguente è una possibile istanza della tabella Scuole: Id_Scuola Denominazione Indirizzo Citta Nazione 1 ITI G. Galilei Via Galilei Livorno Italia 2 LS E. Fermi Via del Pero Belluno Italia 3 ITI L. Da Vinci Via Roma Grosseto Italia 4 ITI A. Volta Viale dell’Indipendenza Milano Italia 5 ITC N. Macchiavelli Via Copernico Pisa Italia 7 ITC M. Polo Via Del Corso Venezia Italia 8 ITI A. Pacinotti Corso Italia Casale Monferrato Italia 9 Information Technology Institute of London Oxford Street London United Kingdom 10 ITI E. Mattei Via Dante Prato Italia 11 ITI E. Majorana Via Garibaldi Grugliasco Italia 12 High Tech Institute Fifth Avenue New York City USA 13 Escuela Tecnica J. Bernoulli Las Ramblas Barcelona Espana Sedi Contiene l’anagrafica delle sedi (normalmente, ma non necessariamente, istituti scolastici) che ospitano le varie prove dell’Olimpiade: Campo R Tipo Id_Sede PK Intero Dim. Descrizione Identificativo sede svolgimento prove Denominazione Carattere 50 Denominazione Indirizzo Carattere 50 Indirizzo Citta Carattere 50 Città Regione Carattere 50 Regione Nazione Carattere 50 Nazione Chiave Primaria: Id_Sede La seguente è una possibile istanza della tabella Sedi: 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 41 Id_Sede Denominazione Indirizzo Citta Regione Nazione 1 ITI G. Galilei Via Galilei Livorno Toscana Italia 2 LS E. Fermi Via del Pero Belluno Veneto Italia 3 ITI L. Da Vinci Via Roma Grosseto Toscana Italia 4 ITI A. Volta Viale dell’Indipendenza Milano Lombardia Italia 5 ITC N. Macchiavelli Via Copernico Pisa Toscana Italia 7 ITC M. Polo Via Del Corso Venezia Veneto Italia 8 ITI A. Pacinotti Corso Italia Casale Monferrato Piemonte Italia 9 Information Technology Institute of London Oxford Street London Greater London United Kingdom 10 ITI E. Mattei Via Dante Prato Toscana Italia 11 ITI E. Majorana Via Garibaldi Grugliasco Piemonte Italia 12 High Tech Institute Fifth Avenue New York City New York USA 13 Escuela Tecnica J. Bernoulli Las Ramblas Barcelona Catalunya Espana Squadre È la tabella relativa all’elenco delle squadre che partecipano alla competizione: Campo Id_Squadra R Tipo PK Intero Dim. Descrizione Identificativo squadra Denominazione Carattere 50 Denominazione squadra Nazione Carattere 50 Nazionalità squadra Chiave Primaria: Id_Squadra La seguente è una possibile istanza della tabella Squadre: 42 Id_Squadra Denominazione Nazione 1 Squadra Uno Italia 2 Squadra Due Italia 3 Squadra Tre Italia 4 Squadra Quattro Italia 5 Squadra Cinque Italia 6 Squadra Sei Italia 7 Squadra Sette Italia 8 Squadra Otto Italia 9 Squadra Nove Regno Unito 10 Squadra Dieci Italia 11 Squadra Undici Italia 12 Squadra Dodici Italia 13 Squadra Tredici Italia 14 Squadra Quattordici Italia 15 Squadra Quindici USA 16 Squadra Sedici Spagna Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Squadre_Gare In questa tabella viene fissata l’associazione tra gare e squadre ovvero quali squadre hanno partecipato alle varie gare dell’Olimpiade. Campo R Tipo Id_Squadra PK Intero Identificativo squadra Id_Gara PK Intero Identificativo gara Intero punteggio riportato Punteggio Dim. Descrizione Chiave Primaria: Id_Squadra, Id_Gara Chiave Esterna: Id_Gara → Gare.Id_Gara Chiave Esterna: Id_Squadra → Squadre.Id_Squadra La seguente è una possibile istanza della tabella Squadre_Gare: Id_Squadra Id_Gara Punteggio 1 5 200 2 7 150 2 14 300 2 18 120 3 3 210 4 3 118 5 4 120 6 1 140 7 7 200 8 1 220 9 9 180 10 10 185 11 11 250 12 4 210 12 12 260 12 16 120 13 13 110 14 7 190 3.4 DB-schema CREATE TABLE Fasi( Fase VARCHAR(50), Record_Singolo INTEGER, Record_Squadra INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Fase) ); CREATE TABLE Scuole( Id_Scuola INTEGER, Denominazione VARCHAR(50), 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 43 Indirizzo VARCHAR(50), Citta VARCHAR(50), Nazione VARCHAR(50), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Scuola) ); CREATE TABLE Sedi( Id_Sede INTEGER, Denominazione VARCHAR(50), Indirizzo VARCHAR(50), Citta VARCHAR(50), Regione VARCHAR(50), Nazione VARCHAR(50), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Sede) ); CREATE TABLE Squadre( Id_Squadra INTEGER, Denominazione VARCHAR(50), Nazione VARCHAR(50), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Squadra) ); CREATE TABLE Atleti( Id_Atleta INTEGER, Cognome VARCHAR(50), Nome VARCHAR(50), Luogo_nascita VARCHAR(50), Data_nascita DATE, Id_Scuola INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Atleta), CONSTRAINT ScuoleAtleti FOREIGN KEY(Id_Scuola) REFERENCES Scuole(Id_Scuola) ); CREATE TABLE Atleti_Squadre( Id_Atleta INTEGER, Id_Squadra INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Atleta,Id_Squadra), CONSTRAINT AtletiAtleti_Squadre FOREIGN KEY(Id_Atleta) REFERENCES Atleti(Id_Atleta), CONSTRAINT SquadreAtleti_Squadre FOREIGN KEY(Id_Squadra) REFERENCES Squadre(Id_Squadra) ); CREATE TABLE Gare( Id_Gara INTEGER, Fase VARCHAR(50), Data DATE, 44 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Id_Sede INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Gara), CONSTRAINT FasiGare FOREIGN KEY(Fase) REFERENCES Fasi(Fase), CONSTRAINT SediGare FOREIGN KEY(Id_Sede) REFERENCES Sedi(Id_Sede) ); CREATE TABLE Squadre_Gare( Id_Squadra INTEGER, Id_Gara INTEGER, Punteggio INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Squadra, Id_Gara), CONSTRAINT GareSquadre_Gare FOREIGN KEY(Id_Gara) REFERENCES Gare(Id_Gara), CONSTRAINT SquadreSquadre_Gare FOREIGN KEY(Id_Squadra) REFERENCES Squadre(Id_Squadra) ); CREATE TABLE Atleti_Gare( Id_Atleta INTEGER, Id_Gara INTEGER, Punteggio INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Atleta, Id_Gara), CONSTRAINT AtletiAtleti_Gare FOREIGN KEY(Id_Atleta) REFERENCES Atleti(Id_Atleta), CONSTRAINT GareAtleti_Gare FOREIGN KEY(Id_Gara) REFERENCES Gare(Id_Gara) ); 3.5 Query a SELECT G are.Fase, Squadre.Denominazione, Squadre.Nazione, Atleti.Cognome, Atleti.Nome, Atleti.Data_nascita FROM Gare, Atleti, Squadre, Atleti_Squadre, Squadre_Gare WHERE Squadre.Id_Squadra = Squadre_Gare.Id_Squadra AND Squadre.Id_Squadra = Atleti_Squadre.Id_Squadra AND Atleti.Id_Atleta = Atleti_Squadre.Id_Atleta AND Gare.Id_Gara = Squadre_Gare.Id_Gara ORDER BY Gare.Fase, Squadre.Denominazione, Squadre.Nazione, Atleti.Cognome, Atleti.Nome, Atleti.Data_nascita; b La soluzione fornita presuppone che la richiesta formulata sia relativa al risultato ottenuto dagli atleti come singoli partecipanti e non come membri di una squadra. 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 45 SELECT Gare.Fase, Gare.Data, Sedi.Denominazione, Atleti.Cognome, Atleti.Nome, Atleti_Gare.Punteggio FROM Sedi, Gare, Atleti, Atleti_Gare WHERE Atleti.Id_Atleta = Atleti_Gare.Id_Atleta AND Gare.Id_Gara = Atleti_Gare.Id_Gara AND Sedi.Id_Sede = Gare.Id_Sede AND Atleti.Cognome = '…' AND Atleti.Nome = '…'; c SELECT G are.Data, Gare.Fase, Sedi.Denominazione, Sedi.Indirizzo, Sedi.Citta, Sedi.Regione, Sedi.Nazione FROM Gare, Sedi WHERE Sedi.Id_Sede = Gare.Id_Sede; d1 Vincitore come partecipante singolo: SELECT A tleti.cognome, Atleti.Nome, Scuole.Denominazione, Scuole.Nazione FROM Scuole, Atleti, Atleti_Gare, Gare WHERE Atleti.Id_atleta = Atleti_Gare.Id_Atleta AND Gare.Id_gara = Atleti_Gare.Id_Gara AND Scuole.Id_scuola = Atleti.Id_Scuola AND Gare.Fase = 'INTERNAZIONALE' AND Punteggio = ( SELECT MAX(Punteggio) AS Massimo FROM Atleti_Gare, Gare WHERE Atleti_Gare.Id_Gara = Gare.Id_Gara AND Gare.Fase = 'INTERNAZIONALE'); d2 Squadra vincitrice: SELECT S quadre.denominazione, Squadre.nazione, Squadre_Gare.Punteggio FROM Squadre, Squadre_Gare, Gare WHERE Squadre.Id_squadra = Squadre_Gare.Id_Squadra AND Gare.Id_gara = Squadre_Gare.Id_Gara AND Gare.Fase = 'INTERNAZIONALE' AND Squadre_Gare.Punteggio = ( SELECT MAX(Punteggio) AS Massimo FROM Squadre_Gare, Gare WHERE Squadre_Gare.Id_ Gara = Gare.Id_Gara AND Gare.Fase = 'INTERNAZIONALE'); 46 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore e1 Classifica gare partecipanti individuali: SELECT G are.Data, Gare.Fase, Sedi.Denominazione, Sedi.Citta, Sedi.Regione, Sedi.Nazione, Atleti.Id_Atleta, Atleti.Cognome, Atleti.Nome, Atleti.Data_nascita, Scuole.Denominazione, Atleti_Gare.Punteggio FROM Scuole, Atleti, Atleti_Gare, Gare, Sedi WHERE Atleti.Id_Atleta = Atleti_Gare.Id_Atleta AND Gare.Id_Gara = Atleti_Gare.Id_Gara AND Sedi.Id_Sede = Gare.Id_Sede AND Scuole.Id_Scuola = Atleti.Id_Scuola ORDER BY Gare.Id_Gara, Atleti_Gare.Punteggio DESC, Atleti.Data_nascita; e2 Classifica gare a squadre: SELECT G are.Data, Gare.Fase, Sedi.Denominazione, Sedi.Citta, Sedi.Regione, Sedi.Nazione, Squadre.Denominazione, Squadre.Nazione, Squadre_Gare.Punteggio FROM Squadre, Squadre_Gare, Gare, Sedi WHERE Gare.Id_gara = Squadre_Gare.Id_Gara AND Sedi.Id_Sede = Gare.Id_Sede AND Squadre.Id_Squadra = Squadre_Gare.Id_Squadra ORDER BY Gare.Id_Gara, Squadre_Gare.Punteggio DESC; f1 Aggiornamento record fase partecipanti singoli: UPDATE Fasi,( SELECT Fase, MAX(Punteggio) AS Record FROM Gare, Atleti_Gare WHERE Gare.Id_Gara = Atleti_Gare.Id_Gara GROUP BY Fase) AS T SET Fasi.Record_Singolo = T.Record WHERE Fasi.Fase = T.Fase; f2 Aggiornamento record fase a squadre: UPDATE Fasi,( SELECT Fase, MAX(Punteggio) AS Record FROM Gare, Squadre_Gare WHERE Gare.Id_Gara = Squadre_Gare.Id_Gara GROUP BY Fase) AS T SET Fasi.Record_Squadra = T.Record WHERE Fasi.Fase = T.Fase; 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 47 g SELECT S cuole.Id_scuola, Scuole.Denominazione, Scuole.Citta, Scuole.Nazione, AVG(Atleti_Gare.punteggio) AS Punteggio_medio FROM Scuole, Atleti, Atleti_Gare, Gare WHERE Atleti.Id_atleta = Atleti_Gare.Id_Atleta AND Gare.Id_Gara = Atleti_Gare.Id_Gara AND Scuole.Id_Scuola = Atleti.Id_Scuola AND Gare.Fase = 'SCOLASTICA' GROUP BY Scuole.Id_Scuola, Scuole.Denominazione, Scuole.Citta, Scuole.Nazione; h In questa query viene usata la funzione YEAR(NOW()) per restituire l’anno della data di sistema per calcolare l’età attuale degli atleti. Volendo conoscere l’età effettiva dei partecipanti all’epoca della gara piuttosto che il riferimento temporale relativo fornito da YEAR(NOW()) deve essere utilizzato un riferimento temporale assoluto, ad esempio 2008. SELECT S quadre.Id_Squadra, Squadre.Denominazione, COUNT(*) AS Atleti, AVG(YEAR(NOW()) - YEAR(Atleti.data_nascita)) AS Eta_media FROM Atleti, Atleti_Squadre, Squadre WHERE Atleti.Id_atleta = Atleti_Squadre.Id_Atleta AND Squadre.Id_Squadra = Atleti_Squadre.Id_Squadra GROUP BY Squadre.Id_Squadra, Squadre.Denominazione; 3.6 Interfaccia utente e sito web 2. L’applicazione reale dovrebbe ovviamente prevedere l’autenticazione dell’utente che viene qui trascurata per semplicità. Il database delle varie fasi delle Olimpiadi Internazionali di Informatica ha preferibilmente un’interfaccia utente fruibile da un browser web: questa soluzione ne consente l’accesso via Internet per l’aggiornamento dei dati da parte delle singole scuole e dei giudici preposti alle singole gare delle varie fasi e contemporaneamente l’accesso in rete locale per l’amministrazione dei dati da parte dello staff tecnico. Le pagine web dinamiche che costituiscono l’interfaccia possono essere sviluppate in linguaggio PHP: a questo scopo si è ipotizzato un server My-SQL in esecuzione sullo stesso computer del web server e che l’accesso al database «Olimpiadi» venga effettuato come utente «root» privo di password. A titolo di esempio sono proposte due script in linguaggio PHP nei quali le pagine web dinamiche sono completamente prive di struttura grafica. Il primo script PHP è composto da 3 pagine dinamiche (denominate «sede. php», «data.php» e «carica.php») e consente all’utente di individuare una specifica gara della fase scolastica selezionandone in successione la sede e la data2; una volta individuata la gara è possibile inserire i punteggi dei singoli atleti – identificati dal codice stabilito in fase di registrazione – caricando 48 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore un file di testo in formato CSV come il seguente (la prima posizione è il codice dell’atleta, mentre la seconda è il punteggio conseguito nella gara): 1,100 2,10 3,50 4,90 5,80 6,60 7,70 8,40 9,90 10,20 <html> <head> <title>Individuazione gara</title> </head> <body> Selezionare la sede di svolgimento della gara: <?php $connection = mysqli_connect("localhost", "root", "", "Olimpiadi"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> <form action="data.php" method="POST"> <label for="sede">Sede</label> <select id="sede" name="sede"> <?php $query = " SELECT Id_sede, Denominazione, Citta, Regione, Nazione FROM Sedi;"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } while ($row = mysqli_fetch_array($result)) { $sede = $row[1].",".$row[2]." ".$row[3]."-".$row[4]; echo "<option value=\"$row[0]\">$sede</option>"; } mysqli_free_result($result); mysqli_close($connection); ?> 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 49 </select><br> <input type="submit" value="Seleziona"> </form> </body> </html> <html> <head> <title>Caricamento file</title> </head> <body> <?php $ID_sede = $_POST['sede']; $connection = mysqli_connect("localhost", "root", "", "Olimpiadi"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL." ; die(); } ?> Selezionare la data di svolgimento della gara: <form enctype="multipart/form-data" action="carica.php" method="POST"> <label for="gara">Gara</label> <select id="gara" name="gara"> <?php $query = " SELECT Id_gara, Data FROM Gare WHERE Fase = 'SCOLASTICA' AND Id_sede = '$ID_sede';"; $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL." ; die(); } while ($row = mysqli_fetch_array($result)) { echo "<option value=\"$row[0]\">$row[1]</option>"; } mysqli_free_result($result); mysqli_close($connection); ?> </select><br> Selezionare il file dei punteggi degli atleti:<br> <input type="file" name="punteggi"><br><br> <input type="submit" value="Inoltra"> </form> </body> </html> 50 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore <html> <head> <title>Esito caricamento file</title> </head> <body> <?php if ($_FILES["punteggi"]["error"] == UPLOAD_ERR_OK) { $ID_gara = $_POST['gara']; $connection = mysqli_connect("localhost", "root", "", "Olimpiadi"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL."; die(); } $statement = mysqli_prepare($connection, " INSERT INTO Atleti_Gare VALUES (?, '$ID_gara', ?)"); $punteggi = file($_FILES["punteggi"]["tmp_name"], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($punteggi as $linea) { $dati = explode(",", $linea); $atleta = trim($dati[0]); $punteggio = trim($dati[1]); mysqli_stmt_bind_param($statement, "ss", $atleta, $punteggio); if (mysqli_stmt_execute($statement)) echo "Punteggio atleta $atleta registrato.<br>"; else echo " Errore: punteggio atleta $atleta NON registrato.<br>"; } mysqli_stmt_close($statement); mysqli_close($connection); unlink(($_FILES["punteggi"]["tmp_name"]); } else echo "Errore caricamento del file."; ?> </body> </html> Come richiesto dalla traccia il secondo script PHP è composto da 2 pagine (denominate «richiesta.html» e «classifica.php») e consente all’utente di scegliere tra classifica individuale o a squadre per visualizzarla: 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 51 <html> <head> <title>Selezione classifica</title> </head> <body> Selezionare la tipologia di classifica richiesta: <form action="classifica.php" method="GET"> <select name="classifica"> <option value="Individuale">Individuale</option> <option value="Squadre">A squadre</option> </select><br> <input type="submit" value="Visualizza"> </form> </body> </html> <html> <head> <title>Classifica</title> </head> <body> <?php $connection = mysqli_connect("localhost", "root", "", "Olimpiadi"); if (mysqli_connect_errno($connection)) { echo "Errore di connessione al DBMS My-SQL."; die(); } if ($_GET['classifica'] == "Individuale") { $query = " SELECT Gare.Data, Gare.Fase, Sedi.Denominazione AS Sede, Sedi.Citta, Sedi.Regione, Sedi.Nazione, Atleti.Id_Atleta, Atleti.Cognome, Atleti.Nome, Atleti.Data_nascita, Scuole.Denominazione AS Scuola, Atleti_Gare.Punteggio FROM Scuole, Atleti, Atleti_Gare, Gare, Sedi WHERE Atleti.Id_Atleta = Atleti_Gare.Id_Atleta AND Gare.Id_Gara = Atleti_Gare.Id_Gara AND Sedi.Id_Sede = Gare.Id_Sede AND Scuole.Id_Scuola = Atleti.Id_Scuola ORDER BY Gare.Id_Gara, Atleti_Gare.Punteggio DESC, Atleti.Data_nascita;"; } else { $query = " SELECT Gare.Data, Gare.Fase, Sedi.Denominazione AS Sede, Sedi.Citta, Sedi.Regione, Sedi.Nazione, Squadre.Denominazione AS Squadra, Squadre.Nazione AS Nazionalita, Squadre_Gare.Punteggio 52 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore FROM Squadre, Squadre_Gare, Gare, Sedi WHERE Gare.Id_gara = Squadre_Gare.Id_Gara AND Sedi.Id_Sede = Gare.Id_Sede AND Squadre.Id_Squadra = Squadre_Gare.Id_Squadra ORDER BY Gare.Id_Gara, Squadre_Gare.Punteggio DESC;”; } $result = mysqli_query($connection, $query); if (!$result) { echo "Errore esecuzione query SQL."; die(); } if (mysqli_num_rows($result) == 0) { echo "Nessun dato da visualizzare."; mysqli_free_result($result); mysqli_close($connection); exit(); } if ($_GET['classifica'] == "Individuale") { ?> <table border> <caption><b>Classifica individuale</b></caption> <thead> <tr> <th>Data gara</th> <th>Fase</th> <th>Sede</th> <th>Citt&agrave</th> <th>Cognome</th> <th>Nome</th> <th>Data nascita</th> <th>Scuola</th> <th>Punti</th> </tr> </thead> <tbody> <?php while ($row = mysqli_fetch_assoc($result)) { ?> <tr> <td><?php echo ($row['Data']); ?></td> <td><?php echo ($row['Fase']); ?></td> <td><?php echo ($row['Sede']); ?></td> <td><?php echo ($row['Citta']); ?></td> <td><?php echo ($row['Cognome']); ?></td> 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 53 <td><?php echo ($row['Nome']); ?></td> <td><?php echo ($row['Data_nascita']); ?></td> <td><?php echo ($row['Scuola']); ?></td> <td><?php echo ($row['Punteggio']); ?></td> </tr> <?php } } else { ?> <table border> <caption><b>Classifica a squadre</b></caption> <thead> <tr> <th>Data gara</th> <th>Fase</th> <th>Sede</th> <th>Citt&agrave</th> <th>Squadra</th> <th>Nazione</th> <th>Punti</th> </tr> </thead> <tbody> <?php while ($row = mysqli_fetch_assoc($result)) { ?> <tr> <td><?php echo ($row['Data']); ?></td> <td><?php echo ($row['Fase']); ?></td> <td><?php echo ($row['Sede']); ?></td> <td><?php echo ($row['Citta']); ?></td> <td><?php echo ($row['Squadra']); ?></td> <td><?php echo ($row['Nazionalita']); ?></td> <td><?php echo ($row['Punteggio']); ?></td> </tr> <?php } } echo "</tbody>\n"; echo "</table>\n"; echo "<br>\n"; mysqli_free_result($result); mysqli_close($connection); ?> </body> </html> 54 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Sono riportate di seguito le pagine web generate dallo script PHP nei due casi di classifica individuale e a squadre: 3 Anno 2008 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 55 4 Anno 2011 - Informatica ABACUS Testo Il Ministero dell’Ambiente commissiona lo sviluppo di un nuovo Sistema Informativo per censire la fauna e la flora presenti nei vari parchi naturali di ciascuna regione. Le informazioni della fauna da raccogliere riguardano l’ordine di appartenenza (mammiferi, rettili, uccelli, …), la specie (scoiattolo, volpe, orso, vipera, falco, aquila, …), il numero di esemplari adulti e cuccioli (con distinzione maschio, femmina), lo stato di salute di ogni esemplare. La flora viene distinta in alberi (quercia, faggio, acacia, …), arbusti (lavanda, rosmarino, rododendro, …) e piante erbacee (fragola di bosco, margherita, primula, …) ed è necessario catalogarle memorizzandone anche la stagione di fioritura e altre caratteristiche peculiari. In ciascun parco, un responsabile (guardaparco) raccoglie le informazioni attraverso un software installato sul notebook in dotazione; il programma, dopo avere acquisito i dati dalle maschere di immissione, li memorizza in un database. Ciascuna regione, dotata del nuovo Sistema Informativo, deve provvedere alla gestione della raccolta dati dei propri parchi ai fini di produrre e inviare al Ministero dell’Ambiente dei report periodici. Il candidato, formulate le opportune ipotesi aggiuntive, realizzi: •un’analisi della realtà di riferimento, completa dello schema funzionale dell’architettura proposta, evidenziandone le principali componenti e la tecnologia utilizzata per la trasmissione delle informazioni; •uno schema concettuale e uno schema logico del database; •la definizione delle relazioni e le seguenti interrogazioni espresse in linguaggio SQL: 1 visualizzare l’elenco di tutti gli esemplari di fauna, suddivisi per specie, presenti nei vari parchi; 2 visualizzare tutti gli esemplari a rischio di estinzione; 3 calcolare e visualizzare il numero di nascite di un certo esemplare nell’arco di un anno di monitoraggio; 4 calcolare e visualizzare il numero totale di diverse specie di arbusti presenti nei vari parchi della regione; 5 visualizzare quante specie diverse di pino sono presenti in ciascun parco; 6 calcolare il numero medio dei cuccioli di ciascuna specie presenti in tutti i parchi della re­ gione; 7 visualizzare l’esemplare più anziano di ogni specie presente in un determinato parco. •La codifica in un linguaggio di programmazione a scelta di un segmento significativo del progetto realizzato. 4.1Analisi della realtà di riferimento e ipotesi aggiuntive Ipotizzando la difficoltà di una connessione di rete permanente nelle aree di un parco naturale, si prevede che l’applicazione dei notebook in dotazione alle guardie del parco produca dei file in formato XML contenenti i dati relativi alla flora e alla fauna oggetto del censimento. Non richiedendo l’operazione di censimento un aggiornamento in tempo reale dei dati acquisiti, i file vengono successivamente trasmessi al Sistema Informativo regionale e costituiscono l’input del software di gestione del database che 56 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore viene mantenuto e gestito a questo livello. In modo analogo il software di gestione del database regionale esporta in un file in formato XML i report periodici da inviare al Ministero dell’Ambiente. Non si ritiene utile dettagliare le modalità di trasmissione dei file e dei report in formato XML: date le caratteristiche di periodicità e di non urgenza dei dati essa può anche consistere nel semplice invio mediante il sistema di posta elettronica certificata del Sistema Informativo, se presso il centro regionale e al Ministero dell’Ambiente sono presenti operatori incaricati di effettuare la gestione dei file ricevuti rispettivamente dai parchi e dai centri regionali3. 3. La soluzione più adatta è comunque quella di un’applicazione client/ server che consenta ai guardaparco di caricare direttamente nel database regionale i risultati del censimento e, analogamente, agli operatori del Sistema Informativo regionale di inoltrare i report periodici al Ministero dell’Ambiente. file XML notebook guardaparco report XML file XML DB server Sistema Informativo regionale server Ministero dell’Ambiente postazione operatore Sistema Informativo regionale postazione operatore Ministero dell’Ambiente notebook guardaparco La soluzione proposta riguarda il database che verrà gestito da ogni singola regione ed è sviluppata tenendo conto delle seguenti ipotesi aggiuntive4: •in relazione alle informazioni relative alla fauna si prevede di censire i singoli esemplari di alcune specie messe sotto controllo (questa soluzione è infatti l’unica che consente di formulare alcune delle query richieste dal testo); •l’identificatore numerico del singolo esemplare di fauna viene generato dall’applicazione del notebook del guardaparco con modalità che non ne consentono la duplicazione5; •il file XML prodotto dall’applicazione dei notebook dei guardaparco relativo alla flora ha la struttura mostrata dal seguente esempio: <?xml version="1.0" ?> <flora> <ID-parco>1</ID-parco> <parco>Parco Alpi Apuane</parco> <regione>Toscana</regione> <specie> <ID-specie>200</ID-specie> <denominazione>Quercia</denominazione> 4. Per semplicità non viene fornito lo schema XSD del formato dei vari file XML, ma solo un esempio per ciascuno di essi. 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 5. Per esempio parti del codice potrebbero riferire univocamente il parco e il guardaparco. 57 </specie> <specie> <ID-specie>101</ID-specie> <denominazione>Rododendro</denominazione> </specie> <specie> <ID-specie>3</ID-specie> <denominazione>Campanula</denominazione> </specie> </flora> •il file XML prodotto dall’applicazione dei notebook dei guardaparco relativo agli esemplari della fauna ha la struttura mostrata dal seguente esempio: <?xml version="1.0" ?> <fauna> <ID-parco>2</ID-parco> <parco>Parco S. Rossore, Migliarino, Massaciuccoli</parco> <regione>Toscana</regione> <esemplare> <ID-specie>6</ID-specie> <specie>Volpe</specie> <ID-esemplare>1234</ID-esemplare> <nome>Red</nome> <mese-nascita>03</mese-nascita> <anno-nascita>2011</anno-nascita> <sesso>M</sesso> <salute>Buona</salute> </esemplare> <esemplare> <ID-specie>6</ID-specie> <specie>Volpe</specie> <ID-esemplare>1256</ID-esemplare> <nome>Toby</nome> <mese-nascita>04</mese-nascita> <anno-nascita>2010</anno-nascita> <sesso>F</sesso> <salute>Ottima</salute> </esemplare> <esemplare> <ID-specie>3</ID-specie> <specie>Lupo</specie> <ID-esemplare>1278</ID-esemplare> <nome>Buck</nome> <mese-nascita>03</mese-nascita> <anno-nascita>2010</anno-nascita> <sesso>M</sesso> <salute>Cattiva</salute> </esemplare> </fauna> 58 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore •il report periodico in formato XML esportato dal Sistema Informativo della regione per la trasmissione al Ministero dell’Ambiente è relativo ai soli esemplari della fauna e ha la struttura mostrata dal seguente esempio: <?xml version="1.0" ?> <fauna> <esemplare> <ID-parco>2</ID-parco> <parco>Parco S. Rossore, Migliarino, Massaciuccoli</parco> <regione>Toscana</regione> <ID-specie>6</ID-specie> <specie>Volpe</specie> <ID-esemplare>1234</ID-esemplare> <nome>Red</nome> <mese-nascita>03</mese-nascita> <anno-nascita>2011</anno-nascita> <sesso>M</sesso> <salute>Buona</salute> </esemplare> <esemplare> <ID-parco>2</ID-parco> <parco>Parco S. Rossore, Migliarino, Massaciuccoli</parco> <regione>Toscana</regione> <ID-specie>6</ID-specie> <specie>Volpe</specie> <ID-esemplare>1256</ID-esemplare> <nome>Toby</nome> <mese-nascita>04</mese-nascita> <anno-nascita>2010</anno-nascita> <sesso>F</sesso> <salute>Ottima</salute> </esemplare> <esemplare> <ID-parco>1</ID-parco> <parco>Parco Alpi Apuane</parco> <regione>Toscana</regione> <ID-specie>3</ID-specie> <specie>Lupo</specie> <ID-esemplare>1278</ID-esemplare> <nome>Buck</nome> <mese-nascita>03</mese-nascita> <anno-nascita>2010</anno-nascita> <sesso>M</sesso> <salute>Cattiva</salute> </esemplare> </fauna> 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 59 4.2 Diagramma database TipoFlora PK OrdineFauna Id_TipoFlora PK Id_Ordine Tipologia Ordine SpecieFlora SpecieFauna PK Id_SpecieFlora FK1 Id_SpecieFlora Specie Fioritura AltreCaratteristiche Parco PK Id_Parco Id_Specie FK1 Id_Ordine Specie AnniAdulto N_EsemplariRischio Parco Regione ParcoFlora PK,FK1 PK,FK2 PK EsemplareFauna Id_Parco Id_SpecieFlora PK,FK1 PK Id_Parco Id_Esemplare FK2 Id_Specie Nome DataNascita Sesso Salute 4.3 Tabelle database EsemplareFauna È la tabella in cui sono censiti gli i singoli esemplari delle varie specie di animali: Campo R Tipo Id_Parco PK Intero Id_Esemplare PK Carattere Id_Specie FK Intero Dim. Descrizione Identificativo parco 50 Identificativo esemplare Identificativo specie Nome Carattere 50 Nome dell’esemplare DataNascita Data Sesso Carattere 1 Sesso (M/F) Salute Carattere 10 Descrizione dello stato di salute (Buona, Cat­ tiva, …) Data di nascita (essendo il monitoraggio men­ sile, il valore del giorno è sempre 1) Chiave Primaria: Id_Parco, Id_Esemplare Chiave Esterna: Id_Parco → Parco.Id_Parco Chiave Esterna: Id_Specie → SpecieFauna.Id_Specie La seguente è una possibile istanza della tabella EsemplareFauna: 60 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore Id_Parco Id_Esemplare Id_Specie Nome DataNascita Sesso Salute 1 1301 3 Olaf 2008/03/01 M Ottima 1 1302 3 Gala 2010/04/01 F Buona 1 1501 5 Yoghi 2006/04/01 M Ottima 1 1502 5 Clarabella 2007/05/01 F Ottima 1 1601 6 Renard 2009/04/01 M Ottima 1 1602 6 Titù 2010/03/01 F Ottima 1 1701 7 Corno Nero 2008/04/01 M Ottima 2 2301 3 Zanna Bianca 2004/03/01 M Buona 2 2302 3 Gamma 2008/03/01 F Ottima 2 2501 5 Bubu 2004/03/01 M Buona 2 2502 5 Yara 2003/04/01 F Buona 2 2701 7 Big Horn 2007/05/01 M Buona 2 2702 7 Cynthia 2007/05/01 F Ottima 2 2703 7 Unico 2006/04/01 M Cattiva OrdineFauna È la tabella in cui sono riportati vari ordini della fauna: Campo Id_Ordine R Tipo PK Intero Ordine Carattere Dim. Descrizione Identificativo ordine fauna 50 (Mammiferi, Rettili, Uccelli, …) Chiave Primaria: Id_Ordine La seguente è una possibile istanza della tabella OrdineFauna: Id_Ordine Ordine 1 Mammiferi 2 Rettili 3 Uccelli 4 Pesci Parco È la tabella in cui sono elencati i parchi regionali: Campo R Tipo Id_Parco PK Intero Dim. Descrizione Identificativo parco Parco Carattere 50 Denominazione del parco Regione Carattere 50 Regione di appartenenza Chiave Primaria: Id_Parco La seguente è una possibile istanza della tabella Parco: Id_Parco Parco Regione 1 Parco Alpi Apuane Toscana 2 Parco S. Rossore, Migliarino, Massaciuccoli Toscana 3 Parco della Maremma Toscana 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 61 ParcoFlora È la tabella in cui sono censite le varie specie della flora di ogni parco: Campo R Tipo Id_Parco PK Intero Dim. Descrizione Identificativo parco Id_SpecieFlora PK Intero Identificativo specie flora Chiave Primaria: Id_Parco, Id_SpecieFlora Chiave Esterna: Id_Parco → Parco.Id_Parco Chiave Esterna: Id_SpecieFlora → SpecieFlora.Id_SpecieFlora La seguente è una possibile istanza della tabella ParcoFlora: Id_Parco Id_SpecieFlora 1 1 1 2 1 3 1 100 1 101 1 102 1 200 1 203 1 205 1 207 2 1 2 2 2 3 2 100 2 101 2 200 2 206 2 207 SpecieFauna È la tabella in cui sono riportate le varie specie di fauna e l’ordine cui appartengono: Campo R Tipo Id_Specie PK Intero Dim. Identificativo specie fauna Id_Ordine FK Intero Identificativo ordine fauna 50 Descrizione Specie Carattere Nome della specie (Scoiattolo, Volpe, Orso, Falco, Aquila, …) AnniAdulto Intero Numero degli anni che impiega un esem­ plare della specie a divenire adulto N_EsemparilRischio Intero Numero minimo di esemplari sotto il quale la specie è a rischio di estinzione Chiave Primaria: Id_Specie Chiave Esterna: Id_Ordine → OrdineFauna.Id_Ordine 62 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore La seguente è una possibile istanza della tabella SpecieFauna: Id_Specie Id_Ordine Specie AnniAdulto N_EsemparilRischio 1 1 Scoiattolo 1 1000 2 1 Cinghiale 1 1500 3 1 Lupo 2 200 4 1 Lepre 1 2000 5 1 Orso 3 40 6 1 Volpe 2 300 7 1 Stambecco 3 200 8 1 Camoscio 3 100 9 1 Marmotta 2 1500 100 2 Vipera 1 1000 200 3 Falco 2 200 201 3 Aquila 3 20 202 3 Corvo 2 2000 300 4 Trota 1 1000 301 4 Cavedano 2 1500 SpecieFlora È la tabella in cui sono riportate le varie specie di flora suddivise per tipologia: Campo R Tipo Id_SpecieFlora PK Intero Id_TipoFlora FK Intero Dim. Descrizione Identificativo specie flora Identificativo tipologia flora Specie Carattere 20 Nome della specie Fioritura Carattere 10 Mese di fioritura (se pertinente) AltreCaratteristiche Carattere 250 Altre caratteristiche Chiave Primaria: Id_SpecieFlora Chiave Esterna: Id_TipoFlora → TipoFlora.Id_TipoFlora La seguente è una possibile istanza della tabella SpecieFlora: Id_SpecieFlora Id_TipoFlora Specie Fioritura 1 1 Fragola Maggio 2 1 Margherita Marzo 3 1 Campanula Febbraio 100 2 Lavanda Aprile 101 2 Rododendro Aprile 102 2 Mirto Maggio 103 2 Rosmarino Marzo 200 3 Quercia 201 3 Leccio 202 3 Olmo 203 3 Ontano 204 3 Platano 205 3 Pino 206 3 Abete 207 3 Larice 208 3 Pino d’Aleppo 209 3 Cedro AltreCaratteristiche 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 63 TipoFlora È la tabella in cui sono elencate le varie tipologie di flora: Campo Id_TipoFlora R Tipo PK Intero Tipologia Carattere Dim. Descrizione Identificativo tipologia flora 20 (Alberi, Arbusti, Erbacee, …) Chiave Primaria: Id_TipoFlora La seguente è una possibile istanza della tabella TipoFlora: Id_TipoFlora Tipologia 1 Erbacee 2 Arbusti 3 Alberi 4.4 DB-schema CREATE TABLE OrdineFauna( Id_Ordine INTEGER, Ordine VARCHAR(50), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Ordine) ); CREATE TABLE Parco( Id_Parco INTEGER, Parco VARCHAR(50), Regione VARCHAR(50), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Parco) ); CREATE TABLE SpecieFauna( Id_Specie INTEGER, Id_Ordine INTEGER, Specie VARCHAR(50), AnniAdulto INTEGER, N_EsemplariRischio INTEGER, CONSTRAINT OrdineFaunaSpecieFauna FOREIGN KEY(Id_Ordine) REFERENCES OrdineFauna(Id_Ordine), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Specie) ); CREATE TABLE TipoFlora( Id_TipoFlora INTEGER, Tipologia VARCHAR(20), CONSTRAINT PrimaryKey PRIMARY KEY(Id_TipoFlora) ); 64 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore CREATE TABLE EsemplareFauna( Id_Parco INTEGER, Id_Esemplare VARCHAR(50), Id_Specie INTEGER, Nome VARCHAR(50), DataNascita DATE, Sesso VARCHAR(1), Salute VARCHAR(10), CONSTRAINT ParcoEsemplareFauna FOREIGN KEY(Id_Parco) REFERENCES Parco(Id_Parco), CONSTRAINT PrimaryKey PRIMARY KEY(Id_Parco,Id_Esemplare), CONSTRAINT SpecieFaunaEsemplareFauna FOREIGN KEY(Id_Specie) REFERENCES SpecieFauna(Id_Specie) ); CREATE TABLE SpecieFlora( Id_SpecieFlora INTEGER, Id_TipoFlora INTEGER, Specie VARCHAR(20), Fioritura VARCHAR(10), AltreCaratteristiche VARCHAR(250), CONSTRAINT PrimaryKey PRIMARY KEY(Id_SpecieFlora), CONSTRAINT TipoFloraSpecieFlora FOREIGN KEY(Id_TipoFlora) REFERENCES TipoFlora(Id_TipoFlora) ); CREATE TABLE ParcoFlora( Id_Parco INTEGER, Id_SpecieFlora INTEGER, CONSTRAINT PrimaryKey PRIMARY KEY(Id_Parco,Id_SpecieFlora), CONSTRAINT ParcoParcoFlora FOREIGN KEY(Id_Parco) REFERENCES Parco(Id_Parco), CONSTRAINT SpecieFloraParcoFlora FOREIGN KEY(Id_SpecieFlora) REFERENCES SpecieFlora(Id_SpecieFlora) ); 4.5 Query 1 SELECT E semplareFauna.Id_Esemplare, SpecieFauna.Specie, Parco.Parco, EsemplareFauna.Nome, EsemplareFauna.DataNascita, EsemplareFauna.Sesso, EsemplareFauna.Salute FROM Parco INNER JOIN ((OrdineFauna INNER JOIN SpecieFauna ON OrdineFauna.Id_Ordine = SpecieFauna.Id_Ordine) INNER JOIN EsemplareFauna ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie) ON Parco.Id_Parco = EsemplareFauna.Id_Parco ORDER BY SpecieFauna.Id_Specie, Parco.Parco; 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 65 2 L’ambigua richiesta del testo è stata interpretata come «specie» (e non «esemplare») a rischio di estinzione: SELECT Specie, N_EsemplariRischio, N_Esemplari FROM SpecieFauna, ( SELECT Id_Specie,COUNT(*) AS N_Esemplari FROM EsemplareFauna GROUP BY id_Specie) AS T WHERE SpecieFauna.Id_Specie = T.Id_Specie AND N_Esemplari <= N_EsemplariRischio; 3 L’ambigua richiesta del testo è stata interpretata come numero di nascite di una certa «specie» (e non «esemplare») nell’arco di un anno solare di monitoraggio: SELECT Specie, COUNT(*) AS N_Nascite FROM SpecieFauna INNER JOIN EsemplareFauna ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie WHERE YEAR(DataNascita)= '…' GROUP BY Specie; 4 SELECT SpecieFlora.Specie, COUNT(*) AS TipoArbusti FROM ( TipoFlora INNER JOIN SpecieFlora ON TipoFlora.Id_TipoFlora = SpecieFlora.Id_TipoFlora INNER JOIN ParcoFlora ON SpecieFlora.Id_SpecieFlora = ParcoFlora.Id_SpecieFlora WHERE TipoFlora.Tipologia='Arbusti' GROUP BY SpecieFlora.Specie; 5 SELECT Parco.Parco, COUNT(*) AS NSpeciePino FROM ( TipoFlora INNER JOIN SpecieFlora ON TipoFlora.Id_TipoFlora = SpecieFlora.Id_TipoFlora) INNER JOIN(Parco INNER JOIN ParcoFlora ON Parco.Id_Parco = ParcoFlora.Id_Parco) ON SpecieFlora.Id_SpecieFlora = ParcoFlora.Id_SpecieFlora WHERE TipoFlora.Tipologia='Alberi' AND SpecieFlora.Specie LIKE 'Pino%' GROUP BY Parco.Parco; 6 Data l’ambiguità della richiesta si presentano due query: la prima conta il numero di cuccioli per ogni parco e per ogni specie, mentre la seconda calcola la media dei cuccioli per specie indipendentemente dal parco: 66 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore SELECT Parco.Parco, SpecieFauna.Specie, COUNT(*) AS Cuccioli FROM SpecieFauna INNER JOIN (Parco INNER JOIN EsemplareFauna ON Parco.Id_Parco = EsemplareFauna.Id_Parco) ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie WHERE (YEAR(DataNascita) - YEAR(CURRENT_DATE())) < AnniAdulto GROUP BY Parco.Parco, SpecieFauna.Specie; SELECT Specie, AVG(Cuccioli) AS MediaCuccioli FROM ( SELECT Parco.Parco, SpecieFauna.Specie, COUNT(*) AS Cuccioli FROM SpecieFauna INNER JOIN (Parco INNER JOIN EsemplareFauna ON Parco.Id_Parco = EsemplareFauna.Id_Parco) ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie WHERE (YEAR(DataNascita) - YEAR(CURRENT_DATE()))<AnniAdulto GROUP BY Parco.Parco, SpecieFauna.Specie) AS T GROUP BY Specie; 7 SELECT * FROM EsemplareFauna, ( SELECT T.Id_Parco, Id_Specie, MAX(Anni) AS Eta FROM (SELECT Parco.Id_Parco, SpecieFauna.Id_Specie, Id_Esemplare, YEAR(CURRENT_DATE()) - YEAR(DataNascita) AS Anni FROM Parco INNER JOIN (SpecieFauna INNER JOIN EsemplareFauna ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie) ON Parco.Id_Parco = EsemplareFauna.Id_Parco WHERE Parco.Parco = '…') AS T GROUP BY Id_Parco,Id_Specie) AS T1 WHERE EsemplareFauna.Id_Parco = T1.Id_parco AND EsemplareFauna.Id_Specie = T1.Id_Specie AND YEAR(CURRENT_DATE()) - YEAR(DataNascita) = Eta; o, in alternativa: SELECT * FROM EsemplareFauna,( SELECT T.Id_Parco, Id_Specie, MIN(DataNascita) AS MinData FROM (SELECT Parco.Id_Parco, SpecieFauna.Id_Specie, Id_Esemplare, DataNascita FROM Parco INNER JOIN (SpecieFauna INNER JOIN EsemplareFauna ON SpecieFauna.Id_Specie = EsemplareFauna.Id_Specie) ON Parco.Id_Parco = EsemplareFauna.Id_Parco WHERE Parco.Parco = '…') AS T GROUP BY Id_Parco, Id_Specie) AS T1 WHERE EsemplareFauna.Id_Parco = T1.Id_parco AND EsemplareFauna.Id_Specie = T1.Id_Specie AND DataNascita = MinData; 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 67 4.6Codifica di un segmento significativo dell’applicazione di gestione del database La seguente classe Java Import consente – mediante il metodo parseDocument – di caricare nel database un file XML relativo al censimento degli esemplari della fauna; nel caso che l’identificativo di esemplare non sia presente nel database viene creato un nuovo record, se è invece già presente viene aggiornato il record esistente. Il parsing del file XML avviene con tecnica SAX, mentre per l’accesso al DBMS si utilizzano le API JDBC; a questo scopo si è ipotizzato un server My-SQL in esecuzione sullo stesso computer dell’applicazione e che l’accesso al database «Parco» venga effettuato come utente «root» privo di password. import import import import import java.io.*; java.sql.*; javax.xml.parsers.*; org.xml.sax.*; org.xml.sax.helpers.*; public class Import extends DefaultHandler { private String text; private int ID_parco; private int ID_specie; private int ID_esemplare; private String nome; private int mese_nascita; private int anno_nascita; private String sesso; private String salute; private int inserted; // numero di nuovi record inseriti private int updated; // numero di record esistenti aggiornati private Connection con; final String URL = "jdbc:mysql://localhost:3306"; final String database = "Parco"; final String user = "root"; final String password = ""; public Import() throws SQLException { // connessione al server DB con = DriverManager.getConnection(URL+"/"+database, user, password); } public void parseDocument(String filename) throws S AXException, ParserConfigurationException, IOException { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); 68 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore parser.parse(filename, this); } // metodi di gestione degli eventi SAX public void startDocument() { inserted = 0; updated = 0; } public void endDocument() { } public void startElement (String uriNamespace, String localNamespace, String qualifiedName, Attributes attributes) throws SAXException { text = ""; } public void characters (char[] characters, int start, int length) throws SAXException { text = new String(characters, start, length); } public void endElement( String uriNamespace, String localNamespace, String qualifiedName) throws SAXException { Statement stat; ResultSet result; String data_nascita; String query; String command; if (qualifiedName.equalsIgnoreCase("ID-parco")) { ID_parco = Integer.parseInt(text); } else if (qualifiedName.equalsIgnoreCase("ID-specie")) { ID_specie = Integer.parseInt(text); } else if (qualifiedName.equalsIgnoreCase("ID-esemplare")) { ID_esemplare = Integer.parseInt(text); } else if (qualifiedName.equalsIgnoreCase("nome")) { nome = text; } else if (qualifiedName.equalsIgnoreCase("mese-nascita")) { mese_nascita = Integer.parseInt(text); } else if (qualifiedName.equalsIgnoreCase("anno-nascita")) { anno_nascita = Integer.parseInt(text); } else if (qualifiedName.equalsIgnoreCase("sesso")) { sesso = text; 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 69 } else if (qualifiedName.equalsIgnoreCase("salute")) { salute = text; } else if (qualifiedName.equalsIgnoreCase("esemplare")) { try{ stat = con.createStatement(); query = " SELECT COUNT(*) AS numero FROM EsemplareFauna WHERE ID_esemplare = " + ID_esemplare + " AND ID_parco = " + ID_parco + ";"; result = stat.executeQuery(query); result.next(); if (result.getInt("numero") > 0) { // esemplare esistente (aggiornamento record) data_nascita = anno_nascita + "-" + mese_nascita + "-1"; command = "UPDATE EsemplareFauna SET Id_specie=" + ID_specie + ", Nome='" + nome + "', DataNascita='" + data_nascita + "', Sesso='" + sesso + "', Salute='" + salute + "' WHERE ID_esemplare = " + ID_esemplare + " AND ID_parco = " + ID_parco + ";"; if (stat.executeUpdate(command) != 0) updated++; result.close(); } else { // nuovo esemplare (inserimento record) data_nascita = anno_nascita + "-" + mese_nascita + "-1"; command = " INSERT INTO EsemplareFauna(ID_parco, ID_esemplare, ID_specie, nome, DataNascita, Sesso, Salute) VALUES (" + ID_parco + ", " + ID_esemplare + ", " + ID_specie + ", '" + nome + "', '" + data_nascita + "', '" + sesso + "', '" + salute + "');"; if (stat.executeUpdate(command) != 0) inserted++; } stat.close(); } catch (SQLException exception) { } } else if (qualifiedName.equalsIgnoreCase("fauna")) { System.out.println( inserted +" nuovi esemplari inseriti e " + updated + " esemplari aggiornati."); } } 70 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore // metodi di gestione degli errori SAX public void warning(SAXParseException exception) { System.out.println(exception.getMessage()); } public void error(SAXParseException exception) { System.out.println(exception.getMessage()); } public void fatalError(SAXParseException exception) { System.out.println(exception.getMessage()); } public static void main(String[] args) { try { Import importer = new Import(); importer.parseDocument(args[0]); } catch ( SAXException | ParserConfigurationException | IOException | SQLException exception) { System.out.println("Errore!"); } } } La seguente classe Java Export permette – mediante il metodo printToFile – di esportare dal database in un file XML il report periodico da inviare al Ministero dell’Ambiente relativo agli esemplari della fauna dei parchi. La creazione del file XML avviene a partire dalla costruzione dell’albero DOM, mentre per l’accesso al DBMS si utilizzano le API JDBC; a questo scopo si è ipotizzato un server My-SQL in esecuzione sullo stesso computer dell’applicazione e che l’accesso al database «Parco» venga effettuato come utente «root» privo di password. import import import import import import import java.io.*; java.sql.*; javax.xml.parsers.*; javax.xml.transform.*; javax.xml.transform.dom.*; javax.xml.transform.stream.*; org.w3c.dom.*; public class Export { Document document; private Connection con; final String URL = "jdbc:mysql://localhost:3306"; final String database = "Parco"; 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 71 final String user = "root"; final String password = ""; public Export() throws ParserConfigurationException, SQLException { // connessione al server DB con = DriverManager.getConnection(URL+"/"+database, user, password); // creazione dell’albero DOM del documento XML createDOMTree(); } private void createDOMTree() throws ParserConfigurationException, SQLException { Statement stat; ResultSet result; int numero; int ID_parco; String parco; String regione; int ID_specie; String specie; int ID_esemplare; String nome; Date data_nascita; int mese_nascita; int anno_nascita; String sesso; String salute; Element element; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // creazione elemento root albero DOM document = builder.newDocument(); Element root = document.createElement(“fauna”); document.appendChild(root); // interrogazione del database stat = con.createStatement(); String query = " SELECT Parco.ID_parco, Parco, Regione, ID_esemplare, SpecieFauna.ID_specie, Nome, DataNascita, Sesso, Salute, Specie FROM Parco, EsemplareFauna, SpecieFauna WHERE Parco.ID_parco = EsemplareFauna.ID_parco AND EsemplareFauna.ID_specie = SpecieFauna.ID_specie;"; result = stat.executeQuery(query); numero = 0; while (result.next()) { // iterazione risultati interrogazione DB ID_parco = result.getInt("ID_parco"); 72 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore parco = result.getString("Parco"); regione = result.getString("Regione"); ID_esemplare = result.getInt("ID_esemplare"); ID_specie = result.getInt("ID_specie"); nome = result.getString("Nome"); data_nascita = result.getDate("DataNascita"); mese_nascita = data_nascita.getMonth() + 1; anno_nascita = data_nascita.getYear() + 1900; sesso = result.getString("Sesso"); salute = result.getString("Salute"); specie = result.getString("Specie"); // creazione elemento XML "esemplare" element = createEsemplareElement( ID_parco, parco, regione, ID_esemplare, ID_specie, specie, nome, mese_nascita, anno_nascita, sesso, salute); root.appendChild(element); numero++; } System.out.println(numero + " esemplari esportati."); result.close(); stat.close(); } private Element createEsemplareElement( int ID_parco, String parco, String regione, int ID_esemplare, int ID_specie, String specie, String nome, int mese_nascita, int anno_nascita, String sesso, String salute) { Text text; Element esemplare = document.createElement("esemplare"); Element _ID_parco = document.createElement("ID-parco"); text = document.createTextNode(Integer.toString(ID_parco)); _ID_parco.appendChild(text); esemplare.appendChild(_ID_parco); Element _parco = document.createElement("parco"); text = document.createTextNode(parco); _parco.appendChild(text); esemplare.appendChild(_parco); Element _regione = document.createElement("regione"); text = document.createTextNode(regione); _regione.appendChild(text); esemplare.appendChild(_regione); Element _ID_specie = document.createElement("ID-specie"); text = document.createTextNode(Integer.toString(ID_specie)); _ID_specie.appendChild(text); 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 73 esemplare.appendChild(_ID_specie); Element _specie = document.createElement("specie"); text = document.createTextNode(specie); _specie.appendChild(text); esemplare.appendChild(_specie); Element _ID_esemplare = document.createElement("ID-esemplare"); text = document.createTextNode(Integer.toString(ID_esemplare)); _ID_esemplare.appendChild(text); esemplare.appendChild(_ID_esemplare); Element _nome = document.createElement("nome"); text = document.createTextNode(nome); _nome.appendChild(text); esemplare.appendChild(_nome); Element _mese_nascita = document.createElement("mese_nascita"); text = document.createTextNode(Integer.toString(mese_nascita)); _mese_nascita.appendChild(text); esemplare.appendChild(_mese_nascita); Element _anno_nascita = document.createElement("anno_nascita"); text = document.createTextNode(Integer.toString(anno_nascita)); _anno_nascita.appendChild(text); esemplare.appendChild(_anno_nascita); Element _sesso = document.createElement("sesso"); text = document.createTextNode(sesso); _sesso.appendChild(text); esemplare.appendChild(_sesso); Element _salute = document.createElement("salute"); text = document.createTextNode(salute); _salute.appendChild(text); esemplare.appendChild(_salute); return esemplare; } private void printToFile(String XMLfile) throws TransformerException { TransformerFactory factory; factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(new File(XMLfile)); transformer.transform(source, result); } public static void main(String args[]) { Export exporter; 74 Esempi di risoluzione delle prove scritte dell’esame di Stato Formichi, Meini, Corso di informatica, © Zanichelli Editore try{ exporter = new Export(); exporter.printToFile(args[0]); } catch ( ParserConfigurationException | TransformerException | SQLException exception) { System.out.println("Errore!"); } } } 4 Anno 2011 - Informatica ABACUS Formichi, Meini, Corso di informatica, © Zanichelli Editore 75