2010-08-26 5 views
12

Ho due tabelle: comments e comments_likes.Creare una query in mysql senza richiamare un trigger (Come disabilitare un trigger)


commenti

id  
message 
likes 

trigger di:

DOPO DELETE

DELETE FROM comments_likes WHERE comment_id = OLD.id; 

comments_likes

id   
comment_id 

trigger di:

dopo l'inserimento che

UPDATE comments SET likes = likes + 1 WHERE comments.id = NEW.comment_id; 

DOPO DELETE

UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id; 

dopo l'aggiornamento

**omited code, updates comments** 

Quindi la domanda è, posso disabilitare i trigger quando li attivazione da un altro trigger?

Quello che voglio è fare qualcosa piace questo:

DOPO DELETE

IF NOT called_from_another_trigger() THEN 
    UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id; 
END IF; 

[EDIT]

una soluzione non ottimale sarebbe (query molto lenta ... fa una query per ogni registro LIKE):

BEGIN 
    IF (SELECT id FROM comments WHERE comments.id = OLD.comment_id) THEN 
     UPDATE comments SET comments.cache_likes = comments.cache_likes - 1 WHERE comments.id = OLD.comment_id; 
    END IF; 
END 

UPDATE LOW PRIORITY e IGNORE non funzionano.

[EDIT 2]

Ho un'altra idea, è possibile impostare una variabile globale nel primo trigger e leggerlo dall'altro grilletto?

Es:

primo trigger:

@disable_triggers = true; 
// do the stuff that calls another triggers 
@disable_triggers = false; 

altro trigger:

if @disable_triggers = false then 
    // do the stuff 
end if; 

risposta

21

Per disabilitare trigger si può fare:

trigger 1

SET @disable_trigger = 1; 
// do stuff that calls trigger 2 
SET @disable_trigger = NULL; 

trigger 2

IF @disable_trigger IS NULL THEN 
    // do stuff only if called from a query and not from trigger 1 
END IF; 
+0

Inerestante! Puoi disabilitare i trigger all'interno di un trigger? – Mchl

+1

@Mchl: Sì, con questo metodo è possibile :) @var sono globali per la connessione. È necessario utilizzare IS NULL perché le variabili che non sono state definite sono sempre NULL. – Wiliam

+1

questo mi ha aiutato 4 anni dopo! Ero esattamente alla ricerca di qualcosa di simile. dopo 1 ora di googling e ricerca SO, ho finalmente trovato la tua risposta. è così facile, ma non l'avrei mai capito da solo. non sono abituato a "programmare" con mysql. –

0

No non si può. Questo è il punto di innesco: essere gestito sempre.

Inoltre, non riesco a capire perché ne avresti bisogno nel tuo caso. Nel peggiore dei casi non viene aggiornato nulla, nessun errore verrà sollevato.

È sempre possibile aggiungere una condizione nel trigger, per controllare se devono essere eseguiti (o parte del loro codice) (ad esempio se c'è un record nella tabella pertinente).

+0

Quando si tenta di eliminare un commento, il trigger cancella tutti i Mi piace. Quando i Mi piace vengono cancellati, aggiornano il commento che è stato cancellato. Viene visualizzato un messaggio di errore: 'Impossibile aggiornare i 'commenti' della tabella nella funzione/trigger memorizzati poiché è già utilizzato dall'istruzione che ha richiamato questa funzione/trigger memorizzato' – Wiliam

+0

@Wiliam: Beh, con una condizione posso farlo ... ma non è la soluzione che stavo cercando uu – Wiliam

+0

@Mchl forse è il punto dei trigger, ma in MySQL non vengono sempre eseguiti. Se una riga viene rimossa a causa dell'impostazione del vincolo di chiave esterna CASCADE, non viene eseguito alcun trigger. Riferimento: [documentazione MySQL] (http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html). Credo fermamente che le radici di questa limitazione di MySQL abbiano lo stesso motivo alla radice dell'errore nel commento di William. –

1

Può essere un po 'brutto, ma quello che faccio è rinominare il tabella a tabella2 a cui il trigger non si collega, quindi, alla fine, rinominare.