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 тригери? Код однаковий для обох, і я не хочу його повторювати.

Відповіді:


126

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


3
Чи можете ви навести іграшковий приклад цього для тих, хто нам незнайомий із синтаксисом?
Zxaos

3
@ Zxaos: Я б запропонував почати з dev.mysql.com/doc/refman/5.1/en/create-procedure.html (який включає деякі приклади) та задати власні запитання, якщо потрібно.
дероберт

2
Шкода, що ми не можемо використовувати операторів AND / OR, як в Oracle, тим більше, коли ми також не можемо передати параметр процедурі цілих змінних СТАРО та НОВО. Мій код буде> 2x
Mikel

Це корисно для розробника, який ніколи не
піде

1
@luismartingil, ймовірно, є додаткові накладні витрати на виклик процедури проти вбудовування її. Але в обмін ви отримуєте легше обслуговування та гарантію, що код двох тригерів не випадково розійдеться.
дероберт

46

У відповідь на запит @Zxaos, оскільки ми не можемо мати операторів AND / OR для тригерів 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.