[Linuxtrent] Re: Postgres e constraint

  • From: Paolo Armani <armani7@xxxxxxxxxxx>
  • To: linuxtrent@xxxxxxxxxxxxx
  • Date: Mon, 10 Nov 2003 15:00:40 +0100

On Monday 10 November 2003 11:44, you wrote:
> Ciao a tutti,
>
> qualcuno usa Postgres sa darmi un esempio di come si crea un trigger
> per il controllo di integrità di una tabella?
>
> Devo portare sotto PG un db Firebird, dove ho una tabella,
> AssenzeDipendenti, fatta grosso modo così::
>
>   CREATE TABLE AssenzeDipendenti
>   (
>     IDDipendente INTEGER PRIMARY KEY,
>     DataInizioAssenza Date,
>     DataFineAssenza Date
>     ...
>   )
>
> sulla quale è attivo questo constraint::
>
>   ALTER TABLE AssenzeDipendenti
>     ADD CONSTRAINT chk_ad_assenze_sovrapposte
>         CHECK (NOT EXISTS (SELECT iddipendente
>                            FROM AssenzeDipendenti ad
>                            WHERE ad.IDDipendente = NEW.iddipendente
>                                  AND ad.DataInizioAssenza <=
> NEW.DataInizioAssenza AND ad.DataFineAssenza >= NEW.DataInizioAssenza));
>
> Ora, scoperto che con PG non posso usare delle subselect nel CHECK, ho
> cercato di capire come farlo coi trigger; ho creato questa funzione::
>
>   create function chk_ad_assenze_sovrapposte (integer_t, timestamp_t)

Si dichaira cosi??
Non era create function chk_ad_assenze_sovrapposte (integer, timestamp)

>   returns trigger as '
>   begin
>     if (exists (select iddipendente
>                 from AssenzeDipendenti ad
>                 where ad.IDDipendente = $1
>                   and ad.DataInizioAssenza <= $2
>                   and ad.DataFineAssenza >= $2
>       raise exception ''Assenze sovrapposte'';
>     end if;

Nota che il trigger nel caso in cui vada tutto bene(cioe' quando non viene 
eseguito un raise exception) 
deve ritornare sempre il dichiarato trigger:
 return NEW;

Se il trigger viene dichiarato con la clausola before, questo comporta la 
possibilita'  da parte del trigger di 
modificare i valori prima dell'inserimento, negli altri casi non mi ricordo se 
e' superfluo o noi dichiararlo
(per es. nel trigger di un delete, o comunque eseguito ad inserimento avvenuto)

>   end;
>   ' language plpgsql;
>

> Ma il codice seguente genera un errore per il fatto che "la funzione
> xxx non esiste"::

Spesso succede per problemi di cast, se non funziona con le altre modifiche 
prova a forzarlo 
(se non ricordo male cmq dovresti accorgerti perche' nell'errore ti mette anche 
i tipi che si aspetta)

>   create trigger trg_ad_assenze_sovrapposte
>     before insert or update
>     on AssenzeDipendenti
>     for each row
>       execute procedure chk_ad_assenze_sovrapposte (IDDipendente,
> DataInizioAssenza);

Se non ricordo male nella funzione creata puoi accedere ai campi della tabella 
con NEW.nome_colonna 
e OLD.nome_colonna (quando esistono...) ed eventualmente modificarlo e poi 
ritornarlo modificato, 
se il trigger e' stato creato con la clausola before. Quindi o non passi nessun 
parametro
(e quindi anche la funzione quando la crei, non ne dichiara) o li passi cosi' 
(se sempre ricordo bene...):

 execute procedure chk_ad_assenze_sovrapposte (NEW.IDDipendente, 
NEW.DataInizioAssenza);

>
> anche se posso vedere la funzione nel database!
>
> Qualche illuminante suggerimento?
Non so se.....  
se ci fosse qualcosaltro....

> ciao, grazie!

Paolo


--
Per iscriversi  (o disiscriversi), basta spedire un  messaggio con OGGETTO
"subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxx


Other related posts: