MySQL Fire Trigger para Insertar y Actualizar

111

¿Es posible disparar un disparador mysql para los eventos de inserción y actualización de una tabla?

Sé que puedo hacer lo siguiente

CREATE TRIGGER my_trigger
    AFTER INSERT ON `table`
    FOR EACH ROW
BEGIN
.....
END //

CREATE TRIGGER my_trigger
    AFTER UPDATE ON `table`
    FOR EACH ROW
BEGIN
.....
END //

Pero como puedo hacer

CREATE TRIGGER my_trigger
    AFTER INSERT ON `table` AND
    AFTER UPDATE ON `table`
    FOR EACH ROW
BEGIN
.....

¿Es posible o tengo que utilizar 2 activadores? El código es el mismo para ambos y no quiero repetirlo.

Adam S-Price
fuente

Respuestas:

126

Tiene que crear dos disparadores, pero puede mover el código común a un procedimiento y hacer que ambos llamen al procedimiento.

derobert
fuente
3
¿Podría dar un ejemplo de juguete de esto para aquellos de nosotros que no estamos familiarizados con la sintaxis?
Zxaos
3
@Zxaos: Sugeriría comenzar con dev.mysql.com/doc/refman/5.1/en/create-procedure.html (que incluye algunos ejemplos) y hacer sus propias preguntas si es necesario.
derobert
2
Es una pena que no podamos usar operadores AND / OR como en Oracle, más aún cuando tampoco podemos pasar por parámetro a un procedimiento todas las variables OLD y NEW. Mi código será> 2x
Mikel
Este es útil para un desarrollador que nunca se compromete a escribir un código dos veces ..
Sayka
1
@luismartingil, es probable que haya una sobrecarga adicional de llamar a un procedimiento en lugar de incluirlo. Pero a cambio, obtiene un mantenimiento más fácil y la garantía de que el código de los dos activadores no divergerá accidentalmente.
derobert
46

En respuesta a la solicitud de @Zxaos, dado que no podemos tener operadores Y / O para los disparadores de MySQL, comenzando con su código, a continuación se muestra un ejemplo completo para lograr lo mismo.

1. Defina el disparador INSERT:

DELIMITER //
DROP TRIGGER IF EXISTS my_insert_trigger//
CREATE DEFINER=root@localhost TRIGGER my_insert_trigger
    AFTER INSERT ON `table`
    FOR EACH ROW

BEGIN
    -- Call the common procedure ran if there is an INSERT or UPDATE on `table`
    -- NEW.id is an example parameter passed to the procedure but is not required
    -- if you do not need to pass anything to your procedure.
    CALL procedure_to_run_processes_due_to_changes_on_table(NEW.id);
END//
DELIMITER ;

2. Defina el activador UPDATE

DELIMITER //
DROP TRIGGER IF EXISTS my_update_trigger//

CREATE DEFINER=root@localhost TRIGGER my_update_trigger
    AFTER UPDATE ON `table`
    FOR EACH ROW
BEGIN
    -- Call the common procedure ran if there is an INSERT or UPDATE on `table`
    CALL procedure_to_run_processes_due_to_changes_on_table(NEW.id);
END//
DELIMITER ;

3. Defina el PROCEDIMIENTO común utilizado por estos dos disparadores:

DELIMITER //
DROP PROCEDURE IF EXISTS procedure_to_run_processes_due_to_changes_on_table//

CREATE DEFINER=root@localhost PROCEDURE procedure_to_run_processes_due_to_changes_on_table(IN table_row_id VARCHAR(255))
READS SQL DATA
BEGIN

    -- Write your MySQL code to perform when a `table` row is inserted or updated here

END//
DELIMITER ;

Observa que me ocupo de restaurar el delimitador cuando termine con mi negocio de definir los desencadenantes y el procedimiento.

Al Zziwa
fuente
1
¿Qué hay IN table_row_id VARCHAR(255)en este caso? Quiero decir, ¿cómo está definiendo qué fila se insertará o actualizará?
VaTo
13

desafortunadamente no podemos usar en MySQL después de INSERT o UPDATE descripción, como en Oracle

Jeff_Alieffson
fuente