/*------------------------------------------------------- Nomi impiegati responsabili di almeno un altro impiegato */ CREATE OR REPLACE VIEW Responsabili AS SELECT C.Nome, C.Cognome, C.Matricola FROM Impiegato C WHERE EXISTS (SELECT * FROM Dipartimento D WHERE C.Matricola = D.Impiegato ); /*-------- COME FUNZIONA? */ SELECT C.Matricola FROM Impiegato C; SELECT D.Impiegato FROM Dipartimento D; SELECT * -- NON utile FROM Dipartimento D WHERE '101' = D.Impiegato; SELECT * -- NON utile FROM Dipartimento D WHERE '103' = D.Impiegato; REM ............. SELECT * -- UTILE FROM Dipartimento D WHERE '210' = D.Impiegato; REM ............. REM si ottiene lo stesso risultato prodotto da: SELECT * FROM Responsabili; -- interrogazione usuale su una vista /* RISULTATO: NOME |COGNOME |MATRIC --------------------|--------------------|------ Marco |Celli |210 Siro |Bisi |231 Sergio |Rossi |301 Mario |Rossi |375 Silvia |Zanzi |010 Anna |Pilatone |020 Antonio |Prevignano |030 Statistics ---------------------------------------------------------- 7 recursive calls 32 db block gets 35 consistent gets 0 physical reads 0 redo size 847 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 7 rows processed ----------------------------------------------------------*/ /*------------------------------------------------ Nomi degli impiegati non responsabili */ SELECT S.Nome, S.Cognome, S.Matricola FROM Impiegato S WHERE NOT EXISTS (SELECT * FROM Dipartimento D WHERE S.Matricola = D.Impiegato ) ORDER BY S.Nome; -- L'ordinamento serve per dopo /*-------- COME FUNZIONA? */ SELECT S.Matricola FROM Impiegato S; SELECT D.Impiegato FROM Dipartimento D; SELECT * -- UTILE FROM Dipartimento D WHERE '101' = D.Impiegato; SELECT * -- UTILE FROM Dipartimento D WHERE '103' = D.Impiegato; REM ............. SELECT * -- NON utile FROM Dipartimento D WHERE '210' = D.Impiegato; REM ............. /* .. che e` il RISULTATO della query iniziale: NOME |COGNOME |MATRIC --------------------|--------------------|------ Carla |Vercellotti |032 Carmelina |Savatteri |031 Fulvia |Donetti |021 Fulvio |Marini |022 Luigi |Neri |104 Mario |Rossi |101 Mario |Bianchi |103 Massimo |Rosciano |033 Nico |Bini |105 Nico |Bini |252 Statistics ---------------------------------------------------------- 0 recursive calls 32 db block gets 32 consistent gets 0 physical reads 0 redo size 1021 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 10 rows processed ----------------------------------------------------------*/ /*------------------------------------------------ VERSIONE ALTERNATIVA della query precedente. */ SELECT T.Nome, T.Cognome, T.Matricola FROM Impiegato T MINUS SELECT * FROM Responsabili; -- USO DELLA VISTA! /* RISULTATO: NOME |COGNOME |MATRIC --------------------|--------------------|------ Carla |Vercellotti |032 Carmelina |Savatteri |031 Fulvia |Donetti |021 Fulvio |Marini |022 Luigi |Neri |104 Mario |Rossi |101 Mario |Bianchi |103 Massimo |Rosciano |033 Nico |Bini |105 Nico |Bini |252 Statistics ---------------------------------------------------------- 7 recursive calls 8 db block gets 72 consistent gets 0 physical reads 0 redo size 1021 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 2 sorts (memory) 0 sorts (disk) 10 rows processed ----------------------------------------------------------*/ DROP VIEW Responsabili; /*------------------------------------------------ Nome e cognome degli impiegati non assegnati ad alcun progetto */ SELECT I.Nome, I.Cognome FROM Impiegato I WHERE I.Matricola != ALL (SELECT P.Impiegato FROM Partecipazione P); /* RISULTATO: Per controllarlo: SELECT Nome, Cognome, Matricola FROM Impiegato; SELECT DISTINCT Impiegato FROM Partecipazione; NOME COGNOME -------------------- -------------------- Nico Bini Sergio Rossi Mario Rossi Silvia Zanzi Massimo Rosciano Statistics ---------------------------------------------------------- 0 recursive calls 72 db block gets 19 consistent gets 0 physical reads 0 redo size 630 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 5 rows processed ----------------------------------------------------------*/ /*------------------------------------------------ ALTERNATIVA SBAGLIATA a Nome e cognome degli impiegati non assegnati ad alcun progetto */ SELECT I.Nome, I.Cognome FROM Impiegato I WHERE I.Matricola != (SELECT P.Impiegato FROM Partecipazione P); /* Oracle segnala errore perche` I.Matricola e` un singolo valore, mentre il risultato della query annidata e` un insieme di valori. Ci sono interpreti in cui questo type checking implicito non esiste: il risultato prodotto e` errato. Produce un sovrainsieme del risultato corretto? */ /*------------------------------------------------ Nome e cognome dei responsabili tali per cui ogni subalterno diretto guadagni almeno 40 milioni */ SELECT C.Nome, C.Cognome FROM Impiegato C WHERE EXISTS (SELECT * FROM Dipartimento D WHERE D.Impiegato = C.Matricola) AND NOT EXISTS (SELECT * FROM Impiegato S, Dipartimento D WHERE S.DipNome = D.Nome AND S.DipSede = D.Sede AND C.Matricola = D.Impiegato AND S.Stipendio < 40 ); /* RISULTATO: NOME COGNOME -------------------- -------------------- Siro Bisi Sergio Rossi Silvia Zanzi Statistics ---------------------------------------------------------- 0 recursive calls 32 db block gets 40 consistent gets 0 physical reads 0 redo size 531 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed ----------------------------------------------------------*/ /*------------------------------------------------ VERSIONE ALTERNATIVA */ SELECT C.Nome, C.Cognome FROM Impiegato C WHERE (C.Matricola = ANY (SELECT D.Impiegato FROM Dipartimento D) ) AND (C.Matricola !=ALL (SELECT D.Impiegato FROM Dipartimento D, Impiegato S WHERE S.DipNome = D.Nome AND S.DipSede = D.Sede AND S.Stipendio < 40 ) ); /* RISULTATO: Statistics ---------------------------------------------------------- 0 recursive calls 32 db block gets 110 consistent gets 0 physical reads 0 redo size 531 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed ----------------------------------------------------------*/ /*------------------------------------------------ VERSIONE ALTERNATIVA */ SELECT C.Nome, C.Cognome FROM Impiegato C WHERE EXISTS (SELECT * FROM Dipartimento D WHERE C.Matricola = D.Impiegato) AND C.Matricola NOT IN (SELECT D.Impiegato FROM Dipartimento D, Impiegato S WHERE D.Nome = S.DipNome AND D.Sede = S.DipSede AND S.Stipendio < 40 ); /* RISULTATO: Statistics ---------------------------------------------------------- 0 recursive calls 32 db block gets 110 consistent gets 0 physical reads 0 redo size 531 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed ----------------------------------------------------------*/