Capitol o 10
Capitol o 10
Capitol o 10
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.1
Realizzare una procedura in un linguaggio di programmazione di alto livello che tramite SQL
Embedded elimina dalla tabella DIPARTIMENTO l'elemento che ha il nome che viene fornito come
parametro alla procedura.
Soluzione:
Soluzione in C:
#include<stdlib.h>
main()
{
char Nome1;
char Nome2;
begin declare section;
char Nome;
exec sql end declare section;
do {
exec sql fetch DipCursore into
:Nome1;
if (Nome1 == Nome2)
exec sql delete from Dipartimento
where nome = :Nome1;
}while (sqlca.sqlcode==0)
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.2
Realizzare un programma in un linguaggio di programmazione di alto livello che tramite SQL
Embedded costruisce una videata in cui si presentano le caratteristiche di ogni dipartimento seguito
dall'elenco degli impiegati che lavorano nel dipartimento, ordinati per cognome
Soluzione:
#include<stdlib.h>
main()
{
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.3
Realizzare l'esercizio precedente usando ADO
Soluzione:
#include<stdlib.h>
main()
{
conn ADODB.Connection;
impiegati ADODB.Recordset;
dipartimenti ADODB.Recordset;
comandoSQL ADODB.Command;
buffer string;
do{
printf(“Dipartimento: “, dipartimenti!Nome, “ situato in:
“,dipartimenti.Città,” Numero Dipendenti:
“,dipartimenti.NumeroDip.” “Dipendenti:”);
do
{
impiegati = New ADODB.Recordset;
buffer = “select CognomeImpiegato, NomeImpiegato
from Impiegato join Dipartimento on
Impiegato.Dipartimento=Dipartimento.”,
dipartimenti!Nome,
“order by CognomeImpiegato”;
comandoSQL.CommandText = buffer;
impiegati.Open ComandoSQL(conn);
printf( impiegati.CognomeImpiegato,” “,
impiegati.NomeImpiegato);
impiegati.movenext;
}while(impiegati.EOF);
dipartimenti.movenext;
}while(dipartimenti.EOF);
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.4
Realizzare un programma java che scandisce gli impiegati ordinati per cognome e inserisce ogni
impiegato che si trova in una posizione che è un multiplo di 10 in una tabella IMPIEGATIESTRATTI
Soluzione:
import java.sql.*;
public class ImpiegatiEstratti {
public static void main(String[] arg){
if(i=10)
{
string NomeImpiegato = risultato.getString(“NomeImpiegato”);
string CognomeImpiegato =
risultato.getString(“CognomeImpiegato”);
string Dipartimento= risultato.getString(“Dipartimento”);
int Stipendio = risultato.getString(“Stipendio”);
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Statement interrogazione2 = conn.createStatement();
ResultSet risultato2 = interrogazione2.executeQuery(
“insert into IMPIEGATIESTRATTI
values(“ NomeImpiegato”,”
CognomeImpiegato”,”
dipartimento”,”
stipedio”,
)”;
i=0;
}}}}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.5
Realizzare un programma che accede al contenuto di una tabella
Capitolo(Numero, Titolo, Lunghezza)
che descrive i capitoli di un libro, con il numero e la dimensione delle pagine. Il programma quindi
popola una tabella
Indice(Numero, Titolo, NumPagine)
in cui si presenta il numero di pagina nel quale inizia il capitolo, supponendo che il capitolo 1 inizia
sulla prima pagina e che i capitoli devono iniziare su pagine dispari (eventualmente introducendo una
pagina bianca alla fine del capitolo)
Soluzione:
#include<stdlib.h>
main()
{
exec sql begin declare section;
char Titolo[50];
int Numero, Lunghezza;
exec sql end declare section;
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.6 Con riferimento al seguente schema relazionale:
• I MPIEGATI (CodiceFiscale, Cognome, Nome, DataNascita, Dipartimen-
to, Stipendio) con vincolo di integrità referenziale fra l’attributo Dipartimento
e la relazione D IPARTIMENTI
• D IPARTIMENTI (Codice, Nome, Sede)
• P ROGETTI (Sigla, Titolo, Valore)
• PARTECIPAZIONE (Impiegato, Progetto, Data) con vincoli di integrità re-
ferenziale fra l’attributo Progetto e la relazione P ROGETTI e fra l’attributo
Impiegato e la relazione I MPIEGATI
scrivere un metodo Java con JDBC (o un frammento di programma in SQL im-
merso in un linguaggio o pseudolinguaggio di programmazione) che inserisca un
impiegato con tutti i dati (letti da input o passati come parametri), verificando l’e-
sistenza del dipartimento, con rifiuto dell’operazione in caso negativo. Assumere,
per semplicità, che il sistema non supporti i vincoli di riferimento.
Soluzione
static void inserimento(Connection con, String cf,
String cognome, String nome,
String dataNascita, String dipartimento,
int stipendio){
try {
// Verifica codice dipartimento
PreparedStatement pquery =
con.prepareStatement(
"select * " +
"from Dipartimenti " +
"where Codice = ?");
pquery.setString(1,dipartimento);
ResultSet result = pquery.executeQuery();
if (result.next()){
pquery.close();
// Il dipartimento esiste
PreparedStatement pupdate =
con.prepareStatement(
"insert into Impiegati" +
"(CodiceFiscale,Cognome,Nome," +
"DataNascita,Dipartimento,Stipendio)" +
"values (?,?,?,?,?,?)");
pupdate.setString(1,cf);
pupdate.setString(2,cognome);
pupdate.setString(3,nome);
pupdate.setString(4,dataNascita);
pupdate.setString(5,dipartimento);
pupdate.setInt(6,stipendio);
pupdate.executeUpdate();
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
pupdate.close();
}
else {
pquery.close();
System.out.println(
"Non esiste dipartimento " +
dipartimento);
}
}
catch (SQLException e){
System.out.println("Errore");
System.out.println(e.getErrorCode() + " " +
e.getSQLState() + e.getMessage() );
}
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.7 Dato lo schema relazionale seguente:
Impiegato i = null;
PreparedStatement s = this.con.prepareStatement(
"setect * " +
"from Impiegati, DatiImpiegati" +
"where Dati = CodiceDati" +
"and cognome = ?" +
"and nome = ?");
s.setString(1, cognome);
s.setString(2, nome);
ResultSet rs = s.executeQuery();
if (rs.hasNext()){
i = new Impiegato (rs.getInt("Codice"),
rs.getString("Nome"),
rs.getString("Cognome"),
rs.getString("Telefono"));
}
s.close();
return i;
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.8 Si consideri il seguente schema relazionale (con gli evidenti
vincoli di integrità referenziale):
Scrivere un metodo Java con JDBC che inserisca un nuovo negozio con codi-
ce, nome, indirizzo e città (letti da input o passati come parametri), prelevando
provincia e regione da altre della stessa tabella (nell’ipotesi che, fissata la città,
provincia e regione siano univocamente determinate) e segnalando come errore (o
eccezione) il caso in cui i dati sulla città non siano disponibili.
Soluzione
/* query di inserimento */
PreparedStatement ins = con.PrepareStatement(
"insert into negozi values (?,?,?,?,?,?);");
ins.setString(1, codice);
ins.setString(2, nome);
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
ins.setString(3, indirizzo);
ins.setString(5, prov);
ins.setString(6, reg);
ins.executeUpdate();
ins.close();
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.9 Con riferimento allo relazionale seguente:
• FARMACI (Codice, NomeFarmaco, PrincipioAttivo, Produttore, Prezzo)
con vincolo di integrità referenziale fra Produttore e la relazione P RODUTTORI
e fra PrincipioAttivo e la relazione S OSTANZE
• P RODUTTORI (CodProduttore, Nome, Nazione)
• S OSTANZE (ID, NomeSostanza, Categoria)
scrivere un metodo Java con JDBC che (supponendo già disponibile una connes-
sione, passata come parametro) stampi un prospetto con tutti i farmaci, organizzati
per produttore:
CodProduttore Nome Nazione
CodiceFarmaco NomeFarmaco Prezzo Sostanza
CodiceFarmaco NomeFarmaco Prezzo Sostanza
...
CodProduttore Nome Nazione
...
Soluzione
public void prontProspetto(Connection con)
throws SQLException{
PreparedStatement p = con.prepareStatement(q1);
ResultSet rs, rs1;
PreparedStatement p2 = con.prepareStatement(q2);
rs.con.executeQuery();
while(rs.hasNext()) {
p1.setString(rs.getString("CodProduttore");
rs1=p1.executeQuery();
System.out.println(
rs.getString("CodProduttore") +
" " + rs.getString("Nome") +
" " + rs.getString("Nazione"));
while(rs1.hasNext()) {
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
System.out.Println(
rs1.getString("CodiceFarmaco") +
" " + rs1.getString("NomeFarmaco") +
" " + rs1.getString("Prezzo") +
" " + rs1.getString("Sostanza"));
}
}
p.close();
p2.close()
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.10 Si consideri una base di dati che contiene informazioni sugli
impiegati, i progetti e le sedi di una azienda, con le partecipazioni degli impiegati
ai progetti e le sedi di svolgimento dei progetti stessi; essa contiene le seguenti
relazioni:
PreparedStatement s1 = con.prepareStatement(q1);
PreparedStatement s2 = con.prepareStatement(q2);
rs1 = s1.executeQuery();
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
while(rs1.hasNext()) {
codice = rs1.getString("Codice");
System.out.println( codice +
" " + getString("Titolo"));
s2.setString(codice);
rs2. = s2.executeQuery();
while(rs2.hasNext()) {
System.out.println(
rs2.getString("Matricola" +
" " + rs2.getString("Cognome"));
}
}
s1.close();
s2.close();
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.11 Estendere la risposta al quesito precedente mostrando anche,
per ciascun progetto, la lista delle sedi di svolgimento, costruendo quindi un
prospetto come il seguente:
CodProgetto TitoloProgetto
MatricolaImpiegato CognomeImpiegato
MatricolaImpiegato CognomeImpiegato
...
NomeSede Città
NomeSede Città
...
CodProgetto TitoloProgetto
...
Soluzione
PreparedStatement s1 = con.prepareStatement(q1);
PreparedStatement s2 = con.prepareStatement(q2);
PreparedStatement s3 = con.prepareStatement(q3);
rs1 = s1.executeQuery();
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
while(rs1.hasNext()) {
codice = rs1.getString("Codice");
System.out.println( codice +
" " + getString("Titolo"));
s2.setString(codice);
rs2. = s2.executeQuery();
while(rs2.hasNext()) {
System.out.println(
rs2.getString("Matricola" +
" " + rs2.getString("Cognome"));
}
s3.setString(codice);
rs3 = s3.executeQuery();
while(rs3.hasNext()) {
System.out.println(
rs3.getString("NomeSede") + " " +
rs3.getString("Citta"));
}
}
s1.close();
s2.close();
s3.close();
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.12 Si ha uno schema di tabella I MPIEGATO (Nome, Indirizzo,
Capo) in cui l’attributo Capo rappresenta il nome del superiore dell’impiegato,
descritto a sua volta nella tabella. Definire il metodo Java (o un frammento di
programma in SQL immerso in un linguaggio o pseudolinguaggio di programma-
zione) setCapo(Impiegato i1, Impiegato i2) che memorizza la relazione tra capo e
sottoposto esistente tra due impiegati rifiutando l’inserimento se la relazione o la
sua inversa già esistono. Supporre che gli oggetti Impiegato abbiano una variabile
di istanza per ogni campo della corrispondente colonna nello schema relazionale
con opportuna corrispondenza di tipi.
Soluzione
/* query di verifica */
String qV = "select * " +
"from Impiegato" +
"where nome = ?" +
"and capo = ?" +
"or" +
"nome = ?" +
"and capo = ?";
/* query di aggiornamento */
String upd = "update Impiegati" +
" set capo = ?" +
" where nome = ?";
PreparedStatement p1 = con.prepareStatement(qV);
p1.setString(1, i.getNome());
p1.setString(2, capo.getNome());
p1.setString(3, capo.getNome());
p1.setString(4, 1.getNome());
ResultSet rs = p1.executeQuery();
if(rs.size() > 0) {
p1.close();
return false;
}
PreparedStatement p2 = con.prepareStatement(upd);
p2.setString(1, capo.getName());
p2.setString(2, i.getName());
p2.executeUpdate();
p1.close();
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
p2.close();
return true;
}
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.13 Con riferimento allo schema relazionale dell’esercizio 10.10, si
scriva un programma Java che realizza quanto richiesto usando JPA. Si mostrino
le annotazioni alle classi Java necessarie per creare la mappatura relazionale degli
oggetti Java. Tale mappatura deve contenere anche le annotazioni necessarie per
la gestione automatica della cancellazione delle istanze persistenti della classe
SVOLGIMENTO collegate tramite vincoli di integrità referenziale alle istanze
delle classi PROGETTO e SEDE. Si realizzino le funzioni di estrazione dei dati
mediante interrogazioni JPQL.
Soluzione
Vedere il codice nell’allegato file Ex10.13.zip
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.14 Si consideri un’applicazione che gestisce l’anagrafica il perso-
nale di un’azienda. Ogni membro del personale caratterizzato da Nome, Cogno-
me, e data di nascita. Gli impiegati dell’azienda sono inoltre cartterizzati da una
matricola e un salario. I collaboratori esterni sono caratterizzati da un numero
di partita IVA e dal costo orario. La classificazione del personale in impiegati e
collaboratori è totale ed esclusiva. Si scriva un programma Java che consenta di
gestire oggetti delle tre classi descritte e si mostri la mappatura relazionale degli
oggetti secondo i tre schemi: Single table per class hierarchy, Table per concrete
class e Joined tables. Si includa nel programma Java un metodo che stampa tutti
gli oggetti dell’anagrafica in ordine alfabetico di cognome, precisando oltre agli
attributi persistenti anche il tipo di ciascun oggetto.
Soluzione
Vedere il codice nell’allegato file Ex10.14.zip
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.
Esercizio 10.15 Effettuare una comparazione sull’efficienza dei due approcci
seguenti per ottenere tutti i corsi in cui un determinato professore insegna. Il
metalinguaggio utilizzato é una ipotetica codifica in cui si può immergere l’SQL.
do
loop while (not cursore1%empty);
fetch cursore1 into Professore;
execute query2(Professore) into cursore2;
do
loop while (not %cursore2%empty);
fetch cursore2 into corso;
print(Professore.Nome, Professore.Cognome,
Corso);
end loop;
end loop;
query1:
query2:
select *
from Corsi
where Professore = ?;
Soluzione
L’approccio 2 è sicuramente più efficiente. La query è predicibile a priori ed
interamente interpretata ed ottimizzata dal dbms, in grado di garantire presta-
zioni migliori di un qualsiasi compilatore di linguaggio di programmazione. Il
programma 1 fornisce implicitamente una implementazione di un join mediante
l’annidamento di due cicli. Tale join è sicuramente ottimizzato in maniera più
avanzata attraverso la dichiarazione esplicita di voler effettuare una tale operazio-
ne a livello database. Inoltre, al punto 2 viene eseguita una sola query, mentre il
punto 1 comporta l’esecuzione di una query di indagine per ogni professore.
Paolo Atzeni, Stefano Ceri, Piero Fraternali, Stefano Paraboschi e Riccardo Torlone
Basi di dati 4/ed, © 2014 McGraw-Hill Education (Italy) S.r.l.