CodeGym /Các khóa học /SQL SELF /Tạo trigger đơn giản để cập nhật dữ liệu: AFTER INSERT

Tạo trigger đơn giản để cập nhật dữ liệu: AFTER INSERT

SQL SELF
Mức độ , Bài học
Có sẵn

Giả sử tụi mình có một bảng lưu thông tin về sinh viên. Trong bảng này, mình cần tự động cập nhật trường last_modified (ngày sửa đổi cuối cùng của bản ghi) mỗi khi thêm sinh viên mới. Trường này quan trọng để theo dõi thay đổi và quản lý dữ liệu nha.

Kịch bản hoạt động như sau:

  1. Khi thêm bản ghi mới vào bảng, trường last_modified sẽ tự động nhận ngày giờ hiện tại.
  2. Tụi mình sẽ dùng trigger AFTER INSERT, nó sẽ chạy sau khi chèn dữ liệu thành công.

Tạo function cho trigger

Đầu tiên phải tạo một function bằng PL/pgSQL. Function này sẽ cập nhật trường last_modified trong bảng của tụi mình. Function là phần bắt buộc để trigger hoạt động, vì trigger chỉ chỉ định việc cần làm, còn logic thì function xử lý hết.

Giờ bắt đầu tạo bảng nha:

-- Tạo bảng students
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    age INT NOT NULL,
    last_modified TIMESTAMP
);

Giờ tạo function để cập nhật trường last_modified:

-- Function để cập nhật last_modified
CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
    -- Gán thời gian hiện tại vào trường last_modified
    NEW.last_modified := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Giải thích chút về function này nha:

  • CREATE OR REPLACE FUNCTION update_last_modified() — tạo function tên là update_last_modified. Nếu đã có rồi thì nó sẽ thay thế luôn.
  • RETURNS TRIGGER — chỉ ra rằng function này dùng cho trigger.
  • NEW.last_modified := NOW(); — cập nhật trường last_modified bằng function NOW(), trả về ngày giờ hiện tại.
  • RETURN NEW; — trả về bản ghi đã cập nhật. Bước này bắt buộc cho trigger AFTER.

Tạo trigger

Sau khi có function rồi thì tạo trigger, gắn nó vào bảng students. Làm như này nè:

-- Tạo trigger sau khi chèn bản ghi
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();

Ý nghĩa từng dòng như sau:

  • CREATE TRIGGER set_last_modified — tạo trigger tên là set_last_modified.
  • AFTER INSERT — trigger sẽ chạy sau khi chèn dòng mới vào bảng.
  • ON students — trigger gắn với bảng students.
  • FOR EACH ROW — trigger sẽ chạy cho từng dòng mới được thêm vào bảng.
  • EXECUTE FUNCTION update_last_modified(); — gọi function mà tụi mình vừa tạo ở trên.

Lưu ý: tên trigger (set_last_modified) và function (update_last_modified) bạn đặt sao cũng được, nhưng nên theo chuẩn đặt tên để code dễ hiểu nha.

Kiểm thử trigger

Test thử trigger hoạt động chưa. Đầu tiên thêm vài bản ghi vào bảng students:

-- Thêm dữ liệu vào bảng
INSERT INTO students (name, age) VALUES ('Ivan Ivanov', 20);
INSERT INTO students (name, age) VALUES ('Anna Petrova', 22);

Giờ xem thử bảng có gì:

-- Xem dữ liệu trong bảng
SELECT * FROM students;

Kết quả mong đợi sẽ kiểu như này:

id name age last_modified
1 Otto Min 20 2023-10-10 14:30:45
2 Anna Song 22 2023-10-10 14:31:12

Chú ý là trường last_modified đã tự động được điền ngày giờ hiện tại cho từng bản ghi nha.

Các lỗi có thể gặp

  1. Lỗi: "relation does not exist" khi tạo trigger. Lỗi này xảy ra nếu bảng students chưa được tạo. Nhớ tạo bảng trước khi tạo trigger nha.
  2. Lỗi quyền truy cập. Nếu user database không có quyền tạo function hoặc trigger thì trigger sẽ không được tạo. Kiểm tra quyền của user nha.
  3. Quên gọi function trong trigger. Nếu bạn quên ghi EXECUTE FUNCTION update_last_modified() thì trigger sẽ không thực hiện được việc cần làm đâu.

Nâng cấp trigger: thêm điều kiện

Trong thực tế, đôi khi bạn muốn trigger chỉ chạy khi thỏa mãn điều kiện nào đó. Ví dụ, nếu trường age nhỏ hơn 18 thì không muốn cập nhật last_modified. Làm được bằng điều kiện WHEN nè:

-- Tạo trigger có điều kiện
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
WHEN (NEW.age >= 18)
EXECUTE FUNCTION update_last_modified();

Giờ trường last_modified chỉ cập nhật cho sinh viên có tuổi >= 18 thôi nha.

Ứng dụng thực tế

Những trigger kiểu này được dùng nhiều trong dự án thực tế lắm. Ví dụ nè:

  • Tự động cập nhật thời gian sửa đổi cuối cùng của bản ghi (giống như mình vừa làm).
  • Theo dõi thay đổi trong database và ghi lại vào bảng log.
  • Đảm bảo tính toàn vẹn dữ liệu, ví dụ kiểm tra các bảng liên quan trước khi thực hiện thao tác.
  • Audit dữ liệu để tuân thủ quy định pháp luật hoặc quy tắc công ty.

Kỹ năng này rất hữu ích nếu bạn làm việc với hệ thống mà độ chính xác và tin cậy dữ liệu quan trọng, ví dụ hệ thống ngân hàng, quản lý kho hoặc CRM.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION