MySQL Fire Trigger для вставки и обновления

111

Можно ли запустить триггер mysql как для событий вставки, так и для обновления таблицы?

Я знаю, что могу сделать следующее

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

Но как я могу

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

Возможно ли это, или надо использовать 2 триггера? Код одинаков для обоих, и я не хочу его повторять.

Адам С-Прайс
источник

Ответы:

127

Вы должны создать два триггера, но вы можете переместить общий код в процедуру и заставить их оба вызывать процедуру.

Derobert
источник
3
Не могли бы вы привести игрушечный пример для тех из нас, кто не знаком с синтаксисом?
Zxaos 01
3
@Zxaos: я бы посоветовал начать с dev.mysql.com/doc/refman/5.1/en/create-procedure.html (который включает несколько примеров) и при необходимости задать свой вопрос (вопросы).
derobert 01
2
Жалко, что мы не можем использовать операторы И / ИЛИ, как в Oracle, тем более, что мы также не можем передавать по параметрам процедуре целые переменные OLD и NEW. Мой код будет> 2x
Mikel
Это полезно для разработчика, который никогда не идет на компромисс при написании кода дважды ..
Sayka
1
@luismartingil, вероятно, дополнительные накладные расходы на вызов процедуры по сравнению с ее встраиванием. Но взамен вы получаете более легкое обслуживание и гарантию того, что код двух триггеров случайно не разойдется.
derobert
46

В ответ на запрос @Zxaos, поскольку у нас не может быть операторов И / ИЛИ для триггеров MySQL, начиная с вашего кода, ниже приведен полный пример достижения того же.

1. Определите триггер 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. Определите триггер 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. Определите общую ПРОЦЕДУРУ, используемую обоими этими триггерами:

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 ;

Вы заметили, что я позабочусь о восстановлении разделителя, когда закончу с определением триггеров и процедур.

Аль-Зива
источник
1
Что IN table_row_id VARCHAR(255)в этом случае? Я имею в виду, как вы определяете, какая строка будет вставлена ​​или обновлена?
VaTo
13

к сожалению, мы не можем использовать в MySQL после описания INSERT или UPDATE , как в Oracle

Джефф Алиффсон
источник