Trigger trong MySQL là một cơ chế tự động thực hiện một tập các câu lệnh SQL khi có một sự kiện cụ thể xảy ra trong cơ sở dữ liệu, chẳng hạn như thêm, cập nhật, hoặc xóa dữ liệu. Nó giúp bạn tự động hóa các quy trình, bảo vệ tính toàn vẹn dữ liệu, và thực hiện các thao tác phức tạp mà không cần can thiệp thủ công.

Các thành phần chính của Trigger:

  1. Sự kiện kích hoạt (Triggering Event): Trigger được kích hoạt bởi một sự kiện trong bảng, chẳng hạn như INSERT, UPDATE, hoặc DELETE. Trigger có thể được thiết lập để kích hoạt trước hoặc sau khi sự kiện xảy ra:
    • BEFORE: Trigger thực hiện trước khi sự kiện xảy ra.
    • AFTER: Trigger thực hiện sau khi sự kiện đã xảy ra.
  2. Bảng (Table): Trigger chỉ áp dụng cho một bảng cụ thể. Khi có sự kiện trong bảng đó, trigger sẽ được kích hoạt.
  3. Thân Trigger (Trigger Body): Đây là phần chứa các câu lệnh SQL sẽ được thực thi khi trigger kích hoạt. Nó có thể bao gồm các câu lệnh phức tạp như UPDATE, INSERT, DELETE, hoặc gọi đến các thủ tục.

Cách tạo Trigger trong MySQL:

Cú pháp để tạo một trigger trong MySQL:

CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name
FOR EACH ROW
BEGIN
    -- Câu lệnh SQL thực thi khi trigger được kích hoạt
END;

Ví dụ về Trigger:

Giả sử bạn có một bảng orders và bạn muốn ghi lại lịch sử các đơn hàng vào bảng order_history mỗi khi có đơn hàng mới được thêm vào bảng orders:

CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
    INSERT INTO order_history (order_id, product_id, quantity, created_at)
    VALUES (NEW.order_id, NEW.product_id, NEW.quantity, NOW());
END;
  • AFTER INSERT: Trigger này được kích hoạt sau khi một bản ghi mới được thêm vào bảng orders.
  • NEW: Là một từ khóa đặc biệt trong trigger, nó tham chiếu đến dữ liệu mới vừa được chèn vào bảng orders.

Ứng dụng của Trigger:

  1. Kiểm tra tính toàn vẹn của dữ liệu: Trigger có thể được sử dụng để xác minh hoặc thực hiện các thao tác nhằm đảm bảo rằng dữ liệu nhập vào phù hợp với các quy tắc kinh doanh hoặc ràng buộc dữ liệu.
  2. Tự động cập nhật bảng khác: Khi có thay đổi trong một bảng, trigger có thể tự động cập nhật các bảng khác liên quan.
  3. Theo dõi và ghi lại thay đổi: Trigger có thể ghi lại các thay đổi vào một bảng lịch sử hoặc nhật ký để theo dõi những thay đổi trong cơ sở dữ liệu.
  4. Tự động tính toán: Trigger có thể thực hiện các tính toán hoặc cập nhật dữ liệu phụ thuộc vào sự kiện trong cơ sở dữ liệu.

Một số lưu ý khi sử dụng Trigger:

  • Triggers có thể làm cho cơ sở dữ liệu phức tạp hơn và khó quản lý, đặc biệt là khi có nhiều triggers kích hoạt lẫn nhau.
  • Quản lý tốt thứ tự thực thi các triggers rất quan trọng để tránh xung đột hoặc kết quả không mong muốn.
  • Trigger không thể gọi trực tiếp các câu lệnh điều khiển giao tác như COMMIT hoặc ROLLBACK.

Trigger giúp bạn tự động hóa các tác vụ lặp lại, đảm bảo tính toàn vẹn dữ liệu và dễ dàng quản lý sự phức tạp trong hệ thống cơ sở dữ liệu.

Ví dụ về các loại Trigger trong MySQL

Dưới đây là các ví dụ chi tiết về Trigger trong MySQL, bao gồm các loại trigger khác nhau như BEFORE INSERT, AFTER INSERT, BEFORE UPDATE, AFTER UPDATE, BEFORE DELETE, và AFTER DELETE. Những ví dụ này sẽ giúp bạn hiểu rõ hơn cách sử dụng trigger trong các tình huống thực tế.

1. Trigger BEFORE INSERT

Trigger BEFORE INSERT được kích hoạt trước khi một bản ghi mới được chèn vào bảng. Trigger này có thể được sử dụng để thực hiện kiểm tra hoặc thay đổi dữ liệu trước khi chèn.

Ví dụ:

Khi một người dùng đăng ký mới, ta muốn tự động điền giá trị mặc định cho trường created_at nếu người dùng không cung cấp.

CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    IF NEW.created_at IS NULL THEN
        SET NEW.created_at = NOW();
    END IF;
END;
  • NEW.created_at: Tham chiếu đến giá trị mới đang được chèn vào. Nếu created_at chưa được cung cấp, nó sẽ được gán giá trị hiện tại bằng NOW().

2. Trigger AFTER INSERT

Trigger AFTER INSERT được kích hoạt sau khi một bản ghi mới đã được chèn vào bảng. Trigger này thường dùng để cập nhật hoặc ghi lại các thay đổi trong một bảng khác.

Ví dụ:

Khi một đơn hàng mới được tạo, chúng ta sẽ thêm một bản ghi vào bảng order_history để theo dõi lịch sử của các đơn hàng.

CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
    INSERT INTO order_history (order_id, product_id, quantity, created_at)
    VALUES (NEW.order_id, NEW.product_id, NEW.quantity, NOW());
END;
  • AFTER INSERT: Sau khi chèn vào bảng orders, dữ liệu đơn hàng sẽ được ghi lại vào bảng order_history.

3. Trigger BEFORE UPDATE

Trigger BEFORE UPDATE được kích hoạt trước khi một bản ghi được cập nhật. Nó có thể được sử dụng để kiểm tra hoặc thay đổi dữ liệu trước khi bản ghi thực sự được cập nhật.

Ví dụ:

Trong hệ thống quản lý nhân viên, nếu cập nhật mức lương của nhân viên, bạn muốn đảm bảo rằng mức lương không được giảm xuống dưới mức lương hiện tại.

CREATE TRIGGER before_employee_update
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
    IF NEW.salary < OLD.salary THEN
        SET NEW.salary = OLD.salary;  -- Ngăn chặn giảm lương
    END IF;
END;

NEW.salary: Giá trị lương mới được cập nhật.

OLD.salary: Giá trị lương hiện tại trước khi cập nhật.

4. Trigger AFTER UPDATE

Trigger AFTER UPDATE được kích hoạt sau khi một bản ghi được cập nhật. Trigger này có thể được sử dụng để ghi nhật ký hoặc thực hiện các thay đổi bổ sung dựa trên việc cập nhật.

Ví dụ:

Khi cập nhật thông tin đơn hàng, chúng ta sẽ ghi lại những thay đổi vào bảng order_history.

CREATE TRIGGER after_order_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
    INSERT INTO order_history (order_id, product_id, quantity, updated_at)
    VALUES (NEW.order_id, NEW.product_id, NEW.quantity, NOW());
END;
  • AFTER UPDATE: Ghi lại vào bảng order_history sau khi đơn hàng được cập nhật.

5. Trigger BEFORE DELETE

Trigger BEFORE DELETE được kích hoạt trước khi một bản ghi bị xóa. Nó có thể được sử dụng để kiểm tra hoặc thực hiện các tác vụ trước khi dữ liệu bị xóa.

Ví dụ:

Trước khi xóa một tài khoản người dùng, chúng ta muốn ghi lại thông tin của người dùng đó vào bảng deleted_users.

CREATE TRIGGER before_user_delete
BEFORE DELETE ON users
FOR EACH ROW
BEGIN
    INSERT INTO deleted_users (user_id, name, email, deleted_at)
    VALUES (OLD.user_id, OLD.name, OLD.email, NOW());
END;
  • OLD: Tham chiếu đến dữ liệu của bản ghi sẽ bị xóa.
  • Dữ liệu người dùng sẽ được sao chép vào bảng deleted_users trước khi bị xóa khỏi bảng users.

6. Trigger AFTER DELETE

Trigger AFTER DELETE được kích hoạt sau khi một bản ghi bị xóa. Nó có thể được sử dụng để ghi nhật ký hoặc thực hiện các hành động bổ sung sau khi dữ liệu đã bị xóa.

Ví dụ:

Khi xóa một đơn hàng khỏi bảng orders, chúng ta sẽ xóa luôn các mục tương ứng trong bảng order_items.

CREATE TRIGGER after_order_delete
AFTER DELETE ON orders
FOR EACH ROW
BEGIN
    DELETE FROM order_items WHERE order_id = OLD.order_id;
END;
  • AFTER DELETE: Sau khi xóa một đơn hàng khỏi bảng orders, các mục tương ứng trong bảng order_items cũng sẽ bị xóa theo.

7. Trigger BEFORE INSERT với kiểm tra điều kiện

Trigger này có thể dùng để kiểm tra dữ liệu đầu vào trước khi chèn. Ví dụ, bạn muốn đảm bảo rằng không ai có thể đăng ký người dùng với tuổi nhỏ hơn 18.

CREATE TRIGGER before_user_insert_check_age
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    IF NEW.age < 18 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Age must be 18 or older!';
    END IF;
END;
  • SIGNAL SQLSTATE: Phát ra lỗi khi điều kiện không thỏa mãn, ngăn không cho chèn dữ liệu.

8. Trigger AFTER INSERT với tự động cập nhật giá trị

Sau khi thêm một đơn hàng mới, hệ thống sẽ tự động cập nhật tổng số lượng hàng tồn kho cho sản phẩm.

CREATE TRIGGER after_order_insert_update_stock
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
    UPDATE products
    SET stock = stock - NEW.quantity
    WHERE product_id = NEW.product_id;
END;
  • UPDATE: Cập nhật số lượng tồn kho sau khi đơn hàng mới được chèn vào.

Tóm lại là

Các Trigger trong MySQL giúp bạn tự động hóa nhiều quy trình quản lý cơ sở dữ liệu phức tạp, bảo đảm tính toàn vẹn dữ liệu và tự động thực hiện các tác vụ cần thiết khi có sự thay đổi trong bảng. Tùy thuộc vào nhu cầu, bạn có thể chọn loại trigger phù hợp (BEFORE/AFTER INSERT, UPDATE, DELETE) để đảm bảo hoạt động tối ưu.