Trigger trong cơ sở dữ liệu

Bách khoa toàn thư mở Wikipedia
Buớc tưới chuyển hướng Bước tới tìm kiếm

Trình kích hoạt cơ sở dữ liệu (Database Trigger) là mã thủ tục được thực hiện tự động để đáp ứng các sự kiện nhất định trên một bảng hay một khung nhìn (View) cụ thể trong cơ sở dữ liệu. Kích hoạt chủ yếu được sử dụng để duy trì tính toàn vẹn của thông tin trên cơ sở dữ liệu. Ví dụ, khi một bản ghi mới (đại diện cho một nhân viên mới) được thêm vào bảng nhân viên, hồ sơ mới cũng nên được tạo ra trong các bảng thuế, kỳ nghỉ và tiền lương. Các trình kích hoạt cũng có thể được sử dụng để ghi lại dữ liệu lịch sử, ví dụ như để theo dõi mức lương trước đây của nhân viên.

Trigger trong hệ quản trị cơ sở dữ liệu (DBMS)[sửa | sửa mã nguồn]

Đa số các DBMS phổ biến hiện nay đều hỗ trợ Database Trigger, với cú pháp gần như tương tự nhau. Giới hạn của nội dung bài viết này sẽ giới thiệu về Trigger trong hệ quản trị cơ sở dữ liệu MariaDB. MariaDB định nghĩa trigger là một tập hợp các câu lệnh chạy (hoặc kích hoạt) khi một sự kiện được đặt trước xảy ra.

Sự kiện (events)[sửa | sửa mã nguồn]

Sự kiện có thể là INSERT, UPDATE hoặc DELETE. Trigger có thể được thực hiện trước hoặc sau sự kiện. Cho đến phiên bản MariaDB 10.2.3, một bảng có thể chỉ có một bộ kích hoạt được xác định cho mỗi sự kết hợp sự kiện/thời gian (ví dụ: bảng chỉ có thể có một nút kích hoạt trước INSERT).

Lệnh khai báo LOAD DATA INFILE và LOAD XML yêu cầu một trigger INSERT cho mỗi hàng đang được chèn vào.

Câu lệnh REPLACE được thực hiện với các quy trình làm việc sau:

  1. Before Insert - trước khi nhập dữ liệu vào.
  2. Before Delete - trước khi xóa (chỉ khi hàng bị xóa).
  3. After Insert - sau khi nhập liệu
  4. After Delete - sau khi xóa (chỉ khi xóa hàng).
Lưu ý rằng lệnh TRUNCATE TABLE không kích hoạt bất kỳ trigger nào.

Kích hoạt và lỗi (Triggers and Errors)[sửa | sửa mã nguồn]

Với các Engine lưu trữ không giao dịch, nếu câu lệnh BEFORE tạo ra lỗi, tuyên bố sẽ không được thực hiện. Các tuyên bố ảnh hưởng đến nhiều hàng sẽ không thành công trước khi chèn dòng hiện tại. Với các Engine giao dịch, các trình kích hoạt (trigger) được thực hiện trong cùng một thao tác như câu lệnh gọi chúng.

Cú pháp tạo Trigger[sửa | sửa mã nguồn]

1 CREATE [OR REPLACE]
2     [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE}]
3     TRIGGER [IF NOT EXISTS] ten_triger thoi_gian_kich_hoat su_kien
4     ON ten_bang FOR EACH ROW
5     [{FOLLOWS | PRECEDES} ten_khac_trigger]
6     cau_lenh_trigger

Câu lệnh này tạo ra một Trigger mới. Trigger là một đối tượng cơ sở dữ liệu được đặt tên có liên quan đến một bảng và được kích hoạt khi một sự kiện cụ thể xảy ra cho bảng. Kích hoạt sẽ trở thành kết hợp với bảng có tên ten_bang, nó phải tham chiếu đến một bảng vĩnh viễn. Bạn không thể liên kết một Trigger với một bảng TEMPORARY hoặc một View.

Trong đó:
  • OR REPLACE - nếu một Trigger đã tồn tại, thay vì trả lại lỗi. Trigger cũ sẽ được tại thế bằng Trigger mới.
  • DEFINER - mệnh đề DEFINER xác định bối cảnh an toàn được sử dụng khi kiểm tra các đặc quyền truy cập tại thời điểm kích hoạt Trigger.
  • IF NOT EXISTS - chỉ tạo Trigger nếu trước đó nó không tồn tại.
  • thoi_gian_kich_hoat - nó có thể trước hoặc sau để chỉ ra rằng trigger được kích hoạt khi nào khi chúng ta thực hiện sửa đổi hàng.
  • su_kien - có thể là INSERT, UPDATEDELETE.
  • FOLLOWS | PRECEDES ten_trigger-khac - thêm trigger mới trước/sau (PRECEDES/FOLLOWS) trigger khác.
Ví dụ:
Ta có chuỗi câu lệnh tạo bảng như sau:
1 CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
2 name char(30) NOT NULL, 
3 PRIMARY KEY (`id`)
4 );  /* Tạo bảng animals */
5 
6 CREATE TABLE animal_count (animals int); /* Tạo bảng animal_count đếm số lượng của bảng animals */
7 
8 INSERT INTO animal_count (animals) VALUES(0); /* INSERT dữ liệu 0 vào bảng animal_count */
Và các câu lệnh tạo Trigger như sau:
1 CREATE TRIGGER increment_animal AFTER INSERT ON animals 
2 FOR EACH ROW 
3 UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
Ta có:
  • Tên là increment_animal
  • Thời gian xảy ra là AFTER
  • Sự kiện là INSERT cho bảng animals với tập hợp lệnh là lệnh UPDATE
Bây giờ, nếu chúng ta chèn một bản ghi vào bảng động vật, trigger sẽ chạy, ta có kết quả như sau:
SELECT * FROM animal_count;
/* Ta được kết quả */
+---------+
| animals |
+---------+
|       0 |
+---------+

/* insert dữ liệu cho bảng animals */
INSERT INTO animals (name) VALUES('Dog');
INSERT INTO animals (name) VALUES('Cat');

/* Xem bảng animal_count */
SELECT * FROM animal_count;
/* Ta được kết quả */
+---------+
| animals |
+---------+
|       2 |
+---------+

Xóa Trigger (DROP TRIGGER)[sửa | sửa mã nguồn]

Ta sử dụng lệnh sau để xóa trigger:

1 DROP TRIGGER [IF EXISTS] ten_trigger;
Trong đó:
  • DROP TRIGGER - tuyên bố xóa Trigger.
  • IF EXISTS - đưa ra một cảnh báo lỗi khi trigger không được tạo trước đó.
  • ten_trigger - tên của trigger trước đó.
Ví dụ:
1 DROP TRIGGER [IF EXISTS] increment_animal;

Hạn chế của Trigger trong MariaDB[sửa | sửa mã nguồn]

  1. Mỗi bảng có thể chỉ có một Trigger cho mỗi sự kết hợp sự kiện/thời gian (tức là: chúng ta không thể xác định hai trigger INSERT cho cùng một bảng).
  2. Trigger sẽ thực hiện tuần tự trên mỗi hàng.
  3. Các trigger của các DBMS khác nhau có thể sẽ không tương thích với nhau (nếu không sử dụng chung chuẩn SQL).
  4. Không thể trả về kết quả.
  5. Không thể sử dụng lệnh RETURN, vì trigger không trả về giá trị. Ta có thể sử dụng LEAVE để thoát ngay lập tức.
  6. Không được kích hoạt bởi các khóa phụ.

CTUET_DBMS_Group3

Tham khảo[sửa | sửa mã nguồn]