PDA

Visualizza la versione completa : [Oracle] esercizio


Danelius
25-02-2009, 10:46
Ciao ragazzi! ho questo esercizio:
Dato il seguente schema relazionale relativo ai viaggi organizzati di un tour operator:


VIAGGIO (id_viaggio, nome, descrizione, durata, luogo, costo);
ITINERARIO (id_viaggio, id_tappa, nome_tappa, giorno, permanenza, descrizione, localitÃ_);
ALBERGHI (id_viaggio, id_tappa, id_albergo, nome_albergo, stelle, trattamento);
DATEDISPONIBILI (id_viaggio, data_inizio, posti_disponibili_rimasti);
PRENOTAZIONI (id_viaggio, data_inizio, id_cliente, nome, cognome, data_nascita, residenza);


Con riferimento allo schema dato, la tabella DATEDISPONIBILI può essere aggiornata tramite trigger
nel momento in cui una prenotazione viene modificata.
Dare il trigger necessario a tenere aggiornata questa tabella

Non so se così è giusto anche perchè ancora sto cercando di installare oracle


CREATE TRIGGER upd_tr
AFTER UPDATE ON prenotazioni
FOR EACH ROW
BEGIN
SELECT id_viaggio, data_inizio
FROM DATEDISPONIBILI
WHERE id_viaggio = new.id_viaggio
AND data_inizio = new.data_inizio
THEN
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti - 1
WHERE WHERE id_viaggio = new.id_viaggio AND data_inizio = new.data_inizio
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti + 1
WHERE id_viaggio = old.id_viaggio AND data_inizio = old.data_inizio

Qualcuno potrebbe correggerlo perfavore? :bhò:

Joe Taras
25-02-2009, 11:28
Mi pare corretto, manca solo l'end che chiude il begin.

Per essere proprio fini e non far fare update di troppo condizionerei tutto al fatto che old.data_inizio debba essere <> new.data_inizio

Per il resto, ripeto, sembra tutto ok

YuYevon
25-02-2009, 11:52
Penso ti converrebbe anche scrivere

CREATE OR REPLACE TRIGGER upd_tr

anziché semplicemente "CREATE TRIGGER upd_tr". Questo perché, se non sbaglio, nel caso provassi a compilare il trigger e poi volessi ricompilarlo (magari a causa di un errore), non ti sarebbe concesso perché il DBMS avrebbe già un trigger dal nome "upd_tr" e saresti quindi costretto a rinominarlo, creandone (di fatto) un altro e accumulando sporcizia nel DBMS. Scrivendo "OR REPLACE" Oracle andrà a rimpiazzare l'eventuale trigger precedentemente creato e non sarai costretto a rinominarlo.

Danelius
25-02-2009, 12:07
Grazie ragazzi! Quindi dovrebbe essere così?



CREATE TRIGGER OR REPLACE upd_tr
AFTER UPDATE ON prenotazioni
FOR EACH ROW
BEGIN
SELECT id_viaggio, data_inizio
FROM DATEDISPONIBILI
WHERE id_viaggio = new.id_viaggio
AND data_inizio = new.data_inizio
THEN
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti - 1
WHERE WHERE id_viaggio = new.id_viaggio AND data_inizio = new.data_inizio
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti + 1
WHERE id_viaggio = old.id_viaggio AND data_inizio = old.data_inizio
END


ma la condizione "old.data_inizio debba essere <> new.data_inizio", dove dovrei metterla? :master:

YuYevon
25-02-2009, 12:13
Scusa ma ora che rileggo... sbaglio io o quel THEN la in mezzo non significa nulla? Non è una parola riservata che va usata soltanto con IF?

Danelius
25-02-2009, 12:48
Forse hai ragione tu...(purtroppo non ho come provarlo :dhò: uff)

Quindi dovrebbe venire così?


CREATE TRIGGER OR REPLACE upd_tr
AFTER UPDATE ON prenotazioni
FOR EACH ROW
BEGIN
SELECT id_viaggio, data_inizio
FROM DATEDISPONIBILI
WHERE id_viaggio = new.id_viaggio
AND data_inizio = new.data_inizio
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti - 1
WHERE id_viaggio = new.id_viaggio AND data_inizio = new.data_inizio
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti + 1
WHERE id_viaggio = old.id_viaggio AND data_inizio = old.data_inizio
END


e così va pure bene?



CREATE TRIGGER OR REPLACE upd_tr
AFTER UPDATE ON prenotazioni
FOR EACH ROW
BEGIN
IF (id_viaggio = (SELECT id_viaggio
FROM DATEDISPONIBILI
WHERE id_viaggio = new.id_viaggio)
AND data_inizio = (SELECT data_inizio
FROM DATEDISPONIBILI
WHERE data_inizio = new.data_inizio)
)
THEN
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti - 1
WHERE id_viaggio = new.id_viaggio AND data_inizio = new.data_inizio
UPDATE DATEDISPONIBILI
SET posti_disponibili_rimasti = posti_disponibili_rimasti + 1
WHERE id_viaggio = old.id_viaggio AND data_inizio = old.data_inizio
END IF
END


e poi dove devo inserire "old.data_inizio debba essere <> new.data_inizio"?
Scusate per tutte ste domande :incupito:

YuYevon
25-02-2009, 13:10
Aspetta un attimo Danelius facciamo un po' d'ordine.

Innanzitutto quest'ultima condizione che hai scritto

IF (id_viaggio = (SELECT id_viaggio
FROM DATEDISPONIBILI
WHERE id_viaggio = new.id_viaggio)
AND data_inizio = (SELECT data_inizio
FROM DATEDISPONIBILI
WHERE data_inizio = new.data_inizio)
)

penso proprio che non vada bene (a parte il fatto che è mostruosa a vedersi).

Per fare un controllo del genere dovresti procedere come segue:

innanzitutto devi dichiarare delle variabili ricorrendo alla sezione DECLARE previsto dal PL/SQL. In questa sezione (per fare quei controlli che volevi fare) puoi scrivere questo:



DECLARE

var_id_viaggio datedisponibili.id_viaggio%type;
var_data_inizio datedisponibili.data_inizio%type;

BEGIN

...


che in pratica significa "var_id_viaggio è una variabile che ha lo stesso tipo del campo id_viaggio della relazione datedisponibili" (si indica con quella sintassi lì, con %type) e "var_data_inizio è una variabile che ha lo stesso tipo del campo data_inizio della relazione datedisponibili". Ovviamente le variabili le puoi chiamare come vuoi, ora mi sono inventato io questi due nomi.

FATTO QUESTO, puoi riscrivere quelle due query come segue:



SELECT id_viaggio INTO var_id_viaggio FROM DATEDISPONIBILI WHERE id_viaggio = new.id_viaggio;


SELECT data_inizio INTO var_data_inizio FROM DATEDISPONIBILI WHERE data_inizio = new.data_inizio


in questo modo nelle due variabili hai i valori che ti interessano per fare tutti i confronti che vuoi.

Per quanto riguarda la prima versione che avevi fatto del trigger, in sostanza al suo interno, incondizionatamente, prima decrementi i posti disponibili e poi li incrementi di nuovo... e francamente non ho nemmeno capito cosa vuoi fare, sta di fatto che così non ha senso ^^".

Per il resto... sicuro di aver studiato un po' di PL/SQL? E' difficile cimentarsi direttamente nella pratica se non si conosce prima un po' di teoria...

Io ti consiglierei innanzitutto di:

1) installare oracle, potresti ricorrere a Oracle XE 10g che è scaricabile gratuitamente;

2) studiare un po' di PL/SQL da un buon manuale. Non è ho di cartacei da consigliarti, posso solo linkarti questa guida che ho usato io (in italiano):

http://www.fileden.com/files/2008/10/7/2133367/TutorialOracleItaliano.pdf

è spiegato tutto abbastanza chiaramente e con diversi esempi, non dovresti avere particolari problemi... ovviamente non è solo una guida sul PL/SQL, c'è anche dell'altro ma magari ricava solo le cose che ti interessano.

Danelius
25-02-2009, 15:19
Per quanto riguarda la prima versione che avevi fatto del trigger, in sostanza al suo interno, incondizionatamente, prima decrementi i posti disponibili e poi li incrementi di nuovo... e francamente non ho nemmeno capito cosa vuoi fare, sta di fatto che così non ha senso ^^".

Siccome devo fare l'update dei posti_disponibili_rimasti, quindi può capitare di decrementarlo o di incrementarlo, o no? :master: Forse ho interpretato male ciò che chiede l'esercizio...tu come lo faresti?

YuYevon
25-02-2009, 15:49
Il problema è che non ho capito come va aggiornato quel valore. Forse a seconda che sia effettuata o disdetta una prenotazione? Se si prenota si decrementa la disponibilità e se si disdice si incrementa? E se è così, la prenotazione e la rinuncia come avvengono? Rispettivamente con INSERT e DELETE sulla tabella "prenotazioni" ?

Insomma se ho capito: se prenoto un viaggio effettuo una scrittura sulla tabella "prenotazioni" per il viaggio con chiave x e deve essere decrementata la disponibilità per il viaggio x nella tabella "datedisponibili", mentre se disdico una prenotazione effettuo una cancellazione (delete) sulla tabella "prenotazioni" per il viaggio x e la disponibilità per tale viaggio (nella tabella "datedisponibili") deve essere incrementata.

Dico bene? Se non è così, spiega con precisione cosa deve fare il trigger, su cosa deve operare e in seguito a cosa... non posso sapere quali sono le tue intenzioni :)

Danelius
25-02-2009, 16:26
Io ho capito come lo hai inteso tu, per questo ho fatto l'incremento e il decremento dei posti_disponibili_rimasti....però come hai detto tu così il valore viene sia decrementato che incrementato....a sto punto non lo so nemmeno io cosa intende l'esercizio...
Comunque, tante grazie per la disponibilità! :)

Loading