MySQL Fire Trigger para inserir e atualizar

111

É possível disparar um gatilho mysql para os eventos de inserção e atualização de uma tabela?

Eu sei que posso fazer o seguinte

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 //

Mas como posso fazer

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

É possível ou tenho que usar 2 gatilhos? O código é o mesmo para ambos e não quero repeti-lo.

Adam S-Price
fonte

Respostas:

126

Você precisa criar dois gatilhos, mas pode mover o código comum para um procedimento e fazer com que ambos chamem o procedimento.

Derobert
fonte
3
Você poderia dar um exemplo de brinquedo para aqueles de nós que não estão familiarizados com a sintaxe?
Zxaos 01 de
3
@Zxaos: Eu sugiro começar com dev.mysql.com/doc/refman/5.1/en/create-procedure.html (que inclui alguns exemplos) e fazer suas próprias perguntas, se necessário.
derobert 01 de
2
É uma pena que não possamos usar operadores AND / OR como no Oracle, ainda mais quando também não podemos passar por parâmetro para uma procedure todas as variáveis ​​OLD e NEW. Meu código será> 2x
Mikel
Este é útil para um desenvolvedor que nunca se compromete a escrever um código duas vezes.
Sayka
1
@luismartingil, provavelmente há alguma sobrecarga extra de chamar um procedimento em vez de embuti-lo. Mas, em troca, você obtém uma manutenção mais fácil e a garantia de que o código dos dois gatilhos não diverge acidentalmente.
derobert
46

Em resposta à solicitação @Zxaos, uma vez que não podemos ter operadores AND / OR para gatilhos MySQL, começando com seu código, abaixo está um exemplo completo para conseguir o mesmo.

1. Defina o gatilho 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 o gatilho 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 o PROCEDIMENTO comum usado por ambos os gatilhos:

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 ;

Você observa que eu tenho o cuidado de restaurar o delimitador quando concluo meu negócio de definir os gatilhos e o procedimento.

Al Zziwa
fonte
1
O que há IN table_row_id VARCHAR(255)neste caso? Quero dizer, como você está definindo qual linha será inserida ou atualizada?
VaTo
13

infelizmente não podemos usar no MySQL após a descrição de INSERT ou UPDATE , como no Oracle

Jeff_Alieffson
fonte