economia news e media viaggi informatica internet salute e benessere int rattenimento e spettacolo sport tempo libero istruzio ne e formazione arte cultura scienza

SQL

Creazione di tabelle. Quarta parte.

A cura di Andrea Silvestri

Pubblicato il 25/03/2001

Continuiamo il discorso sui vincoli, approfondendo i check constraint.

Le condizioni definite in questo vincolo sono soggette ad alcune limitazioni:

  • Non possono fare riferimento a valori di altri record.
  • Non possono richiamare funzioni come la SYSDATE (che restituisce la data di sistema), la USER (restituisce l'utente corrente), UID o USERENV (che restituiscono altre informazioni sull'utente).
  • Non possono fare riferimento alle seguenti pseudocolonne: CURRVAL, NEXTVAL, LEVEL o ROWNUM.
Se si definiscono piu' check su di una colonna si deve fare attenzione che questi non siano in conflitto fra loro, in quanto non viene effettuato alcun controllo dal sistema. Un errore di questo tipo impedirebbe l'inserimento di qualsiasi record.
Vediamo alcuni esempi classici di check constraint:

CHECK (sesso in ('M','F'))
CHECK (eta > 0)
CHECK (stipendio + bonus <=10.000.000)
CHECK (codice like 'CD_____')

Cambiando discorso, pensiamo un attimo ad un quesito: cosa capiterebbe se cercassi di eliminare un record referenziato da una foreign key? Ad esempio, se cercassi di eliminare una sede in cui lavorano alcune persone. Il constraint non permette una cancellazione di questo tipo, al fine di mantenere l'integrita' dei dati. In caso contrario mi troverei in una situazione inconsistente, in cui alcuni impiegati risulterebbero come lavoratori in una sede che non esiste piu'. Ma se volessi a tutti i costi eliminare quel record? Dovrei fare in modo da mantenere la situazione congruente, ad esempio eliminando il constraint, ma questo andrebbe a scapito di tutti i record presenti e di quelli che in futuro verrebbero inseriti. Un'altra soluzione potrebbe essere quella di annullare il campo che punta al record da eliminare (ricordo che una foreign key puo' essere nulla), in questo caso mi ritroverei con impiegati che non so in quale sede stanno lavorando, che comunque e' meglio piuttosto che averli in una sede inesistente. L'ultima soluzione consiste nel cancellare prima tutti i record che puntano a quello da eliminare e successivamente cancellare quest'ultimo. In questo caso non avrei errori perche' il record da eliminare non e' piu' referenziato da altri record. E' possibile intervenire in fase di definizione del constraint in modo che questa cancellazione avvenga in maniera automatica, aggiungendo la clausola ON DELETE CASCADE. Esempio:

CREATE TABLE impiegati(
.........
sedeNUMBER CONSTRAINT FK_IMP_SEDI REFERENCES sedi(sede) ON DELETE CASCADE
...........


In questo modo eliminando una sede verrebbero eliminati tutti i dipendenti associati a quella sede, senza che l'utente sia avvisato. In questo caso sarebbe meglio avvisare chi sta cancellando, che esistono ancora dipendenti in modo che possa prima spostare questi su di un'altra sede.
Se ad esempio avessimo una tabella dei telefoni, in cui sono memorizzati tutti i numeri di telefono di una persona, quindi con una foreign key che punta alla persona, allora in questo caso in fase di cancellazione di una persona sarebbe sensato che automaticamente venissero cancellati i sui telefoni. Altro esempio, il caso ordini e dettaglio ordini, se annullo un ordine ho piacere che spariscano tutti i dettagli ad esso associati.
In conclusione, esistono casi in cui puo' essere utile utilizzare questa clausola e altri in cui e' assolutamente sconsigliato utilizzarla.

Vuoi essere aggiornato sulle novità della guida?

Feed RSS XML vostro feed RSS