Trigger trong SQL là công cụ mạnh mẽ trong quản lý cơ sở dữ liệu, giúp tự động hóa các tác vụ và đảm bảo tính toàn vẹn của dữ liệu. Tìm hiểu về các thao tác cơ bản với trigger SQL với từng loại trigger khác nhau.

Đọc bài viết này để hiểu rõ hơn về:

  • Trigger là gì
  • Các thành phần chính của một trigger
  • Các thao tác cơ bản với trigger trong SQL
  • Các loại trigger
  • Ưu nhược điểm của trigger

Trigger là gì?

Trigger (hay trình kích hoạt) trong SQL là một đoạn mã tự động thực thi khi xảy ra một sự kiện cụ thể trên bảng hoặc chế độ xem (view) trong cơ sở dữ liệu, chẳng hạn như thêm, sửa, xóa dữ liệu hoặc thay đổi cấu trúc bảng. Trigger hoạt động như một cơ chế giám sát, đảm bảo rằng mọi thay đổi trong cơ sở dữ liệu tuân theo các quy tắc và quy định đã thiết lập. Trigger giúp duy trì tính toàn vẹn dữ liệu, tự động hóa các tác vụ và giảm thiểu lỗi do thao tác thủ công.

Trigger còn được coi là một dạng stored procedure đặc biệt nhưng không có tham số và chúng được tự động kích hoạt mà không cần được gọi trực tiếp bởi người dùng hay ứng dụng. Ví dụ, trong trường hợp bạn cần theo dõi tần suất và thời điểm thay đổi dữ liệu trong một bảng thường xuyên cập nhật, ta có thể sử dụng trigger để tự động ghi lại thông tin thay đổi vào một bảng khác, giúp dễ dàng kiểm soát và phân tích lịch sử thay đổi mà không cần thao tác thủ công.

Tùy vào hệ quản trị cơ sở dữ liệu, cú pháp và chức năng cụ thể của triggers có thể khác nhau, nhưng mục đích chung vẫn là duy trì tính toàn vẹn dữ liệu hoặc tự động hóa các tác vụ và bảo vệ hoạt động của cơ sở dữ liệu.

Thành phần của một trigger trong SQL

Trigger là một tập hợp các câu lệnh SQL tự động được thực thi khi xảy ra một sự kiện cụ thể trên cơ sở dữ liệu. Các thành phần chính của một trigger bao gồm:

  • Tên Trigger: Tên định danh của trigger trong cơ sở dữ liệu.
  • Đối tượng bị ảnh hưởng: Là bảng hoặc view mà trigger được áp dụng. Điều này được xác định trong phần ON.
  • Loại Sự Kiện: Xác định trigger sẽ được kích hoạt khi nào, bao gồm các hành động như INSERT, UPDATE, DELETE, hoặc các sự kiện DDL (Data Definition Language).
  • Thời điểm Kích Hoạt:
    • AFTER: Trigger thực thi sau khi sự kiện hoàn thành.
    • INSTEAD OF: Thay thế hành động mặc định của sự kiện.
  • Thân Trigger (Trigger Body): Nằm giữa BEGIN … END, chứa các câu lệnh SQL thực hiện hành động cụ thể khi trigger được kích hoạt. Ví dụ: ghi log, kiểm tra điều kiện hoặc thực hiện các thao tác trên bảng khác.

Cấu trúc tổng quát của trigger như sau:

CREATE|ALTER TRIGGER trigger_name

ON {table_name | view_name | DATABASE | ALL SERVER}  

{FOR | AFTER | INSTEAD OF} {event_type}  

AS  

BEGIN  

    -- Các câu lệnh cần thực hiện khi trigger được kích hoạt

END;

Một số thao tác với trigger

Cú pháp với trigger có thể khác nhau tùy theo hệ quản trị cơ sở dữ liệu (DBMS) mà bạn đang sử dụng. Dưới đây là cú pháp tổng quát của trigger trong SQL Server:

Tạo trigger

Khi tạo trigger bạn sẽ được yêu cầu phải xác định thời điểm trigger sẽ được thực thi (khi nào) và hành động mà nó sẽ thực hiện. 

Cú pháp tổng quát:

CREATE TRIGGER [schema_name.]trigger_name  

ON { table_name | view_name } 

{ BEFORE | AFTER | INSTEAD OF } { INSERT | UPDATE | DELETE }  

AS  

BEGIN

  -- Trigger statements  

END;

Ví dụ để tạo một trigger ghi lại các thông tin của bản ghi bị xóa trong bảng employees vào bảng employees_log ta sử dụng cú pháp sau:

CREATE TRIGGER after_employee_delete  

ON employees 

AFTER DELETE  

AS  

BEGIN

    INSERT INTO employees_log (employee_id, name, action)  

    VALUES (OLD.employee_id, OLD.name, 'deleted');  

END;

Xoá trigger

Cú pháp:

DROP TRIGGER [IF EXISTS] schema_name.trigger_name;

Hoặc nếu bạn sử dụng SQL Server, bạn có thể tạm thời vô hiệu hóa trigger mà không cần phải xoá hoặc sửa lại trigger với cú pháp sau:

DISABLE TRIGGER trigger_name ON table_name;

Để kích hoạt lại trigger, ta dùng cú pháp như sau:

ENABLE TRIGGER trigger_name ON table_name;

Sửa đổi trigger

Để sửa đổi một trigger, bạn cần phải xóa trigger cũ và tạo một trigger mới với các thay đổi mong muốn.

Cú pháp:

DROP TRIGGER IF EXISTS trigger_name; 

CREATE TRIGGER trigger_name  

ON { table_name | view_name } 

{ BEFORE | AFTER | INSTEAD OF } { INSERT | UPDATE | DELETE }   

AS  

BEGIN

  -- Trigger statements  

END;

Ví dụ để xóa trigger log_changes và tạo lại trigger mới để ghi lại thông tin khi bản ghi trong bảng employees được cập nhật, ta sử dụng cú pháp sau:

DROP TRIGGER IF EXISTS log_changes; 

CREATE TRIGGER log_changes  

ON employees 

AFTER UPDATE  

AS

BEGIN  

   INSERT INTO employees_log (employee_id, name, action)  

   VALUES (OLD.employee_id, OLD.name, 'updated');  

END;

Kiểm tra trigger

Có thể xem các trigger đã được tạo trong cơ sở dữ liệu bằng cách sử dụng các câu lệnh truy vấn đặc biệt tùy theo DBMS mà bạn sử dụng. Trong SQL Server, bạn có thể xem các trigger thông qua truy vấn hệ thống.

Cú pháp:

SELECT * FROM sys.triggers

Với cú pháp trên sẽ trả về bảng kết quả gồm:

Cột Mô tả
name Tên trigger.
object_id ID duy nhất của trigger trong cơ sở dữ liệu.
parent_id ID của bảng hoặc đối tượng mà trigger được gắn vào.
type Loại đối tượng, thường là ‘TR’ cho trigger.
type_desc Mô tả loại đối tượng, ví dụ: ‘SQL_TRIGGER’ cho trigger thông thường.
create_date Thời gian tạo trigger.
modify_date Thời gian chỉnh sửa gần nhất của trigger.
is_ms_shipped Giá trị boolean (0 hoặc 1), xác định trigger do hệ thống cung cấp hay không.
is_disabled Giá trị boolean, xác định trigger có đang bị vô hiệu hóa hay không.

Ví dụ ta có kết quả trả về như sau:

name object_id parent_id type type_desc create_date modify_date is_ms_shipped is_disabled
log_changes 123456 654321 TR SQL_TRIGGER 2024-01-01 10:00:00 2024-01-02 12:00:00 0 0

Các loại trigger trong SQL

DML trigger 

DML Trigger (Data Manipulation Language Trigger) được kích hoạt bởi các thao tác dữ liệu như INSERT, UPDATEDELETE trên bảng hoặc view. Đây là loại trigger giúp giám sát và tự động xử lý các thay đổi dữ liệu.

DML trigger bao gồm:

  • Before Trigger: Được kích hoạt trước khi hành động INSERT, UPDATE hoặc DELETE được thực hiện thành công và bao gồm BEFORE + INSERT/UPDATE/DELETE.
  • After Trigger: Được kích hoạt sau khi hành động INSERT, UPDATE hoặc DELETE được thực hiện thành công và bao gồm AFTER + INSERT/UPDATE/DELETE. Lưu ý là After trigger không được hỗ trợ trên view.
  • Instead of Trigger: Thay thế hành động INSERT, UPDATE hoặc DELETE mặc định bằng hành động được chỉ định trong trigger và bao gồm INSTEAD OF + INSERT/UPDATE/DELETE.

Lưu ý là SQL Server không hỗ trợ BEFORE Trigger.

DML trigger thường được sử dụng để:

  • Kiểm tra tính hợp lệ hoặc giới hạn thao tác dữ liệu.
  • Tự động cập nhật bảng khác dựa trên thay đổi trong bảng chính.
  • Ghi lại lịch sử thay đổi dữ liệu.

Cú pháp tổng quát trong SQL server:

CREATE|ALTER TRIGGER [schema_name.]trigger_name 

ON {table_name | view_name} 

{FOR | BEFORE | AFTER | INSTEAD OF } { INSERT | UPDATE | DELETE }

AS 

BEGIN 

-- trigger statements 

END;

Lưu ý là After trigger không thể sử dụng trên view trong SQL server.

Trong đó:

  • schema_name: Tùy chọn, là schema chứa bảng hoặc view.
  • trigger_name: Tên trigger.
  • AFTER hoặc INSTEAD OF: Thời điểm kích hoạt.
  • INSERT | UPDATE | DELETE: Loại sự kiện kích hoạt trigger.
  • BEGIN … END: Chứa các lệnh SQL cần thực hiện.

Ví dụ để tạo một AFTER INSERT trigger trên bảng Employees để ghi log khi có bản ghi mới được thêm vào, ta sử dụng cú pháp sau:

CREATE TRIGGER roAfterInsert  

ON Employees 

AFTER INSERT  

AS  

BEGIN  

   INSERT INTO EmployeeLog(EmployeeID, Action)  

   SELECT EmployeeID, 'Inserted'  

   FROM inserted;  

END;

Trong đó:

  • Bảng inserted: Là bảng tạm do SQL Server tạo, chứa các bản ghi mới được thêm vào.
  • Bảng deleted: Sử dụng trong các trigger DELETE hoặc UPDATE để chứa các bản ghi bị xóa hoặc bị thay đổi trước khi cập nhật.

=> Bảng inserteddeleted được sử dụng để so sánh dữ liệu trước và sau khi thay đổi trong trigger UPDATE.

DDL Trigger

DDL Trigger (Data Definition Language Trigger) có chức năng phản hồi các sự kiện liên quan đến thay đổi cấu trúc cơ sở dữ liệu như CREATE, ALTERDROP.

DDL trigger thường được sử dụng để:

  • Ngăn chặn các thay đổi không mong muốn trong cấu trúc cơ sở dữ liệu.
  • Theo dõi và ghi lại các thay đổi schema cho mục đích audit.
  • Tự động hóa các thao tác bảo mật đối với thay đổi cấu trúc dữ liệu.

Cú pháp tổng quát trong SQL Server:

CREATE|ALTER TRIGGER trigger_name  

ON { ALL SERVER | DATABASE }  

{ FOR | AFTER } { event_type }  

AS  

BEGIN  

    -- Trigger statements  

END;

Trong đó:

  • ALL SERVER: Áp dụng trên toàn bộ server.
  • DATABASE: Áp dụng trên cơ sở dữ liệu cụ thể.
  • event_type: Các sự kiện như CREATE_TABLE, DROP_TABLE.

Ví dụ để tạo một DDL trigger để ngăn chặn việc xóa bảng trong cơ sở dữ liệu, ta sử dụng cú pháp sau:

CREATE TRIGGER PreventDropTable  
ON DATABASE  

FOR DROP_TABLE  

AS  

BEGIN 

   PRINT 'Dropping tables is not allowed';  

   ROLLBACK;  

END;

Giải thích ví dụ: ​

  • Khi hành động DROP TABLE xảy ra, trigger sẽ hiển thị thông báo và hủy bỏ hành động.

Session Trigger

Là loại trigger được kích hoạt khi có sự kiện LOGON là khi một người dùng đăng nhập thành công nhưng trước khi phiên làm việc bắt đầu hoặc khi sự kiện LOGOFF khi người dùng kết thúc phiên làm việc. Cả hai trigger này cho phép kiểm soát phiên làm việc của người dùng, ghi log thông tin đăng nhập hoặc đăng xuất và áp đặt các chính sách bảo mật.

Session Trigger thường được sử dụng để:

  • Kiểm soát số lượng phiên làm việc, ghi nhận thời gian đăng nhập, hoặc giới hạn truy cập dựa trên điều kiện cụ thể.
  • Thực hiện các tác vụ dọn dẹp hoặc ghi lại thông tin cuối cùng của phiên làm việc.

Cú pháp tổng quát trên SQL server:

CREATE | ALTER  TRIGGER trigger_name  

ON ALL SERVER

{ FOR | AFTER } {LOGON | LOGOFF}  

AS  

BEGIN

  -- Trigger statements  

END;

Trong đó:

  • ALL SERVER: Chỉ định trigger áp dụng ở cấp máy chủ.
  • LOGON | LOGOFF: Chỉ định sự kiện kích hoạt khi người dùng đăng nhập hoặc đăng xuất.

Ví dụ để tạo một logon trigger để giới hạn số lượng phiên đăng nhập cho một tài khoản ta sử dụng cú pháp sau:

CREATE TRIGGER LimitLoginSessions  

ON ALL SERVER 

 FOR LOGON  

AS  

BEGIN

   IF (SELECT COUNT(*)  FROM sys.dm_exec_sessions WHERE login_name = ORIGINAL_LOGIN()) > 3  

       BEGIN 

           PRINT 'Login limit exceeded'; 

           ROLLBACK;  

      END  

END;

Giải thích ví dụ:

  • sys.dm_exec_sessions:  là bảng hệ thống chứa thông tin về các phiên làm việc hiện tại.
  • Trigger sẽ hủy đăng nhập nếu số phiên vượt quá 3.

Server Error Trigger

Là loại trigger được kích hoạt khi xảy ra lỗi máy chủ trong quá trình hoạt động.

Server Error Trigger được sử dụng để:

  • Ghi nhận lỗi hệ thống để phân tích và xử lý sau.
  • Thực hiện các hành động khắc phục khi xảy ra lỗi nghiêm trọng.

Cú pháp tổng quát trên SQL Server:

CREATE | ALTER  TRIGGER trigger_name  

ON ALL SERVER

{ FOR | AFTER } {LOGON | LOGOFF}  

AS  

BEGIN

  -- Trigger logic here

END;

Trong đó:

  • ERROR_LOG: Sự kiện kích hoạt trigger khi một lỗi hệ thống được ghi lại.

Ví dụ để tạo một trigger có chức năng giới hạn số lượng phiên đăng nhập đồng thời ta sử dụ cú pháp sau:

CREATE TRIGGER LimitLoginSessions  

ON ALL SERVER  

FOR LOGON  

AS  

BEGIN

   IF (SELECT COUNT(*)  FROM sys.dm_exec_sessions WHERE login_name = ORIGINAL_LOGIN()) > 3  

       BEGIN

           PRINT 'Login limit exceeded';

           ROLLBACK;  

      END  

END;

Giải thích ví dụ:

  • ERROR_MESSAGE(): Hàm trả về thông báo lỗi gần nhất.
  • GETDATE(): Hàm lấy thời gian hiện tại.
  • Trigger ghi lại lỗi vào bảng ServerErrorLog để phân tích sau.

Một số tips sử dụng trigger trong SQL hiệu quả

  • Giữ trigger đơn giản và hiệu quả: Tránh các logic phức tạp hoặc thao tác dữ liệu lớn trong trigger để không làm chậm hiệu suất hệ thống.
  • Sử dụng trigger để ghi log và audit: Trigger rất hữu ích trong việc tự động ghi lại các thay đổi dữ liệu, tạo ra các bản ghi audit để theo dõi và đảm bảo tính minh bạch.
  • Tránh thực hiện các hành động xử lý phức tạp trong trigger: Những hành động phức tạp nên được quản lý trong ứng dụng hoặc stored procedure, trigger chỉ nên dùng cho các tác vụ tự động đơn giản.
  • Ghi chú rõ ràng cho trigger: Ghi chép về mục đích và cách thức hoạt động của trigger giúp việc bảo trì và hiểu rõ hệ thống dễ dàng hơn, đặc biệt khi có nhiều trigger trong cơ sở dữ liệu.

Ưu điểm và hạn chế của trigger trong SQL

Ưu điểm Hạn chế
Tự động thực thi các tác vụ: Trigger được kích hoạt tự động, giảm thiểu sự can thiệp thủ công. Gây quá tải hiệu suất: Trigger có thể làm tăng tải cho máy chủ cơ sở dữ liệu nếu không được tối ưu hóa.
Tăng cường tính toàn vẹn dữ liệu: Trigger đảm bảo dữ liệu được kiểm tra và tuân thủ các quy tắc trước khi chèn hoặc cập nhật. Khó khăn trong việc gỡ lỗi: Trigger hoạt động ở tầng cơ sở dữ liệu, làm việc xác định và sửa lỗi phức tạp hơn.
Hỗ trợ ghi log và xử lý lỗi: Tự động ghi lại các thay đổi hoặc lỗi phát sinh. Rủi ro tạo vòng lặp vô hạn: Trigger có thể tạo ra vòng lặp vô hạn nếu không được cấu hình đúng, dẫn đến việc lặp lại các tác vụ không mong muốn.
Giảm tải công việc ở phía client: Nhiều thao tác được thực hiện trực tiếp trong cơ sở dữ liệu thay vì ứng dụng. Hạn chế trong quản lý: Trigger chỉ có thể được tạo trong cơ sở dữ liệu hiện tại và có thể tham chiếu đến các đối tượng ngoài cơ sở dữ liệu, gây khó khăn trong quản lý.
Dễ dàng chỉnh sửa, thêm mới hoặc xóa trigger. Khó kiểm soát: Trigger thực hiện các tác vụ mà người dùng không thấy được, điều này có thể dẫn đến việc khó theo dõi khi xảy ra sự cố.

Câu hỏi thường gặp về trigger trong SQL

Điểm khác biệt giữa trigger và transaction là gì?

Trigger là một cơ chế tự động thực thi khi có sự thay đổi trong cơ sở dữ liệu, nhưng không thể được gọi thủ công và không nhận tham số. Trong khi đó, Transaction là một khối các câu lệnh SQL có thể được điều khiển thủ công, cho phép người dùng thực hiện commit hoặc rollback để đảm bảo tính toàn vẹn dữ liệu.

Có thể tạo nhiều Trigger cho cùng một sự kiện không?

Có thể, hầu hết các hệ quản trị cơ sở dữ liệu cho phép tạo nhiều trigger cho cùng một sự kiện. Tuy nhiên, việc này có thể làm phức tạp quản lý và giảm hiệu suất, nên cần sử dụng cẩn thận.

Trigger có ảnh hưởng đến hiệu suất của cơ sở dữ liệu không?

Có, sử dụng nhiều triggers phức tạp có thể làm chậm hiệu suất, đặc biệt khi áp dụng trên các bảng lớn. Để tránh tác động tiêu cực, nên sử dụng trigger một cách cẩn trọng và tối ưu hóa các thao tác bên trong trigger với một số phương pháp như:

  • Giữ logic trigger đơn giản và ngắn gọn: Chỉ thực hiện các tác vụ thật sự cần thiết bên trong trigger và tránh viết các đoạn mã phức tạp hoặc các truy vấn nặng làm tăng thời gian thực thi.
  • Chỉ kích hoạt trigger trên các sự kiện cụ thể và đối tượng cần thiết: Giới hạn trigger để chỉ kích hoạt khi cần thiết và chỉ áp dụng trigger trên các bảng thực sự cần theo dõi thay đổi.
  • Vô hiệu hóa những trigger dư thừa, không còn được sử dụng.
  • Sử dụng bảng tạm hoặc xử lý ngoài trigger khi cần: Thay vì xử lý toàn bộ logic bên trong trigger, có thể ghi dữ liệu vào một bảng tạm và xử lý thông qua tác vụ bên ngoài để giảm tải công việc trực tiếp trên trigger.

Tổng kết Trigger trong SQL

Trigger trong SQL là một công cụ hữu ích để tự động hóa các tác vụ và duy trì tính toàn vẹn dữ liệu trong cơ sở dữ liệu. Tuy nhiên, cần lưu ý về các hạn chế và tác động đến hiệu suất khi sử dụng. Khi sử dụng đúng cách, trigger sẽ giúp bạn quản lý cơ sở dữ liệu hiệu quả hơn và giảm thiểu lỗi trong quá trình thao tác với dữ liệu. 

Cùng tìm hiểu thêm về các chủ đề khác thuộc SQL: