• User Newbie

    trigger mysql

    Mi fate un esempio di un trigger che impedisca l'insermento di una riga che non rispetta certi vincoli?

    Il mio scopo è sostituire un check perchè in MySQL non vengono accettati

    il mio check sarebbe del tipo

    CONSTRAINT chk_stato CHECK (STATO IN (1, 2, 3));

    se aggiungo un trigger del tipo:

    CREATE TRIGGER TR_chk_statoPartita
    AFTER INSERT
    ON Partita
    FOR EACH ROW
    DELETE FROM partita
    where stato <= 0 AND stato >= 2;

    me lo accetta ma non mi fa inserire nulla nella tabella Partita e quando provo ad inserire qualcosa mi dice:

    ERROR 1442 (HY000): Can't update table 'partita' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

    Dove sbaglio???


  • User Attivo

    C'è spiegato tutto nell'errore che esce: non puoi effettuare nel trigger delle operazioni sulla stessa tabella che invoca il trigger.
    Non ti conviene effettuare il controllo tramite PHP prima di effettuare la query di inserimento? Altrimenti potresti utilizzare un campo di tipo ENUM per stato così che avrà solo dei valori possibili predefiniti.


  • User Newbie

    Volevo mettere dei controlli interni al db... Cmq ho risolto come fare

    creo un trigger che quando un dato viola un vincolo, imposto un altro dato di default non null a NULL in modo tale che mysql tira fuori un'eccezione e non fa l'inserimento!

    delimiter //

    CREATE TRIGGER TR_chk_statoPartita_INSERT
    BEFORE INSERT ON Partita
    FOR EACH ROW
    IF NEW.stato>2
    OR NEW.stato < 0
    THEN set NEW.stato = NULL;
    END IF ; //

    dove "stato" è NON NULL

    Grazie cmq per la tua risposta 🙂


  • User Newbie

    Purtroppo la mia soluzione non risolve tutti i casi 😞

    Adesso ho bisogno di un trigger che mi cancelli alcune righe da una tabella dal momento che inserisco un certo valore

    del tipo:

    CREATE TRIGGER myTrigger
    AFTER INSERT ON T1
    FOREACH ROW
    IF NEW.b = 1;
    DELETE FROM T1
    WHERE a= NEW.a
    and b = 0;

    Ma dal momento in cui provo a fare un inserimento in quella tabella MySQL tira fuori lo stesso erroraccio... Non c'è proprio alcun modo per fare un controllo del genere da MySQL? Devo operare per forza da PHP? Grazie per il vostro aiuto!


  • User Attivo

    Dovresti provare a utilizzare le Stored Function o Procedure: dev.mysql.com/doc/refman/5.1/en/stored-routines.html


  • User Newbie

    Cioè tu mi consigli di fare un procedura che che si occupi di cancellare i dati nella mia tabella e di chiamarla nel mio trigger?
    Non capisco cosa cambia... C'è solo un passaggio in più ma il problema di fondo è lo stesso, vado sempre ad effettuare operazioni sulla stessa tabella che invoca il trigger... Non credi?


  • User Attivo

    Invece di fare la query di inserimento potresti eseguire una procedura che fa l'inserimento e poi cancella le righe che deve cancellare.
    Non so se è possibile eseguire una procedura attraverso un trigger, ma non se fosse possibile non penso che dia lo stesso errore.


  • User Newbie

    E quindi se ho capito bene, quando dovrei fare un inserimento chiamerei direttamente la procedura invece che effettuare l'INSERT direttamente?
    E' una soluzione, però questo non mi garantirebbe l'integrità del mio db... E da quel punto di vista sarebbe la stessa cosa che occuparsene da PHP.

    Oppure intendi dire che devo chiamare la procedura nel trigger azionato BEFORE INSERT (visto che si può fare 🙂 ) e che questo ovvierebbe il problema? (Anche se non capisco perchè 🙂 )

    Grazie cmq per le tue risposte... 🙂


  • User Attivo

    Sì, fai eseguire la procedura invece che l'INSERT. L'integrità viene mantenuta perché è come fare il TRIGGER con l'eliminazione con il vantaggio che funziona e che dovrebbe essere più veloce.


  • User Newbie

    Il fatto è che se venisse fatta una insert su qulla tabella nessuno controllerà la correttezza dei dati... Però vabbè, se questa è l'unica soluzione adotterò questa anche se l'integrità dei dati non è garantita al 100%... :ciauz: :wink3: