esempi risoluzione prove d`esame Informatica

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