View Full Version : [PL/SQL]Trigger nn funzionante
antony85
24-02-2009, 14:10
salve,utilizzo il seguente trigger in modo ke controlli che i valori inseriti nella tabella zb.nome non siano gli stessi presenti in za.nome...il trigger viene compilato,ma al momento dell'esecuzione,oracle presenta l'errore
"superato numero massimo di livelli sql ricorsivi(50)"
come posso risolvere??
CREATE OR REPLACE TRIGGER tr4
BEFORE INSERT ON zb
FOR EACH ROW
DECLARE
CURSOR c1 IS (SELECT nome FROM za);
varc1 c1%rowtype;
app EXCEPTION;
flag boolean:=FALSE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO varc1;
EXIT WHEN c1%NOTFOUND;
IF :NEW.nome = varc1.nome THEN
RAISE app;
END IF;
END LOOP;
IF flag= FALSE then
INSERT INTO zb(nome,prezzo_singolo)VALUES(:NEW.nome,:NEW.prezzo_singolo);
COMMIT;
END IF;
EXCEPTION
WHEN app THEN
Raise_Application_Error(-20002,'Errore parola gia presente in za');
END;
Non si capisce se devi farlo come esercizio o se ti serve veramente...
Comunque, in qualsiasi caso
dentro un trigger BEFORE INSERT on zb(o AFTER INSERT) non bisogna scrivere di nuovo uno statement di
INSERT INTO zb, altrimenti il motore entra in ricorsione e viene fuori quell'errore.
COMMIT dentro un trigger manco a parlarne (ma tanto se togli la insert di cui prima magari non ti viene neppure voglia di fare la commit...)
Se sai come funzionano le transazioni capisci anche quanti danni puo' fare un COMMIT nascosto dentro un Trigger.
Avere risolto con un cursore tale trigger significa peggiorare di tanto qualcosa che si puo' fare con un semplice SELECT di controllo di esistenza di quanto stai testando.
A mio avviso una soluzione migliore sarebbe un TRIGGER INSTEAD OF, nel quale potresti fare una INSERT... WHERE NOT EXISTS, controllare se sei riuscito ad inserire altrimenti sollevi l'eccezione.
Nessun cursore, 4/5 righe di codice
Si davvero, io me ne sono stato zitto per non sembrare un cagacazzo ma... perchè un trigger per queste cose?!?
antony85
25-02-2009, 00:44
chiaramente è giusto x uno scopo didattico...x cercare di esercitarsi qnt piu possibile su problemi autoinventati..
antony85
25-02-2009, 13:51
scusami ma a livello di sintassi come devo scrivere "where not exist"?
scusami ma a livello di sintassi come devo scrivere "where not exist"?
Qualcosa tipo
INSERT INTO zb (nome, prezzo_singolo)
SELECT :NEW.nome,:NEW.prezzo_singolo
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM za WHERE za.nome=:NEW.nome)
Dopo questa istruzione puoi valutare quante righe sono state inserite, ovvero 0 oppure 1 (la dual ha una sola riga, quindi al massimo sara' inserita 1 riga, proprio quella che vuoi tu).
E prendere di conseguenza la decisione se sollevare l'eccezione oppure no.
antony85
25-02-2009, 15:20
grazie mille gugo:D
antony85
25-02-2009, 16:28
ok,ho risolto il problema di prima(semplicemente mi è bastato togliere la insert nel trigger(ke generava il problema ricorsivo)).
Ora ho un altro problema,il quale gestisce le date:
in pratica come input ho una data completa(20-gen-85) e voglio effettuare dei controlli sopra,ovvero ke se la data è compresa in un periodo(ovvero dal 1 gennaio al 31 marzo) fai questo,altrimenti se compresa in un altro periodo(1 aprile 31 giugno)fai quest'altro.il problema è ke la data incorpora anche il campo anno,ke a me da problemi nei confronti coi periodi(i quali sono senza anno),quindi magari avrei bisogno di caratteri "jolly" per poter fare il confronto...cm si fa?
antony85
26-02-2009, 12:42
up:(
Prova a studiare la funzione TO_CHAR(di una data), e con quella potrai poi giocare con la BETWEEN per i periodi.
Comunque non so se hai capito che la soluzione con il cursore non e' soddisfacente.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.