Prova del 14/09/09 Considerare la seguente descrizione di un campeggio: Un campeggio è descritto da nome, indirizzo, partita IVA e uno o più numeri telefonici. Ai clienti vengono offerti essenzialmente due possibili sistemazioni: sistemazione in tenda e sistemazione tramite camper/roulotte. Ogni sistemazione ha un numero di piazzola ed è contraddistinta da un tipo che ne definisce la dimensione (piccola, media,grande) e posizione (laterale, centrale). La sistemazione ha un costo giornaliero che dipende dalle sue caratteristiche complessive. I clienti possono associare alla sistemazione alcuni servizi (tennis, calcetto, ecc). La fruizione di ogni servizio è associata ad un costo orario. Durante il periodo di soggiorno il cliente sceglie obbligatoriamente una sistemazione e associa liberamente uno o più servizi. Un cliente è sempre registrato per mezzo di una semplice anagrafica (nome, cognome, residenza e CF). 1. Descrivere il sistema tramite uno schema E-R, elencando in particolare la cardinalità delle relazioni, le chiavi ed eventuali regole applicabili. 2. Costruire in SQL la base di dati relativa al sistema. 3. Risolvere, tramite interrogazioni SQL, i problemi seguenti: a. Stampare la lista dei clienti presenti nel campeggio in una data inserita dall'utente; b. stampare il numero di piazzole libere per un dato giorno, suddividendo il risultato tra le due sistemazioni possibili (ad esempio sistemazioni in tenda libere n. 23, sistemazioni in camper libere n.4); c. calcolare il costo complessivo del soggiorno per un dato cliente, comprensivo di sistemazione e servizi utilizzati. 1/6
Campeggio Cliente Sistemazione Servizio Osservazioni: Soluzione GLOSSARIO DEI TERMINI Termine Descrizione Relazioni con Struttura che offre ai propri clienti una sistemazione e servizi per periodi definiti di soggiorno. Caratterizzato da nome, indirizzo, P. IVA. Può avere più numeri di telefono. Persona che effettua il soggiorno. Caratterizzata da nome, cognome, indirizzo di residenza e codice fiscale. Complesso di informazioni riferito alla permanenza di un cliente presso il campeggio. E' caratterizzato da una determinata configurazione di sistemazione e servizi di base. E inoltre riferito ad un periodo ben definito e ad un singolo cliente. Sistemazione fisica entro il campeggio. Definita da numero di piazzola, tipo (camper o roulotte), dimensione, posizione e costo giornaliero. Entità che riassume i dati di un servizio aggiuntivo. Caratterizzata da costo orario. Campeggio Cliente Sistemazione Servizio L individuazione del soggiorno come entità fondamentale e la caratterizzazione temporale dello stesso è la principale difficoltà del problema proposto. Altre soluzioni sono possibili (ad esempio la codifica del soggiorno come relazione), con ovvie implicazioni sulle cardinalità delle relazioni e la definizione di attributi di relazione. L attributo multiplo telefono deve essere risolto tramite relazione con cardinalità 1-N. Alle entità soggiorno e servizio vengono assegnate chiavi addizionali onde evitare ambiguità legate agli altri attributi; Per la sistemazione si usa il codice piazzola, per il campeggio la partita IVA, per il cliente il codice fiscale. Il totale della fattura potrebbe essere un attributo della stessa (ammettendo qualche ridondanza). La soluzione proposta calcola il totale per derivazione. 2/6
SCHEMA E-R cogn ind nome CLIENTE (1,N) cf (0,N) presso effettua datain oretot (1,1) (0,N) SOGGIORNO include SISTEMAZIONE SERVIZIO (1,1) datafi tipo cod costog codpiaz relativo a desc cod (1,1) (0,N) costoor posiz dim (1,1) (1,N) ha TELEFONO numero (0,N) CAMPEGGIO nome piva ind REGOLE Regola di VINCOLO 1: una sistemazione non può essere assegnata a più soggiorni nello stesso periodo di tempo Regola di VINCOLO 2: un servizio può essere assegnato a più soggiorni nello stesso periodo di tempo ma va controllata la congruità delle ore totali assegnate Regola di DERIVAZIONE 1: Il costo complessivo di un soggiorno può essere calcolato a partire dai costi di sistemazione e servizi prescelti. 3/6
create schema CAMPEGGIO_TURISTICO create table CAMPEGGIO ( piva char(16) primary key, nome char(20) not null, ind char(40) ) CREAZIONE BASE DI DATI create table TELEFONO ( numero char(20) primary key, camp char(16), foreign key (camp) references CAMPEGGIO(piva) on update cascade on delete cascade) create table CLIENTE ( cf char(16) primary key, cogn char(20) not null, nome char(20), ind char(40) ) create table SISTEMAZIONE ( codpiaz integer primary key, tipo char(30), dim char(20), posiz char(20), costog numeric(7,2) not null ) create table SERVIZIO ( cod integer primary key, desc char(30), costoor numeric(7,2) not null ) 4/6
create table SOGGIORNO ( cod int primary key, datain date not null, datafi date not null, codcamp char(16), codsist integer, codcli char(16), foreign key (codcamp) references CAMPEGGIO(piva) on update cascade on delete no action, foreign key (codsist) references SISTEMAZIONE(codpiaz) on update cascade on delete no action, foreign key (codcli) references CLIENTE(cf) on update cascade on delete no action ) create table INCLUDE ( codsogg integer, codserv integer, oretot integer not null, primary key(codsogg, codserv), foreign key (codsogg) references SOGGIORNO(cod) on update cascade on delete cascade, foreign key (codserv) references SERVIZIO(cod) on update cascade on delete cascade ) QUERY 1 QUERY SELECT CLIENTE.* FROM CLIENTE, SOGGIORNO WHERE cf = SOGGIORNO.codcli AND datain <= vardata AND (datafi = NULL OR datafi >= vardata) QUERY 2 NOTA: trova prima tutte le sistemazioni occupate e usando la nidificazione trova successivamente le libere SELECT tipo AS Tipo_sistemazione, COUNT(*) AS numero_libere FROM SISTEMAZIONE WHERE codpiaz NOT IN (SELECT codsist FROM SOGGIORNO WHERE datain <= vardata AND (datafi = NULL OR datafi >= vardata) ) GROUP BY tipo 5/6
QUERY 3 NOTA: poiché un dato cliente potrebbe aver effettuato più soggiorni, utilizzando più servizi per ogni singolo soggiorno, trova prima i costi di tutti i soggiorni del cliente e poi i costi di tutti i servizi, unisce le tabelle e calcola il totale raggruppando per codice soggiorno SELECT CODSOG AS CODICE_SOGGIORNO, SUM(COSTO) AS TOTALE FROM (SELECT cod AS CODSOG, (datafi - datain) * costog AS COSTO FROM SOGGIORNO, SISTEMAZIONE, CLIENTE WHERE SOGGIORNO.codsist = codpiaz AND SOGGIORNO.codcli = cf AND cf = varcf UNION SELECT cod AS CODSOG, oretot*costoor AS COSTO FROM SOGGIORNO, CLIENTE, SERVIZIO, INCLUDE WHERE SOGGIORNO.codcli = cf AND SOGGIORNO.cod = INCLUDE.codsogg AND SERVIZIO.cod = INCLUDE.codserv AND cf = varcf ) GROUP BY CODSOG 6/6