Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

[MYSQL] Errore 1442 su Trigger!

Problemi di HTML? Di PHP, ASP, .NET, JSP, Perl, SQL, JavaScript, Visual Basic..?
Vuoi realizzare programmi in C, C++, Java, Ruby o Smalltalk, e non sai da che parte cominciare?
Entra qui e troverai le risposte!

Moderatori: Triumph Of Steel, archimede

[MYSQL] Errore 1442 su Trigger!

Postdi <BIG> » 29/03/14 20:45

Ciao sto facendo un progetto di basi di dati con altri due ragazzi e abbiamo un grosso problema con l'unica operazione che ci rimane da implementare. Praticamente in un sistema di Forum e Topic vogliamo che dopo 20 commenti l'utente venga promosso automaticamente a Premium (P).
Ovviamente dobbiamo implementarlo con un trigger ma non riusciamo a superare questo errore se qualcuno riuscisse a darci una mano gliene saremmo davvero molto grati! :)

Le tabelle in questione sono:
UTENTE( Nick, Password, Email, DataNascitaU, Indirizzo, TipoUtente, FanSquadra, NumCom);
COMMENTO( ID, NickAutore, DataC, Testo, TitoloTopic);

Con il vincolo di FK: COMMENTO.NickAutore → UTENTE.Nick;

Il nostro trigger:

Codice: Seleziona tutto
DELIMITER |
CREATE TRIGGER Premium
AFTER INSERT ON COMMENTO
FOR EACH ROW
BEGIN
   DECLARE numcommenti INT DEFAULT 0;
   DECLARE cursore CURSOR FOR SELECT NumCom FROM UTENTE WHERE UTENTE.`Nick`=NEW.NickAutore;
   
   OPEN cursore;
        FETCH cursore INTO numcommenti;
        CLOSE cursore;
       
   IF numcommenti>'19' THEN UPDATE UTENTE SET UTENTE.`TipoUtente` = 'P' WHERE UTENTE.`Nick`=NEW.NickAutore;
    END IF;
END;


Infine l'errore:
[ERRORE] Query SQL non riuscita. Errore: SQLSTATE[HY000]: General error: 1442 Can't update table 'utente' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Grazie in anticipo a chi vorrà darci una mano!
<BIG>
Utente Junior
 
Post: 24
Iscritto il: 08/08/11 14:17

Sponsor
 

Postdi archimede » 29/03/14 21:08

Non conosco Mysql, ma se proprio dovessi usare dei trigger io farei così:

- un trigger su Commento che ad ogni insert fa
Codice: Seleziona tutto
UPDATE UTENTE SET NumCom = NumCom + 1 WHERE UTENTE.`Nick`=NEW.NickAutore;

- un BEFORE UPDATE trigger su Utente che, qualora NEW.NumCom sia > 19, mette NEW.`TipoUtente`= 'P'.

HTH.

Alessandro

PS: ovviamente sapete che mettere delle colonne calcolate in un db è in genere considerata una pratica da evitare.
archimede
Moderatore
 
Post: 2753
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi <BIG> » 29/03/14 21:31

Intanto grazie della risposta!
Ho appena provato la tua proposta ma non funziona :cry: :cry: mi da esattamente lo stesso errore perché il problema penso sia nel fatto che c'è il vincolo di chiave esterna tra COMMENTO e UTENTE quindi ad ogni inserimento di un commento anche la tabella UTENTE è in uso.
E non può modificare una tabella da un trigger mentre questa è in uso.

Per quanto riguarda invece l'attributo calcolato, inizialmente pensavamo di recuperare il numero di commenti in un altro modo ma dall'analisi delle ridondanze era risultato essere più conveniente mantenere un attributo come NumCom, se hai qualche soluzione più appropriata ti ascolto.
<BIG>
Utente Junior
 
Post: 24
Iscritto il: 08/08/11 14:17

Postdi archimede » 29/03/14 22:15

Dubito che la FK sia la causa dell'errore. Esattamente quale/i istruzione/i lo causa?
Per quanto riguarda invece l'attributo calcolato, inizialmente pensavamo di recuperare il numero di commenti in un altro modo ma dall'analisi delle ridondanze era risultato essere più conveniente mantenere un attributo come NumCom, se hai qualche soluzione più appropriata ti ascolto.
Non so cosa intendi con analisi delle ridondanze, ma se dovessi determinare il tipo di utente dal numero di posts, io farei una bella view (codice NON testato):
Codice: Seleziona tutto
SELECT t.*,
       CASE t.NumCom
       WHEN < 20 THEN 'N'
       ELSE 'P'
       END TipoUtente
  FROM (SELECT u.*, (SELECT count(*) FROM commento WHERE NickAutore = u.Nick) AS NumCom
          FROM utente AS u) AS T
HTH.

Alessandro
archimede
Moderatore
 
Post: 2753
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi <BIG> » 30/03/14 01:55

Con analisi delle ridondanze intendo il calcolo del costo delle operazioni in termini di velocità e di memoria nel caso si tenga o meno l'attributo NumCom (ridondanza perché calcolabile ad esempio dalla relazione tra utente e commento).
Comunque va beh tornando al problema principale, il trigger viene lanciato in seguito a:
Codice: Seleziona tutto
INSERT INTO COMMENTO (NickAutore,DataC,Testo,TitoloTopic) VALUES ((SELECT Nick FROM UTENTE WHERE Nick='$user'),:lab1,:lab2,:lab3)


Dove :lab1,:lab2,:lab3 sono le label per gli altri attributi.
<BIG>
Utente Junior
 
Post: 24
Iscritto il: 08/08/11 14:17

Postdi archimede » 30/03/14 03:20

A me funziona: http://sqlfiddle.com/#!9/0d44c/1

Mi sa che il problema è dato da quella SELECT nella INSERT, il cui senso peraltro mi sfugge completamente: che bisogno hai di selezionare da una tabella un valore che già conosci?

Alessandro
archimede
Moderatore
 
Post: 2753
Iscritto il: 07/11/02 12:41
Località: Genova

Postdi <BIG> » 30/03/14 11:03

Ho risolto grazie mille!!! :)

Facevamo quella select perché all'inizio ci diceva che inserendo semplicemente la variabile $user come nick si violava un vincolo di fk ma adesso non da nessun problema! Quindi grazie dell'aiuto :)
<BIG>
Utente Junior
 
Post: 24
Iscritto il: 08/08/11 14:17

Postdi archimede » 30/03/14 11:49

Lieto che abbiate risolto.

Presumendo che i commenti possano essere cancellati, ora dovete implementare anche un AFTER DELETE trigger (e modificare il trigger su Utente di conseguenza).

Alessandro
archimede
Moderatore
 
Post: 2753
Iscritto il: 07/11/02 12:41
Località: Genova


Torna a Programmazione


Topic correlati a "[MYSQL] Errore 1442 su Trigger!":

Errore strano
Autore: Mr.Frank
Forum: Software Windows
Risposte: 0

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti