├── .gitignore ├── 20230217_Esame.sql ├── Esercizi ├── 2015_03_27 │ ├── DB_creation.sql │ ├── FunzioneES4.sql │ └── Traccia.pdf ├── 2022_12_08_AutoCheck │ ├── Creazione_DB.sql │ ├── Insert.sql │ ├── TriggerES1.sql │ ├── TriggerES2.sql │ └── traccia.pdf ├── 2022_12_08_HashtagFoto │ ├── Creazione DB.sql │ ├── Funzione_1(ES5).sql │ ├── Funzione_2(ES6).sql │ ├── Insert.sql │ └── traccia.pdf ├── 2022_12_08_RivisteArticoli │ ├── Creazione_DB.sql │ ├── Funzione_1(ES4).sql │ ├── Insert.sql │ ├── Trigger_1(ES3).sql │ └── traccia.pdf ├── 2022_12_13_LogRichieste │ ├── Creazione DB.sql │ ├── Insert.sql │ ├── LOG_Funzione(ES2).sql │ ├── LOG_Trigger_1(ES1).sql │ └── Traccia.pdf └── AlberiNodi │ ├── Alberi.pdf │ ├── Creazione_E_Trigger.sql │ └── Traccia.pdf └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | .puml 4 | -------------------------------------------------------------------------------- /20230217_Esame.sql: -------------------------------------------------------------------------------- 1 | --Esercizio 3 2 | --1) 3 | ALTER TABLE COMPORDINE 4 | ADD CONSTRAINT UQ_ArticoloOrdine UNIQUE (CodO, CodA); 5 | 6 | --2) 7 | ALTER TABLE LISTINO 8 | ADD CONSTRAINT CK_PrezziQuantita CHECK 9 | (quantita1>quantita2) 10 | 11 | 12 | --SE QUANTITA1>QUANTITA2 13 | --ALLORA QUANTITA1/PREZZO1=Quantita_Art_Attuale) THEN 45 | n_articoli_check=n_articoli_check+1; 46 | END IF; 47 | END LOOP; 48 | 49 | IF(n_articoli_ordine<>n_articoli_check) 50 | UPDATE Ordine SET Completo='N' WHERE CodO=NEW.CodO; 51 | ELSE IF 52 | MOVE ABSOLUTE 0 FROM cursore_ArticoliQuantita; 53 | FOR i IN 1..n_articoli LOOP 54 | FETCH cursore_ArticoliQuantita INTO CodA_Attuale, Quantita_Art_Attuale; 55 | UPDATE Magazzino SET Quantita=Quantita-Quantita_Art_Attuale WHERE CodA=CodA_Attuale; 56 | END LOOP; 57 | CLOSE cursore_ArticoliQuantita; 58 | RETURN NEW; 59 | END; 60 | $$ 61 | LANGUAGE PLPGSQL; 62 | 63 | CREATE TRIGGER trig_es5 64 | BEFORE UPDATE ON b.Ordine 65 | WHEN (Completo='S') 66 | EXECUTE FUNCTION es5; 67 | 68 | /* 69 | TUTTI GLI ARTICOLI CHE HANNO SCORTA 70 | SUFFICIENTE IN MAGAZZINO (R1) <- select di CodA, CodO(CompOrdine c JOIN Magazzino m ON m.Coda=c.CodA 71 | WHERE m.quantita>=c.quantita) 72 | 73 | RESULT <-SELECT CodA (R1 JOIN Ordine o ON r1.codO=o.CodO) WHERE Completo='N'; 74 | */ 75 | ------------------------------------------------------------------------------------------------------------------------ 76 | 77 | --TRIGGER ESERCIZIO 78 | CREATE TRIGGER cancella_prenotazioni 79 | AFTER INSERT OR UPDATE 80 | ON prestito 81 | FOR EACH ROW 82 | WHEN (articolo.datapubblicazione IS NOT NULL) 83 | EXECUTE FUNCTION b.prova; 84 | 85 | CREATE FUNCTION b.prova() RETURNS TRIGGER AS 86 | $$ 87 | DECLARE 88 | id_utente prestito.utente%TYPE=(SELECT UTENTE 89 | FROM PRESTITO 90 | WHERE codprestito = NEW.codprestito); 91 | BEGIN 92 | DELETE FROM prenotazione p WHERE p.utente = id_utente; 93 | end; 94 | $$ 95 | language plpgsql; 96 | 97 | 98 | 99 | CREATE TRIGGER richieste_prestito 100 | AFTER INSERT 101 | ON prestito 102 | FOR EACH ROW 103 | DECLARE 104 | v_ISBN libro.ISBN%TYPE = (SELECT ISBN 105 | FROM prestito p 106 | JOIN esemplare e 107 | WHERE p.codicebarre = e.codicebarre 108 | AND codprestito = NEW.codprestito); 109 | BEGIN 110 | DELETE 111 | from PRENOTAZIONE 112 | WHERE utente = NEW.utente 113 | AND ISBN = v_ISBN; 114 | END; 115 | $$ 116 | 117 | ------------------------------------------------------------------------------------------------------------------------ -------------------------------------------------------------------------------- /Esercizi/2015_03_27/DB_creation.sql: -------------------------------------------------------------------------------- 1 | drop schema u; 2 | create schema u; 3 | 4 | create table u.libro( 5 | isbn varchar(10) 6 | primary key, 7 | titolo varchar(20), 8 | editore varchar(20), 9 | anno varchar(4) 10 | ); 11 | 12 | create table u.esemplare( 13 | ISBN varchar(10), 14 | codicebarre varchar(20) 15 | primary key, 16 | collocazione varchar(10), 17 | prestito boolean, 18 | consultazione boolean, 19 | constraint fk_libro foreign key (ISBN) references u.libro(isbn) 20 | ); 21 | 22 | 23 | create table u.profilo( 24 | codprofilo varchar(5) 25 | primary key, 26 | maxdurata int, 27 | maxprestito int 28 | ); 29 | 30 | create table u.utente( 31 | cf varchar(10) primary key , 32 | codprofilo varchar(5), 33 | nome varchar(15), 34 | cognome varchar(15), 35 | data date, 36 | 37 | constraint fk_profilo foreign key (codprofilo) references u.profilo(codprofilo) 38 | ); 39 | create table u.prestiti( 40 | codprestito serial primary key, 41 | codbarre varchar(20), 42 | utente varchar(10), 43 | data date, 44 | scadenza date, 45 | restituzione date, 46 | sollecito date, 47 | 48 | constraint fk_esemplare foreign key (codbarre) references u.esemplare(codicebarre), 49 | constraint fk_utente foreign key (utente) references u.utente(cf) 50 | ); 51 | create table u.prenotazione( 52 | codprenotazione serial, 53 | isbn varchar(10), 54 | utente varchar(10), 55 | data date, 56 | constraint fk_libro foreign key (isbn) references u.libro(isbn), 57 | constraint fk_utente foreign key (utente) references u.utente(cf) 58 | ); 59 | 60 | insert into u.libro (isbn, titolo, editore, anno) 61 | VALUES ('978-88-17-00000-0', 'Il Signore degli Anelli', 'Mondadori', '1954'); 62 | 63 | insert into u.esemplare(isbn, codicebarre, collocazione, prestito, consultazione) 64 | VALUES ('978-88-17-00000-0', '9788817000000', 'A1', false, false); 65 | 66 | insert into u.profilo(codprofilo, maxdurata, maxprestito) 67 | VALUES ('A', 30, 3); 68 | 69 | insert into u.utente(cf, codprofilo, nome, cognome, data) 70 | VALUES ('RSSMRA80A01F205X', 'A', 'Mario', 'Rossi', '1980-01-01'); 71 | 72 | insert into u.prestiti(codbarre, utente, data, scadenza, restituzione, sollecito) 73 | VALUES ('9788817000000', 'RSSMRA80A01F205X', '2018-01-01', '2018-01-31', null, false); -------------------------------------------------------------------------------- /Esercizi/2015_03_27/FunzioneES4.sql: -------------------------------------------------------------------------------- 1 | create function u.funtion_1() returns varchar 2 | as 3 | $$ 4 | declare 5 | output_finale text; 6 | data_corrente u.prestiti.sollecito%TYPE; 7 | risultato_query record; 8 | cursore_2 cursor for (select * 9 | from prestiti); 10 | query_utente_nome varchar(1000); 11 | query_utente_cognome varchar(1000); 12 | query_libro_titolo varchar(1000); 13 | nome_utente u.utente.nome%TYPE; 14 | cognome_utente u.utente.cognome%TYPE; 15 | titolo_libro u.libro.titolo%TYPE; 16 | 17 | 18 | begin 19 | open cursore_2; 20 | loop 21 | fetch cursore_2 into risultato_query; 22 | exit when not found; 23 | if (risultato_query.scadenza > data_corrente) then 24 | update u.prestiti set sollecito=True where codprestito=risultato_query.codprestito; 25 | query_utente_nome = 'select ut.nome' || 26 | 'from u.presito p join u.utente ut on ut.cf=' 27 | || '''' || risultato_query.utente || ''''; 28 | execute query_utente_nome into nome_utente; 29 | query_utente_cognome = 'select ut.cognome' || 30 | 'from u.presito p join u.utente ut on u.cf=' 31 | || '''' || risultato_query.utente || ''''; 32 | execute query_utente_cognome into cognome_utente; 33 | query_libro_titolo = 'select l.titolo' || 34 | 'from (u.presito p join u.esemplare e on p.codbarre=' || 35 | 'e.codbarre) join u.libro l on e.isbn = l.isbn' || 36 | 'where p.codprestito=' || '''' || risultato_query.codprestito || ''''; 37 | execute query_libro_titolo into titolo_libro; 38 | output_finale = risultato_query.utente || nome_utente || 39 | cognome_utente || titolo_libro; 40 | 41 | end if; 42 | end loop; 43 | end 44 | $$ 45 | language plpgsql; -------------------------------------------------------------------------------- /Esercizi/2015_03_27/Traccia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/2015_03_27/Traccia.pdf -------------------------------------------------------------------------------- /Esercizi/2022_12_08_AutoCheck/Creazione_DB.sql: -------------------------------------------------------------------------------- 1 | --DROP SCHEMA v CASCADE; 2 | CREATE SCHEMA v; 3 | 4 | 5 | CREATE TABLE v.TARIFFE 6 | ( 7 | Ingresso VARCHAR(32) NOT NULL, 8 | Uscita VARCHAR(32) NOT NULL, 9 | KM INTEGER NOT NULL, 10 | Categoria INTEGER NOT NULL, 11 | Costo DOUBLE PRECISION NOT NULL, 12 | CONSTRAINT PK_TARIFFE PRIMARY KEY (Ingresso, Uscita, Categoria) 13 | ); 14 | 15 | CREATE TABLE v.AUTO 16 | ( 17 | Targa VARCHAR(10) NOT NULL, 18 | CODFIS VARCHAR(16) NOT NULL, 19 | Categoria INTEGER NOT NULL, 20 | CONSTRAINT PK_AUTO PRIMARY KEY (Targa) 21 | ); 22 | 23 | 24 | CREATE TABLE v.PCHECK 25 | ( 26 | PuntoCheck VARCHAR(10) NOT NULL, 27 | VelocitaMax INTEGER NOT NULL, 28 | 29 | CONSTRAINT PK_PCHECK PRIMARY KEY (PuntoCheck) 30 | ); 31 | 32 | CREATE TABLE v.CHECK 33 | ( 34 | PuntoCheck VARCHAR(10) NOT NULL, 35 | Targa VARCHAR(10) NOT NULL, 36 | Velocita INTEGER NOT NULL, 37 | Data DATE NOT NULL, 38 | Tempo TIME NOT NULL, 39 | Infrazione BOOLEAN, 40 | 41 | CONSTRAINT PK_CHECK PRIMARY KEY (PuntoCheck, Targa, Data, Tempo), 42 | CONSTRAINT FK_PCHECK FOREIGN KEY (PuntoCheck) REFERENCES v.PCHECK (PuntoCheck), 43 | CONSTRAINT FK_AUTO FOREIGN KEY (Targa) REFERENCES v.AUTO (Targa) 44 | ); 45 | 46 | CREATE TABLE v.VIAGGIO 47 | ( 48 | CodiceViaggio VARCHAR(10) NOT NULL, 49 | Targa VARCHAR(10) NOT NULL, 50 | DataI DATE NOT NULL, 51 | DataF DATE, 52 | OraI TIME NOT NULL, 53 | OraF TIME, 54 | Ingresso VARCHAR(32) NOT NULL, 55 | Uscita VARCHAR(32), 56 | Tariffa DOUBLE PRECISION, 57 | KM INTEGER, 58 | 59 | CONSTRAINT PK_VIAGGIO PRIMARY KEY (CodiceViaggio), 60 | CONSTRAINT FK_VIAGGIO_AUTO FOREIGN KEY (Targa) REFERENCES v.AUTO (Targa), 61 | CONSTRAINT CK_VIAGGIO CHECK (DataF > DataI OR (DataF = DataI AND OraF > OraI)), 62 | CONSTRAINT CK_VIAGGIO2 CHECK (KM > 0), 63 | CONSTRAINT CK_VIAGGIO3 CHECK (Tariffa > 0) 64 | ); 65 | 66 | 67 | -------------------------------------------------------------------------------- /Esercizi/2022_12_08_AutoCheck/Insert.sql: -------------------------------------------------------------------------------- 1 | 2 | INSERT INTO v.AUTO(targa, codfis, categoria) values (1, 1, 1), 3 | (2, 2, 2); 4 | 5 | 6 | INSERT INTO v.PCHECK(puntocheck, velocitamax) values ('prova', 10); 7 | INSERT INTO v.PCHECK(puntocheck, velocitamax) values ('prova1', 10); 8 | 9 | INSERT INTO v.TARIFFE(ingresso, uscita, km, categoria, costo) values ('ingresso1_cat1','uscita1_cat1', 10, 1, 10), 10 | ('ingresso1_cat2','uscita1_cat2', 10, 2, 20), 11 | ('ingresso2_cat1','uscita2_cat1', 20, 1, 11), 12 | ('ingresso2_cat2','uscita2_cat2', 20, 2, 22); 13 | 14 | 15 | 16 | 17 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) VALUES ('prova', 1, 9, '2001-01-01', '00:30'); 18 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) VALUES ('prova1', 1, 11, '2001-01-01', '00:45'); 19 | 20 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) 21 | VALUES ('prova', '2', 11,'2007-07-07','00:45'), 22 | ('prova1', '2', 9,'2007-07-07','00:40'), 23 | ('prova1', '2', 11,'2007-12-07','01:50'); 24 | 25 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) 26 | values ('prova', '1', 9, '2001-01-01', '00:00:00'); -- non infrangono 27 | 28 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) 29 | values ('prova', '1', 110, '2001-01-01', '00:00:10'); -- infrangono 30 | 31 | INSERT INTO v.VIAGGIO(CODICEVIAGGIO, TARGA, DATAI, ORAI, INGRESSO) 32 | ( 33 | values (1, 1, '2001-01-01','01:01', 'ingresso1_cat1'), 34 | (2, 1, '2001-01-01', '11:11', 'ingresso2_cat1'), 35 | (3, 2, '2012-12-12', '12:12', 'ingresso1_cat2'), 36 | (4, 2, '2022-12-22', '22:22', 'ingresso2_cat2') 37 | ); 38 | 39 | UPDATE v.viaggio 40 | SET uscita='uscita1_cat1' 41 | WHERE codiceviaggio='1'; 42 | 43 | UPDATE v.viaggio 44 | SET uscita='uscita2_cat1' 45 | WHERE codiceviaggio='2'; 46 | 47 | UPDATE v.viaggio 48 | SET uscita='uscita1_cat2' 49 | WHERE codiceviaggio='3'; 50 | 51 | UPDATE v.viaggio 52 | SET uscita='uscita2_cat2' 53 | WHERE codiceviaggio='4'; 54 | 55 | UPDATE v.viaggio 56 | SET uscita='uscita2_cat2' 57 | WHERE codiceviaggio='5'; 58 | 59 | INSERT INTO V.CHECK(puntocheck, targa, velocita, data, tempo) 60 | values ('prova', '1', 30, '2022-12-14', '12:05'); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_AutoCheck/TriggerES1.sql: -------------------------------------------------------------------------------- 1 | --TRIGGER 1 2 | /* 3 | Si scriva il seguente trigger. Quando viene inserito un 4 | check per un viaggio si controlla se la velocit`a rilevata è 5 | superiore alla velocit`a massima. Se è superiore, si pone a TRUE 6 | il campo infrazione del CHECK. 7 | */ 8 | 9 | SELECT codiceviaggio, targa, V.ingresso, V.uscita, tariffa, V.km 10 | FROM v.viaggio AS V NATURAL JOIN v.AUTO AS A, v.Tariffe AS T 11 | WHERE T.ingresso=V.ingresso 12 | 13 | CREATE OR REPLACE FUNCTION v.setInfraction() RETURNS trigger AS 14 | $$ 15 | DECLARE 16 | MAXvelocita v.pcheck.velocitaMAX%TYPE; 17 | BEGIN 18 | SELECT velocitaMAX INTO MAXvelocita 19 | FROM v.pcheck WHERE puntocheck = NEW.puntocheck; 20 | 21 | IF NEW.velocita > MAXvelocita THEN 22 | UPDATE v.check 23 | SET infrazione = TRUE -- l'infrazione esiste 24 | WHERE puntocheck = NEW.puntocheck 25 | AND targa = NEW.targa 26 | AND velocita=NEW.velocita 27 | AND data=NEW.data 28 | AND tempo=NEW.tempo; 29 | END IF; 30 | RAISE NOTICE 'Infrazione: %', new.infrazione; 31 | RETURN NULL; 32 | END 33 | $$ LANGUAGE plpgsql; 34 | 35 | CREATE or REPLACE TRIGGER Infractions AFTER INSERT ON v.check 36 | FOR EACH ROW 37 | EXECUTE PROCEDURE v.setInfraction(); 38 | 39 | ------------------------------------------------------------------------------------------------------------------------ 40 | -- Insert per testare il trigger 41 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) 42 | values ('prova', '1', 9, '2001-01-01', '00:00:00'); -- non infrangono 43 | 44 | INSERT INTO v.CHECK(puntocheck, targa, velocita, data, tempo) 45 | values ('prova', '1', 110, '2001-01-01', '00:00:10'); -- infrangono 46 | -------------------------------------------------------------------------------- /Esercizi/2022_12_08_AutoCheck/TriggerES2.sql: -------------------------------------------------------------------------------- 1 | --TRIGGER 2 2 | /*Si scriva il seguente trigger. Quando viene aggiornato un 3 | viaggio esprimendo un valore per il casello di uscita si aggiornano anche gli 4 | attributi Km e Tariffa recuperando i valori dalla tabella TARIFFE (la tariffa 5 | dipende da ingresso, uscita e categoria dell’auto).*/ 6 | 7 | CREATE OR REPLACE FUNCTION v.update_viaggio() RETURNS trigger AS 8 | $$ 9 | DECLARE 10 | prezzo v.tariffe.costo%TYPE; 11 | chilometraggio v.viaggio.KM%TYPE; 12 | 13 | BEGIN 14 | IF (NEW.uscita IS NOT NULL) THEN --quando viene inserita l'uscita 15 | SELECT T.costo, T.KM --salvo il prezzo e i km relativi al viaggio 16 | INTO --prezzo, chilometraggio 17 | NEW.KM, NEW.Tariffa 18 | FROM V.AUTO AS A NATURAL JOIN V.viaggio AS V, 19 | v.tariffe AS T 20 | WHERE (NEW.uscita=T.uscita) 21 | AND (OLD.ingresso=T.ingresso) 22 | AND (T.categoria=A.categoria); 23 | 24 | --UPDATE v.viaggio 25 | --SET km=chilometraggio, tariffa=prezzo 26 | -- WHERE OLD.codiceviaggio=codiceviaggio; 27 | --RAISE NOTICE 'Old_Viaggio: %', OLD.codiceviaggio; 28 | END IF; 29 | RETURN NEW; 30 | EXCEPTION 31 | WHEN OTHERS THEN 32 | RAISE EXCEPTION 'Errore'; 33 | END 34 | 35 | $$ 36 | LANGUAGE plpgsql; 37 | 38 | 39 | CREATE OR REPLACE TRIGGER TRIGGER_2_prof BEFORE UPDATE OF uscita ON v.viaggio 40 | FOR EACH ROW 41 | EXECUTE PROCEDURE v.update_viaggio(); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_AutoCheck/traccia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/2022_12_08_AutoCheck/traccia.pdf -------------------------------------------------------------------------------- /Esercizi/2022_12_08_HashtagFoto/Creazione DB.sql: -------------------------------------------------------------------------------- 1 | xDROP SCHEMA f CASCADE; 2 | CREATE SCHEMA f; 3 | 4 | CREATE TABLE f.hashtag ( 5 | Parola VARCHAR(50), 6 | 7 | CONSTRAINT hashtag_pk PRIMARY KEY (parola) 8 | ); 9 | 10 | CREATE TABLE f.utente( 11 | CodU INTEGER, 12 | Nome VARCHAR(50), 13 | Cognome VARCHAR(50), 14 | email VARCHAR(50), 15 | CONSTRAINT utente_pk PRIMARY KEY (codU) 16 | ); 17 | 18 | CREATE TABLE f.album( 19 | CodA INTEGER, 20 | Nome VARCHAR(50), 21 | Titolo VARCHAR(50), 22 | Owner INTEGER, 23 | InAlbum INTEGER, 24 | 25 | CONSTRAINT album_pk PRIMARY KEY (codA), 26 | CONSTRAINT utente_fk FOREIGN KEY (owner) REFERENCES f.utente(codU) 27 | ); 28 | 29 | CREATE TABLE f.foto ( 30 | Codf SERIAL, 31 | Uri VARCHAR(100), 32 | Titolo VARCHAR(50), 33 | Owner INTEGER, 34 | CodAlbum INTEGER, 35 | Aggiunta TIMESTAMP, 36 | Rimossa TIMESTAMP, 37 | 38 | CONSTRAINT foto_pk PRIMARY KEY (codf), 39 | CONSTRAINT album_fk FOREIGN KEY (codalbum) REFERENCES f.album(codA), 40 | CONSTRAINT utente_fk FOREIGN KEY (owner) REFERENCES f.utente(codU) 41 | ); 42 | 43 | CREATE TABLE f.tagfoto ( 44 | CodF INTEGER, 45 | Parola VARCHAR(50), 46 | 47 | CONSTRAINT tagfoto_pk PRIMARY KEY (codf, parola), 48 | CONSTRAINT foto_fk FOREIGN KEY (codf) REFERENCES f.foto(codf), 49 | CONSTRAINT hashtag_fk FOREIGN KEY (parola) REFERENCES f.hashtag(parola) 50 | ); 51 | 52 | CREATE TABLE f.visibile( 53 | CodProp INTEGER, 54 | CodUt INTEGER, 55 | CodA INTEGER, 56 | 57 | CONSTRAINT visibile_pk PRIMARY KEY (codprop, codut, coda), 58 | CONSTRAINT proprietario_fk FOREIGN KEY (codprop) REFERENCES f.utente(codU), 59 | CONSTRAINT utente_fk FOREIGN KEY (codut) REFERENCES f.utente(codU), 60 | CONSTRAINT album_fk FOREIGN KEY (coda) REFERENCES f.album(codA) 61 | ); 62 | 63 | CREATE TABLE f.log( 64 | CodU INTEGER, 65 | CodF INTEGER, 66 | Time TIMESTAMP, 67 | Operation VARCHAR(50), 68 | 69 | CONSTRAINT log_pk PRIMARY KEY (codu, codf, time), 70 | CONSTRAINT utente_fk FOREIGN KEY (codu) REFERENCES f.utente(codU), 71 | CONSTRAINT foto_fk FOREIGN KEY (codf) REFERENCES f.foto(codf) 72 | ); 73 | 74 | CREATE TABLE f.tagalbum 75 | ( 76 | CodA INTEGER, 77 | Parola VARCHAR(50), 78 | 79 | CONSTRAINT tagalbum_pk PRIMARY KEY (coda, parola), 80 | CONSTRAINT album_fk FOREIGN KEY (coda) REFERENCES f.album(codA), 81 | CONSTRAINT hashtag_fk FOREIGN KEY (parola) REFERENCES f.hashtag(parola) 82 | ); 83 | -------------------------------------------------------------------------------- /Esercizi/2022_12_08_HashtagFoto/Funzione_1(ES5).sql: -------------------------------------------------------------------------------- 1 | /* 2 | Si scriva una funzione PLSQL che riceve in ingresso l’identificativo 3 | di un album e che restituisce una stringa contenente tutti i tag associati all’album e agli album in 4 | esso contenuti (ad ogni livello di profondità) senza ripetizioni. 5 | */ 6 | 7 | CREATE OR REPLACE PROCEDURE f.f2_figli(tagalbum f.album.coda%TYPE) AS $$ 8 | DECLARE 9 | figlio f.album.coda%TYPE; 10 | BEGIN 11 | FOR figlio IN (SELECT codA FROM f.album AS A WHERE A.inalbum=tagalbum) LOOP 12 | 13 | CALL f.f2_figli(figlio); 14 | RAISE NOTICE 'figlio: %', figlio; 15 | INSERT INTO f.tmp(codA) values (figlio); 16 | end loop; 17 | end 18 | $$ language plpgsql; 19 | 20 | 21 | CREATE OR REPLACE FUNCTION f.f1_rec(IN Input f.album.coda%type)RETURNS VARCHAR(500) AS $$ 22 | DECLARE 23 | stringa f.tagalbum.parola%TYPE; 24 | output VARCHAR(500); 25 | counter INTEGER = 1; 26 | BEGIN 27 | CREATE TABLE f.tmp(codA INTEGER); 28 | INSERT INTO f.tmp VALUES (Input); 29 | CALL f.f2_figli(Input); 30 | FOR stringa IN (SELECT DISTINCT parola FROM f.tmp NATURAL JOIN f.tagalbum) LOOP 31 | IF(counter>1) THEN 32 | output=CONCAT(output, ', ', stringa); 33 | ELSE 34 | output=stringa; 35 | END IF; 36 | counter = counter + 1; 37 | END LOOP; 38 | DROP TABLE f.tmp CASCADE; 39 | RETURN output; 40 | END 41 | $$ LANGUAGE plpgsql; 42 | 43 | SELECT f.f1_rec(1); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_HashtagFoto/Funzione_2(ES6).sql: -------------------------------------------------------------------------------- 1 | /* 2 | Usando SQL DINAMICO si scriva una funzione che riceve in ingresso 3 | una lista di tag separati dal carattere @ e che restituisce una stringa degli 4 | uri delle foto (separati da @) a cui sono associati tutti i tag passati per parametro 5 | */ 6 | 7 | CREATE OR REPLACE FUNCTION f.f_sqlDYN(IN stringa text) RETURNS text AS $$ 8 | DECLARE 9 | strQRY text; 10 | numParoleSTR INTEGER = regexp_count(stringa, '@') + 1; 11 | parolaSTR f.tagfoto.parola%TYPE; 12 | count INTEGER = 0; 13 | selectQRY text = 'SELECT uri FROM f.tagfoto as t NATURAL JOIN f.foto WHERE t.parola = '; 14 | cursQRY refcursor; 15 | output text; 16 | correctURI f.foto.uri%TYPE; 17 | BEGIN 18 | FOR i in 1..numParoleSTR LOOP 19 | parolaSTR = split_part(stringa, '@', i); 20 | IF count = 0 THEN 21 | strQRY = concat('(',selectQRY, '''', parolaSTR, '''', ')'); 22 | count = 1; 23 | ELSE 24 | strQRY = concat(' ', strQRY, ' INTERSECT ', '(',selectQRY, '''', parolaSTR, '''', ')'); 25 | end if; 26 | end loop; 27 | RAISE NOTICE 'Query: {%}', strQRY; 28 | 29 | OPEN cursQRY FOR EXECUTE strQRY; 30 | count = 0; 31 | LOOP 32 | FETCH cursQRY INTO correctURI; 33 | EXIT WHEN NOT FOUND; 34 | IF count = 0 THEN 35 | output = correctURI; 36 | count = 1; 37 | ELSE 38 | output = concat(output, '@', correctURI); 39 | end if; 40 | end loop; 41 | RAISE NOTICE 'RISULTATO: {%}', output; 42 | RETURN output; 43 | end 44 | $$ LANGUAGE plpgsql; 45 | 46 | SELECT f.f_sqlDYN('provatabelle1e3'); 47 | 48 | --(SELECT uri FROM f.tagfoto as t NATURAL JOIN f.foto WHERE t.parola = 'provatabelle1e3') INTERSECT (SELECT uri FROM f.tagfoto as t NATURAL JOIN f.foto WHERE t.parola = 'prova11') 49 | --SELECT uri FROM f.tagfoto NATURAL JOIN f.foto WHERE parola = 'x'; 50 | 51 | -------------------------------------------------------------------------------- /Esercizi/2022_12_08_HashtagFoto/Insert.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO F.album(coda, titolo, inalbum) 2 | values (1, 'padre1', null), 3 | (11, 'padre1-figlio1', 1), 4 | (12, 'padre1-figlio2', 1), 5 | (13, 'padre1-figlio3', 1), 6 | --ALBUM 11 7 | (111, 'padre11-figlio1', 11), 8 | (112, 'padre11-figlio2', 11), 9 | (113, 'padre11-figlio3', 11), 10 | --ALBUM 113 11 | (1131, 'padre113-figlio1', 113), 12 | --ALBUM 13 13 | (131, 'padre13-figlio1', 13), 14 | (132, 'padre13-figlio2', 13), 15 | --ALBUM 2 16 | (2, 'padre2', null), 17 | (21, 'padre2-figlio1', 2), 18 | (22, 'padre2-figlio2', 2); 19 | 20 | 21 | INSERT INTO f.hashtag(parola) 22 | values ('caso'), 23 | ('prova'), 24 | ('sei'), 25 | ('un'), 26 | ('grande'), 27 | ('bionda'), 28 | ('luigi'); 29 | 30 | INSERT INTO f.tagalbum(coda, parola) 31 | values (1,'caso'), 32 | (1,'grande'), 33 | (11,'bionda'), 34 | (12,'bionda'), 35 | (13,'caso'), 36 | --ALBERO 2 37 | (2,'bionda'), 38 | (21,'grande'), 39 | (22,'caso'), 40 | (22,'luigi'); 41 | 42 | INSERT INTO f.foto(codf, uri) 43 | values (1, 'uri1'), 44 | (2,'uri2'), 45 | (3,'uri3'), 46 | (4,'uri4'); 47 | 48 | INSERT INTO f.hashtag(parola) 49 | values ('prova11'), 50 | ('prova12'), 51 | ('prova13'), 52 | ('prova21'), 53 | ('prova22'), 54 | ('prova23'), 55 | ('prova31'), 56 | ('prova32'); 57 | 58 | INSERT INTO f.tagfoto(codf, parola) 59 | values (1,'prova11'), 60 | (1,'prova12'), 61 | (1,'prova13'), 62 | --foto 2 63 | (2,'prova21'), 64 | (2,'prova22'), 65 | (2,'prova23'), 66 | --foto 3 67 | (3,'prova31'), 68 | (3,'prova32'); 69 | 70 | INSERT INTO f.hashtag(parola) values ('provatabelle1e3'); 71 | 72 | INSERT INTO f.tagfoto(codf, parola) VALUES 73 | (1,'provatabelle1e3'), 74 | (3,'provatabelle1e3'); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_HashtagFoto/traccia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/2022_12_08_HashtagFoto/traccia.pdf -------------------------------------------------------------------------------- /Esercizi/2022_12_08_RivisteArticoli/Creazione_DB.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS r CASCADE ; 2 | CREATE SCHEMA IF NOT EXISTS r; 3 | 4 | CREATE TABLE r.rivista ( 5 | isnn VARCHAR(32), 6 | titolo VARCHAR(32), 7 | editore VARCHAR(32), 8 | periodicita VARCHAR(32), 9 | CONSTRAINT pk_rivista PRIMARY KEY (isnn) 10 | ); 11 | CREATE TABLE r.fascicolo( 12 | CodF VARCHAR(32), 13 | isnn VARCHAR(32), 14 | numero int, 15 | anno int, 16 | CONSTRAINT pk_fascicolo PRIMARY KEY (CodF), 17 | CONSTRAINT fk_fascicolo_rivista FOREIGN KEY (isnn) REFERENCES r.rivista(isnn) 18 | ); 19 | CREATE TABLE r.articolo ( 20 | doi VARCHAR(32), 21 | CodF VARCHAR(32), 22 | titolo VARCHAR(32), 23 | autore VARCHAR(32), 24 | sommario VARCHAR(32), 25 | PagI INTEGER, 26 | PagF INTEGER, 27 | CONSTRAINT pk_articolo PRIMARY KEY (doi), 28 | CONSTRAINT FK_ARTICOLO_RIVISTA FOREIGN KEY (CodF) REFERENCES r.fascicolo(CodF) 29 | ); 30 | CREATE TABLE r.Profilo 31 | ( 32 | CodProfilo VARCHAR(32), 33 | Tipo VARCHAR(32), 34 | MaxGiorno INTEGER, 35 | MaxMese INTEGER, 36 | CONSTRAINT PK_Profilo PRIMARY KEY (CodProfilo) 37 | ); 38 | CREATE TABLE r.Utente 39 | ( 40 | CF VARCHAR(32), 41 | email VARCHAR(32), 42 | CodProfilo VARCHAR(32), 43 | Nome VARCHAR(32), 44 | Cognome VARCHAR(32), 45 | DataNascita DATE, 46 | CONSTRAINT PK_Utente PRIMARY KEY (CF), 47 | CONSTRAINT FK_Utente_Profilo FOREIGN KEY (CodProfilo) REFERENCES r.Profilo (CodProfilo) 48 | ); 49 | 50 | CREATE TABLE r.accesso( 51 | CF VARCHAR(32), 52 | doi VARCHAR(32), 53 | data DATE, 54 | CONSTRAINT pk_accesso PRIMARY KEY (CF,doi,data), 55 | CONSTRAINT fk_accesso_articolo FOREIGN KEY (doi) REFERENCES r.articolo(doi), 56 | CONSTRAINT fk_accesso_utente FOREIGN KEY (CF) REFERENCES r.utente(CF) 57 | ); 58 | CREATE TABLE r.Descrizione 59 | ( 60 | Parola VARCHAR(32), 61 | Doi VARCHAR(32), 62 | CONSTRAINT FK_Descrizione_Articolodoc FOREIGN KEY (Doi) REFERENCES r.Articolo (Doi) 63 | ); 64 | CREATE TABLE r.ParoleChiave 65 | ( 66 | Parola VARCHAR(32), 67 | ISNN VARCHAR(32), 68 | CONSTRAINT PK_ParoleChiave PRIMARY KEY (Parola, ISNN), 69 | CONSTRAINT FK_ParoleChiave_ FOREIGN KEY (ISNN) REFERENCES r.rivista(ISNN) 70 | ); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_RivisteArticoli/Funzione_1(ES4).sql: -------------------------------------------------------------------------------- 1 | /* 2 | Si scriva una funzione in SQL DINAMICO che riceve iningresso una stringa di parole chiave 3 | separate dal carattere +. La funzione restituisce la stringadi doi degli articoli a cui 4 | sono associate TUTTE le parole chiave nella stringa. 5 | */ 6 | 7 | --QUESTO ESERCIZIO NON È IN SQL DINAMICO PER FARLO IN SQL DINAMICO VEDI ES 6 DI 2022_12_08_HashtagFoto 8 | 9 | CREATE OR REPLACE FUNCTION r.pro(string VARCHAR(500)) RETURNS VARCHAR(500) AS $$ 10 | DECLARE 11 | numParoleSTR INTEGER; 12 | parolaSTR r.descrizione.parola%TYPE; 13 | numDOI INTEGER; 14 | cursDOI CURSOR FOR SELECT doi FROM r.articolo; 15 | currentDOI r.descrizione.doi%TYPE; 16 | match INTEGER; 17 | output VARCHAR(500); 18 | BEGIN 19 | string=replace(string, '+', '@'); 20 | numParoleSTR = regexp_count(string, '@') + 1; 21 | numDOI = (SELECT Count(doi) FROM r.articolo); 22 | OPEN cursDOI; 23 | 24 | FOR i in 1..numDOI LOOP 25 | FETCH cursDOI INTO currentDOI; 26 | match=0; 27 | 28 | FOR j in 1..numParoleSTR LOOP 29 | parolaSTR = split_part(string, '@', j); 30 | 31 | IF EXISTS (SELECT * FROM r.descrizione as d 32 | WHERE d.doi=currentDOI AND d.parola=parolaSTR) THEN 33 | match = match +1; 34 | end if; 35 | IF match = numParoleSTR THEN 36 | output=CONCAT(output, currentDOI); 37 | end if; 38 | end loop; 39 | end loop; 40 | RETURN output; 41 | END; 42 | $$ LANGUAGE plpgsql; 43 | 44 | SELECT r.pro('prova2'); -------------------------------------------------------------------------------- /Esercizi/2022_12_08_RivisteArticoli/Insert.sql: -------------------------------------------------------------------------------- 1 | --RIVISTA 2 | INSERT INTO r.rivista(ISNN) 3 | values ('rivista1'), 4 | ('rivista2'); 5 | 6 | --FASCICOLO 7 | INSERT INTO r.fascicolo(isnn, codf) 8 | values ('rivista1','fascicolo1'), 9 | ('rivista2','fascicolo2'); 10 | 11 | --PAROLECHIAVE 12 | INSERT INTO r.parolechiave(isnn, parola) 13 | values ('rivista1', 'silvio1'), 14 | ('rivista1', 'forzanapoli1'), 15 | ('rivista2', 'barra2'), 16 | ('rivista2', 'prova2'); 17 | 18 | --ARTICOLO 19 | INSERT INTO r.articolo(doi, codf, sommario) 20 | values ('doi1', 'fascicolo1', 'silvio1 barra2 forzanapoli1'), 21 | ('doi2', 'fascicolo2', 'silvio1 barra2 prova2'); 22 | 23 | 24 | -------------------------------------------------------------------------------- /Esercizi/2022_12_08_RivisteArticoli/Trigger_1(ES3).sql: -------------------------------------------------------------------------------- 1 | /* 2 | Si implementi un trigger azionato quando viene inserito 3 | un nuovo articolo. Il trigger cerca la presenza nel sommario dell’articolo delle parole chiave 4 | associate alla rivista dell’articolo. Se viene trovata la presenza di una parola chiave questa 5 | viene memorizzata nella tabella DESCRIZIONE. 6 | */ 7 | 8 | CREATE OR REPLACE FUNCTION r.funz_1() RETURNS TRIGGER AS $$ 9 | DECLARE 10 | word r.parolechiave.parola%TYPE; 11 | cursore CURSOR FOR SELECT parola FROM r.fascicolo NATURAL JOIN r.parolechiave 12 | WHERE r.fascicolo.codf=NEW.codf; 13 | i int:=0; 14 | n int:=(SELECT COUNT(*) FROM r.fascicolo NATURAL JOIN r.parolechiave); 15 | BEGIN 16 | OPEN cursore; 17 | WHILE (iTout); --le richieste sono state fatte alle 2 15 | T1_c_transazioni_risorse CURSOR FOR -- 16 | SELECT codtransazione, ris.codrisorsa 17 | FROM l.richieste ric JOIN l.risorsa ris ON ris.codrisorsa = ric.codrisorsa 18 | WHERE (tattuale-ric.tempo)>Tout AND ris.stato<>'UNLOCK'; --T1 19 | T1_transazione l.richieste.codtransazione%TYPE; 20 | T1_risorsa l.richieste.codrisorsa%TYPE; 21 | 22 | T2_n_transazioni INTEGER:=(SELECT COUNT(*) FROM l.assegnazione); 23 | T2_c_transazioni_risorse CURSOR FOR SELECT codtransazione, codrisorsa FROM l.assegnazione; 24 | T2_transazione l.richieste.codtransazione%TYPE; 25 | T2_risorsa l.richieste.codrisorsa%TYPE; 26 | 27 | --temporegistrazione INTEGER; 28 | --tempo_corrente INTEGER:=5; 29 | --tempoattesa INTEGER:=temporegistrazione-tempo_corrente; 30 | output VARCHAR(500):=''; 31 | BEGIN 32 | OPEN T1_c_transazioni_risorse; --T1 APERTO 33 | for i IN 1..T1_n_transazioni LOOP 34 | RAISE NOTICE 'i(%)', i; 35 | FETCH T1_c_transazioni_risorse INTO T1_transazione, T1_risorsa; 36 | OPEN T2_c_transazioni_risorse; --T2 APERTO 37 | FOR j IN 1..T2_n_transazioni LOOP 38 | RAISE NOTICE 'j(%)', j; 39 | FETCH T2_c_transazioni_risorse INTO T2_transazione, T2_risorsa; 40 | raise notice 'T1:(%), T2:(%)', T1_risorsa, T2_risorsa; 41 | if(T1_risorsa=T2_risorsa) THEN 42 | RAISE NOTICE 'siamo uguali'; 43 | output=output || ' ' || T1_transazione; 44 | end if; 45 | end loop; 46 | 47 | CLOSE T2_c_transazioni_risorse; --T2 CHIUSO 48 | end loop; 49 | CLOSE T1_c_transazioni_risorse; --T1 chiuso 50 | RAISE NOTICE 'output:{%}', output; 51 | end 52 | $$ 53 | LANGUAGE plpgsql; 54 | 55 | CALL l.funzione2(2); --le richieste aspettano per massimo TOUT ore 56 | 57 | -------------------------------------------------------------------------------- /Esercizi/2022_12_13_LogRichieste/LOG_Trigger_1(ES1).sql: -------------------------------------------------------------------------------- 1 | /*Si implementi il seguente trigger. Quando una transazione registra 2 | una operazione di ABORT sul log, tutte le scritture fatte dalla transazione e riportate sul LOG 3 | devono essere annullate in ordine inverso a quelle in cui sono state fatte. Per annullare le 4 | scritture si deve consultare il log e si deve assegnare ad ogni risorsa scritta dalla transizione 5 | il valore ValorePrima riportato nel LOG. Inoltre, le risorse assegnate alla transazione devono 6 | tornare libere: si rimuovono le assegnazioni alla transazione e lo stato della risorsa assume 7 | valore UNLOCK.*/ 8 | DELETE FROM l.log WHERE cod=99; 9 | 10 | CREATE OR REPLACE FUNCTION l.funzione1() RETURNS TRIGGER 11 | AS 12 | $$ 13 | DECLARE 14 | controllo integer:=0; 15 | count INTEGER:=(SELECT COUNT(*) 16 | FROM l.log 17 | WHERE codtransazione=NEW.codtransazione); 18 | operazioniprecedenti CURSOR FOR ( 19 | SELECT codrisorsa 20 | FROM l.log 21 | WHERE codtransazione=NEW.codtransazione 22 | ORDER BY log.timestamp DESC 23 | ); 24 | BEGIN 25 | OPEN operazioniprecedenti; 26 | FOR i IN 1..count LOOP 27 | FETCH operazioniprecedenti INTO controllo; 28 | RAISE NOTICE 'controllo{%}', controllo; 29 | UPDATE l.risorsa SET valore=valoreprima, stato='UNLOCK' FROM l.log WHERE risorsa.codrisorsa=controllo; 30 | END LOOP; 31 | RETURN NEW; 32 | end; 33 | $$ 34 | LANGUAGE plpgsql; 35 | 36 | 37 | CREATE OR REPLACE TRIGGER trigger1 BEFORE INSERT OR UPDATE ON l.log 38 | FOR EACH ROW 39 | WHEN (NEW.operazione='ABORT') 40 | EXECUTE FUNCTION l.funzione1(); 41 | UPDATE l.risorsa SET valore=valoreprima FROM l.log WHERE risorsa.codrisorsa=1; 42 | 43 | INSERT INTO l.log(cod, operazione, codrisorsa, valoreprima, valoredopo, codtransazione, timestamp) 44 | values (99, 'ABORT', 4, NULL, NULL, 51, 8); -------------------------------------------------------------------------------- /Esercizi/2022_12_13_LogRichieste/Traccia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/2022_12_13_LogRichieste/Traccia.pdf -------------------------------------------------------------------------------- /Esercizi/AlberiNodi/Alberi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/AlberiNodi/Alberi.pdf -------------------------------------------------------------------------------- /Esercizi/AlberiNodi/Creazione_E_Trigger.sql: -------------------------------------------------------------------------------- 1 | --MARIO PENNA E SIMONE PARENTE MARTONE 2 | DROP SCHEMA IF EXISTS e CASCADE; 3 | CREATE SCHEMA e; 4 | 5 | CREATE TABLE e.Nodo 6 | ( 7 | CodA INTEGER, --FK 8 | CodN INTEGER, --PK 9 | Label INTEGER, 10 | 11 | CONSTRAINT Nodo_PK PRIMARY KEY (CodN) 12 | ); 13 | 14 | CREATE TABLE e.Albero 15 | ( 16 | CodA INTEGER, 17 | root INTEGER, 18 | 19 | CONSTRAINT Albero_PK PRIMARY KEY (CodA), 20 | CONSTRAINT Nodo_PK FOREIGN KEY (root) REFERENCES e.Nodo (CodN) 21 | ); 22 | 23 | CREATE TABLE e.Arco 24 | ( 25 | CodA INTEGER, --FK 26 | CodArco INTEGER, --PK 27 | Padre INTEGER, --FK 28 | Figlio INTEGER, --FK 29 | 30 | CONSTRAINT Arco_PK PRIMARY KEY (CodArco), 31 | CONSTRAINT Albero_FK FOREIGN KEY (CodA) REFERENCES e.Albero (CodA), 32 | CONSTRAINT Padre_FK FOREIGN KEY (Padre) REFERENCES e.Nodo (CodN), 33 | CONSTRAINT Figlio_FK FOREIGN KEY (Figlio) REFERENCES e.Nodo (CodN) 34 | ); 35 | 36 | ALTER TABLE e.Nodo 37 | ADD CONSTRAINT Albero_FK FOREIGN KEY (CodA) REFERENCES e.Albero (CodA); 38 | 39 | INSERT INTO e.Albero(coda) 40 | (values (1), 41 | (2), 42 | (3)); 43 | 44 | INSERT INTO e.Nodo(codn, coda, label) --nel disegno i numeri dei nodi corrispondono ai label 45 | ( --albero 1 46 | values (11, 1, 1), 47 | (12, 1, 2), 48 | (13, 1, 3), 49 | (14, 1, 4), 50 | (15, 1, 5), 51 | (16, 1, 6), 52 | (17, 1, 7), 53 | --albero 2 54 | (210, 2, 10), 55 | (211, 2, 11), 56 | (212, 2, 12), 57 | (23, 2, 3), 58 | (26, 2, 6), 59 | (27, 2, 7), 60 | (214, 2, 14), 61 | (215, 2, 15), 62 | (216, 2, 16), 63 | --albero 3 64 | (321, 3, 21), 65 | (312, 3, 12), 66 | (315, 3, 15), 67 | (316, 3, 16), 68 | (323, 3, 23), 69 | (327, 3, 27), 70 | (328, 3, 28)); 71 | 72 | UPDATE e.Albero 73 | SET root=11 74 | WHERE CodA = 1; 75 | 76 | UPDATE e.albero 77 | SET root=210 78 | WHERE CodA = 2; 79 | 80 | UPDATE e.albero 81 | SET root=321 82 | WHERE CodA = 3; 83 | 84 | INSERT INTO e.Arco(CodA, codarco, padre, figlio) 85 | ( --ALBERO 1 86 | values (1, 112, 11, 12), 87 | (1, 113, 11, 13), 88 | (1, 124, 12, 14), 89 | (1, 125, 12, 15), 90 | (1, 136, 13, 16), 91 | (1, 137, 13, 17), 92 | --ALBERO 2 93 | (2, 21011, 210, 211), 94 | (2, 21012, 210, 212), 95 | (2, 2113, 211, 23), 96 | (2, 21114, 211, 214), 97 | (2, 21215, 212, 215), 98 | (2, 21216, 212, 216), 99 | (2, 236, 23, 26), 100 | (2, 237, 23, 27), 101 | --ALBERO 3 102 | (3, 32112, 321, 312), 103 | (3, 32123, 321, 323), 104 | (3, 31215, 312, 315), 105 | (3, 31216, 312, 316), 106 | (3, 32327, 323, 327), 107 | (3, 32328, 323, 328)); 108 | 109 | --Scrivere una funzione che prenda in input un albero e un nodo e restituisca la somma dei label dei nodi del cammino dalla radice al nodo. 110 | CREATE OR REPLACE FUNCTION e.somma_nodi(albero e.Albero.CodA%TYPE, nodo_input e.Nodo.CodN%TYPE) 111 | RETURNS INT 112 | AS 113 | $$ 114 | DECLARE 115 | somma_nodi INTEGER := 0; 116 | root_a e.Albero.root%TYPE; 117 | padre e.Arco.padre%TYPE; 118 | cursore e.Arco.figlio%TYPE := nodo_input; 119 | labelv e.Nodo.label%TYPE := 0; --variabile label 120 | BEGIN 121 | SELECT root, N.label --trovo radice dell'albero e relativo label 122 | into root_a, labelv --e lo salvo in due variabili distinte 123 | FROM e.Albero AS A 124 | NATURAL JOIN e.Nodo AS N 125 | WHERE albero = A.coda; 126 | somma_nodi = somma_nodi + labelv; --sommo il label della radice 127 | 128 | WHILE cursore != root_a 129 | LOOP 130 | --salgo di nodo in nodo fino a raggiungere la radice precedentemente trovata 131 | SELECT A.padre INTO padre 132 | FROM e.Nodo AS N 133 | NATURAL JOIN e.Arco AS A 134 | WHERE figlio = cursore; 135 | SELECT N.label INTO labelv 136 | FROM e.Nodo AS N 137 | WHERE cursore = N.codn; 138 | somma_nodi := somma_nodi + labelv; --sommo i label dei nodi 139 | cursore = padre; 140 | END LOOP; 141 | 142 | RETURN somma_nodi; 143 | END 144 | $$ 145 | LANGUAGE plpgsql; 146 | 147 | SELECT e.somma_nodi(2, 23); 148 | 149 | 150 | CREATE or REPLACE FUNCTION e.max_cammino(cod_albero e.albero.codA%TYPE) 151 | RETURNS INT 152 | AS 153 | $$ 154 | DECLARE 155 | foglia e.Nodo.CodN%TYPE; --variabile in cui conserviamo il CodN di una foglia 156 | max INTEGER := 0; --max valore del percorso dalla foglia alla radice 157 | i INTEGER := 0; --indice per loop 158 | n INTEGER := 0; --numero di foglie dell'albero (da usare come max del loop) 159 | cursore CURSOR FOR --cursore che scorre tutti i nodi senza figli(foglie) 160 | (SELECT N.CodN --tutti i nodi 161 | FROM e.Nodo AS N 162 | WHERE coda = cod_albero 163 | EXCEPT --meno 164 | SELECT A.padre --nodi con figli 165 | FROM e.Arco AS A); 166 | 167 | BEGIN 168 | n := (SELECT COUNT(*) --numero di foglie dell'albero 169 | FROM (SELECT N.CodN 170 | FROM e.Nodo AS N 171 | WHERE coda = cod_albero 172 | EXCEPT 173 | SELECT A.padre 174 | FROM e.Arco AS A) AS Q); 175 | 176 | OPEN cursore; 177 | 178 | WHILE i < n 179 | LOOP 180 | FETCH cursore INTO foglia; 181 | IF (max < e.somma_nodi(cod_albero, foglia)) THEN 182 | max = e.somma_nodi(cod_albero, foglia); 183 | END IF; 184 | i := i + 1; 185 | END LOOP; 186 | 187 | CLOSE cursore; 188 | RETURN max; 189 | END; 190 | 191 | $$ 192 | LANGUAGE plpgsql; 193 | 194 | --Dato in input un albero, restituisce la somma massima dei label dei nodi di un cammino dalla radice ad una foglia. 195 | SELECT e.max_cammino(3); -------------------------------------------------------------------------------- /Esercizi/AlberiNodi/Traccia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simoneparente/databases_unina/850e5d034ef08a2900e95e38a34d31c7237381ee/Esercizi/AlberiNodi/Traccia.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 📚 Guida per l'esame di Basi Di Dati 2 | Nota: le prove scritte d'esame sono identiche per tutti i gruppi. 3 | 4 | ## ⌨️ *Descrizione* 5 | Esercizi svolti durante il semestre invernale 2022-2023 per il corso del gruppo 2, guidato dal prof. Silvio Barra. 6 | - Origine degli esercizi: prove intercorso e prove d'esame. 7 | - Linguaggio utilizzato: plpgsql. 8 | 9 | ## 📑 *Appunti* 10 | Appunti del corso di Basi di dati scritti su Notion: [link](https://simoneparente.notion.site/d7306c76270d4f6a9f0a0b3892a02aa3?v=2dfe3774303c43a0868d3b950b19a8d7) 11 | 12 | ## ℹ️ Consigli 13 | 14 | ### Gestione e Creazione DB 15 | 1. Utilizza [DataGrip](https://www.jetbrains.com/datagrip) per gestire il Database, ti salva la vita. 16 | 2. Quando costruisci un nuovo database, inizia con la creazione delle tabelle, prosegui poi con la definizione dei trigger e, infine, popola le tabelle con le INSERT. 17 | 3. Le funzioni puoi aggiungerle alla fine. 18 | 19 | ## ©️ *Creato da* 20 | - 🧑🏻‍💻 [Simone Parente](https://github.com/simoneparente) 21 | - 🧑🏻‍💻 [Mario Penna](https://github.com/bickpenna/) 22 | - 🧑🏻‍💻 [Lorenzo Tecchia](https://github.com/lorenzotecchia) 23 | 24 | ## 🏬 *Info* 25 | - Università degli Studi di Napoli: "Federico II" 26 | - Dipartimento di Ingegneria Elettrica e delle Tecnologie dell'Informazione 27 | - Corso di Laurea in Informatica 28 | 29 | ## TODO 30 | 31 | - [X] Guida alla creazione dei DB 32 | - [X] Eliminare file che non sono eseguibilie e/o corretti 33 | - [ ] Guida per come fare commit su questa repo 34 | - [X] Appunti 35 | --------------------------------------------------------------------------------