After Update Trigger trong MySQL - MySQL nâng cao
Trong bài này bạn sẽ học cách tạo After Update Trigger trong MySQL, đây là loại trigger được gọi sau khi lệnh update hoàn thành, vì vậy bạn có thể truy cập OLD và NEW nhưng không thay đổi được giá trị của chúng. Về cách hoạt động thì không khác gì lệnh After Insert, điểm khác duy nhất là một bên ...
Trong bài này bạn sẽ học cách tạo After Update Trigger trong MySQL, đây là loại trigger được gọi sau khi lệnh update hoàn thành, vì vậy bạn có thể truy cập OLD và NEW nhưng không thay đổi được giá trị của chúng.
Về cách hoạt động thì không khác gì lệnh After Insert, điểm khác duy nhất là một bên là INSERT TRIGGER
và một bên là UPDATE TRIGGER
.
1. Cú pháp After Update Trigger trong MySQL
Như thường lệ, bạn phải hiểu rằng đây là loại trigger hoạt động sau khi lệnh update thực hiện xong.
Cú pháp của nó như sau:
CREATE TRIGGER trigger_name AFTER UPDATE ON table_name FOR EACH ROW trigger_body
MySQL nhận biết đây là loại AFTER UPDATE
trigger thông qua từ khóa này.
Về phần trigger body bạn nên đặt trong thẻ BEGIN .. END
để tường minh, vì dù sao body nếu có nhiều lệnh SQL thì đó là điều bắt buộc.
DELIMITER $$ CREATE TRIGGER trigger_name AFTER UPDATE ON table_name FOR EACH ROW BEGIN -- statements END$$ DELIMITER ;
Như mình đã nói ở trên, bạn có thể truy xuất đến giá trị của OLD
và NEW
nhưng không thể cập nhật được, vì MySQL đã thực hiện update xong mới gọi đến trigger này.
2. Ví dụ After Update Trigger trong MySQL
Hãy xem ví dụ dưới đây, chúng ta vẫn làm việc với bảng sales như ở bài trước. Hãy chạy lệnh SQL này để tạo bảng.
Tạo table sale
Dưới đây là cấu trúc của bảng Sales
.
DROP TABLE IF EXISTS Sales; CREATE TABLE Sales ( id INT AUTO_INCREMENT, product VARCHAR(100) NOT NULL, quantity INT NOT NULL DEFAULT 0, fiscalYear SMALLINT NOT NULL, fiscalMonth TINYINT NOT NULL, CHECK(fiscalMonth >= 1 AND fiscalMonth <= 12), CHECK(fiscalYear BETWEEN 2000 and 2050), CHECK (quantity >=0), UNIQUE(product, fiscalYear, fiscalMonth), PRIMARY KEY(id) );
Tiếp theo hãy insert 3 dòng dữ liệu vào, khác hoàn toàn với bài trước.
INSERT INTO Sales(product, quantity, fiscalYear, fiscalMonth) VALUES ('2001 Ferrari Enzo',140, 2021,1), ('1998 Chrysler Plymouth Prowler', 110,2021,1), ('1913 Ford Model T Speedster', 120,2021,1);
Nào, bây giờ hãy sử dụng lệnh Select
để xem trong bảng có gì nhé.
SELECT * FROM Sales;
Tạo thêm một table SalesChanges
để lưu trữ thông tin cập nhật của bảng sales
.
DROP TABLE IF EXISTS SalesChanges; CREATE TABLE SalesChanges ( id INT AUTO_INCREMENT PRIMARY KEY, salesId INT, beforeQuantity INT, afterQuantity INT, changedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP );
Tạo trigger
Tiếp theo hãy tạo trigger xử lý tình huống sau: Nếu giá trị của quantity
cập nhật khác với gí trị cũ thì hãy lưu vết vào table SalesChanges
để sau này biết lịch sử thay đổi của nó.
DELIMITER $$ CREATE TRIGGER after_sales_update AFTER UPDATE ON sales FOR EACH ROW BEGIN IF OLD.quantity <> new.quantity THEN INSERT INTO SalesChanges(salesId,beforeQuantity, afterQuantity) VALUES(old.id, old.quantity, new.quantity); END IF; END$$ DELIMITER ;
Về các hàm mình sử dụng ở trên khá quen thuộc với các bạn rồi nên mình không giải thích gì thêm.
Thử trigger
Bây giờ hãy thử update dữ liệu xem trigger có hoạt động không nhé.
Bạn hãy để ý dòng dữ liệu ID = 1
có giá trị của quantity
là 140, bây giờ mình sẽ cập nhật nó thành 350.
Nếu như trigger hoạt động đúng thì nó sẽ lưu vết vào bảng SalesChanges
.
UPDATE Sales SET quantity = 350 WHERE id = 1;
Hãy chạy câu SQL trên nhé, sau đó chạy lệnh dưới đây để xem trong bảng SalesChanges
có gì không.
SELECT * FROM SalesChanges;
Như vậy là nó đã hoạt động. Bây giờ hãy thử cập nhật tất của quantity
tăng lên 10%.
UPDATE Sales SET quantity = CAST(quantity * 1.1 AS UNSIGNED);
Xem lại bảng SalesChanges:
SELECT * FROM SalesChanges;
Vùng mình khoanh đỏ chính là ba dòng dữ liệu đã được thêm vào bởi vì mình đã update tăng 10% quantity
cho 3 rows trong bảng Sales
.
Như vậy là mình đã hướng dẫn xong cách sử dụng After Update Trigger trong MySQL, với loại trigger này sẽ giúp bạn làm được khá nhiều việc, nhất là dùng đẻ lưu vết các table.