2010-08-26 25 views
12

Tengo 2 tablas: comments y comments_likes.Realice una consulta en mysql sin invocar un desencadenador (Cómo deshabilitar un desencadenador)


comentarios

id  
message 
likes 

desencadena:

DESPUÉS DE ELIMINAR

DELETE FROM comments_likes WHERE comment_id = OLD.id; 

comments_likes

id   
comment_id 

desencadena:

después Insertar

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

DESPUÉS DE ELIMINAR

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

después de la actualización

**omited code, updates comments** 

Entonces la pregunta es, puedo desactivar los disparadores cuando se activa desde otro gatillo?

Lo que quiero es hacer algo le gusta a:

DESPUÉS DE ELIMINAR

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

[EDIT]

una solución no sería optimizado (consulta muy lento ... realiza una consulta para cada 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 

ACTUALIZACIÓN LOW PRIORITY y IGNORE no funciona.

[EDIT 2]

Tengo otra idea, es posible establecer una variable global en el primer gatillo y leerlo desde el otro gatillo?

Ex:

primer disparador:

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

otro desencadenante:

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

Respuesta

21

Para desactivar los disparadores que puede hacer:

Disparador 1

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

Disparador 2

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

¡Innecesario! ¿Puedes realmente desactivar los disparadores dentro de un gatillo? – Mchl

+1

@Mchl: Sí, con este método puedes :) @var son globales para la conexión. Debe usar IS NULL porque las variables que no se han definido siempre son NULL. – Wiliam

+1

¡esto me ayudó 4 años después! Estaba buscando exactamente algo como esto. después de 1 hora de googlear y buscar SO, finalmente encontré tu respuesta. es tan fácil, pero nunca lo hubiera averiguado solo. simplemente no estoy acostumbrado a poder "programar" con mysql. –

0

No, no puede. Ese es el punto de los factores desencadenantes: que se ejecute siempre.

Además, no veo por qué lo necesitaría en su caso. En el peor de los casos, nada se actualiza; no se generarán errores.

Siempre puede agregar una condición en su desencadenador, para comprobar si se deben ejecutar (o parte de su código) (por ejemplo, si hay un registro en la tabla correspondiente).

+0

Cuando intenta eliminar un comentario, el desencadenador borra todos los "me gusta". Cuando se eliminan los Me gusta, actualizan el comentario que se ha eliminado. Aparece un mensaje de error: 'No se pueden actualizar los 'comentarios' de la tabla en la función/disparador almacenado porque ya está siendo utilizado por la declaración que invoca esta función/desencadenador almacenado'' – Wiliam

+0

@Wiliam: Bueno, con una condición puedo hacerlo ... pero no es la solución que estaba buscando uu – Wiliam

+0

@Mchl tal vez ese es el punto de los factores desencadenantes, pero en MySQL no siempre se ejecutan. Si se elimina una fila debido a la imposición de restricciones de clave foránea CASCADE, no se ejecutan desencadenantes. Referencia: [Documentación de MySQL] (http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html). Creo firmemente que las raíces de esta limitación de MySQL tienen la misma razón raíz que el error en el comentario de William. –

1

Puede ser un poco feo, pero lo que hago es cambiar el nombre del table to table2 que el disparador no se une también, y luego, al final, renombra nuevamente.

Cuestiones relacionadas