MySQL Fire Trigger für Einfügen und Aktualisieren

110

Ist es möglich, einen MySQL-Trigger sowohl für die Einfüge- als auch für die Aktualisierungsereignisse einer Tabelle auszulösen?

Ich weiß, dass ich Folgendes tun kann

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

Aber wie kann ich das machen?

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

Ist es möglich oder muss ich 2 Trigger verwenden? Der Code ist für beide gleich und ich möchte ihn nicht wiederholen.

Adam S-Preis
quelle

Antworten:

126

Sie müssen zwei Trigger erstellen, aber Sie können den allgemeinen Code in eine Prozedur verschieben und beide die Prozedur aufrufen lassen.

derobert
quelle
3
Könnten Sie ein Spielzeugbeispiel für diejenigen von uns geben, die mit der Syntax nicht vertraut sind?
Zxaos
3
@Zxaos: Ich würde vorschlagen, mit dev.mysql.com/doc/refman/5.1/en/create-procedure.html (einschließlich einiger Beispiele) zu beginnen und bei Bedarf Ihre eigenen Fragen zu stellen.
Derobert
2
Es ist schade, dass wir keine AND / OR-Operatoren wie in Oracle verwenden können, umso mehr, wenn wir die gesamten Variablen OLD und NEW nicht als Parameter an eine Prozedur übergeben können. Mein Code wird> 2x sein
Mikel
Dies ist nützlich für einen Entwickler, der
eingeht
1
@luismartingil Es gibt wahrscheinlich einen zusätzlichen Aufwand für das Aufrufen einer Prozedur im Vergleich zum Inlining. Im Gegenzug erhalten Sie jedoch eine einfachere Wartung und die Garantie, dass der Code der beiden Trigger nicht versehentlich abweicht.
Derobert
46

Als Antwort auf die @ Zxaos-Anfrage finden Sie unten ein vollständiges Beispiel, um dasselbe zu erreichen, da wir keine UND / ODER-Operatoren für MySQL-Trigger haben können, beginnend mit Ihrem Code.

1. Definieren Sie den INSERT-Trigger:

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. Definieren Sie den UPDATE-Trigger

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. Definieren Sie das gemeinsame VERFAHREN, das von diesen beiden Triggern verwendet wird:

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 ;

Sie stellen fest, dass ich darauf achte, das Trennzeichen wiederherzustellen, wenn ich mit der Definition der Auslöser und der Prozedur fertig bin.

Al Zziwa
quelle
1
Was ist IN table_row_id VARCHAR(255)in diesem Fall? Ich meine, wie definieren Sie, welche Zeile eingefügt oder aktualisiert werden soll?
VaTo
13

Leider können wir MySQL nicht nach der INSERT- oder UPDATE- Beschreibung verwenden, wie in Oracle

Jeff_Alieffson
quelle