MySQL Fire Trigger sia per l'inserimento che per l'aggiornamento


111

È possibile attivare un trigger mysql sia per gli eventi di inserimento che di aggiornamento di una tabella?

So di poter fare quanto segue

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

Ma come posso fare

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

È possibile o devo usare 2 trigger? Il codice è lo stesso per entrambi e non voglio ripeterlo.

Risposte:


126

È necessario creare due trigger, ma è possibile spostare il codice comune in una procedura e fare in modo che entrambi chiamino la procedura.


3
Potresti fornire un esempio giocattolo di questo per quelli di noi che non hanno familiarità con la sintassi?
Zxaos

3
@Zxaos: suggerirei di iniziare con dev.mysql.com/doc/refman/5.1/en/create-procedure.html (che include alcuni esempi) e di porre le tue domande se necessario.
derobert

2
È un peccato non poter utilizzare gli operatori AND / OR come in Oracle, ancor di più quando non possiamo nemmeno passare per parametro a una procedura le intere variabili OLD e NEW. Il mio codice sarà> 2x
Mikel

Questo è utile per uno sviluppatore che non
scende

1
@luismartingil, probabilmente c'è qualche sovraccarico extra nel chiamare una procedura piuttosto che nell'inlining. Ma in cambio si ottiene una manutenzione più semplice e la garanzia che il codice dei due trigger non divergerà accidentalmente.
derobert

46

In risposta alla richiesta @Zxaos, poiché non possiamo avere operatori AND / OR per i trigger MySQL, a partire dal tuo codice, di seguito è riportato un esempio completo per ottenere lo stesso risultato.

1. Definisci il trigger 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. Definire il trigger 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. Definire la PROCEDURA comune utilizzata da entrambi questi trigger:

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 ;

Si noti che mi occupo di ripristinare il delimitatore quando ho finito con la mia attività di definire i trigger e la procedura.


1
Cosa c'è IN table_row_id VARCHAR(255)in questo caso? Voglio dire, come definisci quale riga verrà inserita o aggiornata?
VaTo

13

sfortunatamente non possiamo usarlo in MySQL dopo la descrizione INSERT o UPDATE , come in Oracle

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.