MySQL Fire Trigger cho cả Chèn và Cập nhật


111

Có thể kích hoạt trình kích hoạt mysql cho cả sự kiện chèn và cập nhật của bảng không?

Tôi biết tôi có thể làm những điều sau

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

Nhưng làm sao tôi có thể làm được

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

Có được không, hay tôi phải sử dụng 2 trigger? Mã này giống nhau cho cả hai và tôi không muốn lặp lại nó.

Câu trả lời:


126

Bạn phải tạo hai trình kích hoạt, nhưng bạn có thể chuyển mã chung vào một thủ tục và cả hai đều gọi thủ tục đó.


3
Bạn có thể đưa ra một ví dụ đồ chơi về điều này cho những người trong chúng ta, những người không quen với cú pháp?
Zxaos

3
@Zxaos: Tôi khuyên bạn nên bắt đầu với dev.mysql.com/doc/refman/5.1/en/create-procedure.html (bao gồm một số ví dụ) và đặt (các) câu hỏi của riêng bạn nếu cần.
derobert

2
Thật tiếc là chúng ta không thể sử dụng các toán tử AND / OR như trong Oracle, thậm chí nhiều hơn khi chúng ta cũng không thể chuyển theo tham số cho một thủ tục toàn bộ các biến CŨ và MỚI. Mã của tôi sẽ là> 2x
Mikel

Cái này thì hữu ích cho một nhà phát triển người không bao giờ thỏa hiệp trên viết một mã hai lần ..
Sayka

1
@luismartil có thể có thêm một số chi phí của việc gọi một thủ tục so với nội tuyến nó. Nhưng đổi lại, bạn sẽ được bảo trì dễ dàng hơn và đảm bảo rằng mã của hai trình kích hoạt sẽ không vô tình khác nhau.
derobert

46

Đáp lại yêu cầu @Zxaos, vì chúng tôi không thể có toán tử VÀ / HOẶC cho trình kích hoạt MySQL, bắt đầu bằng mã của bạn, dưới đây là một ví dụ hoàn chỉnh để đạt được điều tương tự.

1. Xác định kích hoạt 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. Xác định trình kích hoạt CẬP NHẬT

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. Xác định QUY TRÌNH chung được sử dụng bởi cả hai trình kích hoạt này:

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 ;

Bạn lưu ý rằng tôi chú ý khôi phục dấu phân cách khi tôi hoàn tất công việc xác định trình kích hoạt và quy trình.


1
Cái gì IN table_row_id VARCHAR(255)trong trường hợp này? Ý tôi là làm cách nào bạn xác định hàng nào sẽ được chèn hoặc cập nhật?
VaTo

13

Rất tiếc, chúng tôi không thể sử dụng trong MySQL sau khi mô tả INSERT hoặc UPDATE , như trong Oracle

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.