Monday, May 28, 2007

Trigger trong MySQL

Từ phiên bản 5.0 trở lên MySQL có hỗ trợ Trigger. Sau đây là bản dịch từ tài liệu Online của mysql.com
Syntax:
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt
Để có thể tạo trigger thì user phải có quyền tạo trigger (tất nhiên rùi :)) )

Trigger chỉ có thể liên quan tới một bảng tbl_name mà thôi không chấp nhận view hay bảng tạm (temporary table)


Khi tạo trigger thì một
DEFINER sẽ được chỉ ra _ sẽ nói ở phần sau của hướng dẫn nầy.
trigger_time là thời điểm mà trigger sẽ chạy. Có thể là BEFORE hay AFTER để chỉ ra trigger sẽ chạy trước hay sau sự kiện gây ra trigger.

trigger_event
cho biết loại của hành động gây ra trigger, nó có thể thuộc các dạng sau:
  • INSERT: Trigger được kích hoạt khi một dòng mới được insert vào bảng ví dụ khi ta thực thi câu lệnh INSERT, LOAD DATA, hay REPLACE

  • UPDATE: Trigger được kích hoạt khi một dòng được thay đổi ở đây thường là sau khi thực thi câu lệnh UPDATE

  • DELETE: Trigger sẽ được kích hoạt khi một dòng bị xoá từ một bảng, ví dụ thông qua câu lệnh DELETE và REPLACE, Tuy vậy lệnh DROP TABLETRUNCATE trên bảng sẽ không thể kích hoạt trigger được

Một điều quan trọng cần phải hiểu là để kích hoạt trigger thì chỉ cần sự kiện kích hoạt xãy ra. Ta không nên chỉ nhìn vào phần nghĩa đen của câu lệnh, ví dụ để kích hoạt trigger theo insert thì lệnh LOAD DATA cũng có thể kích hoạt trigger được.

Không được có hai trigger cho một bảng của cùng một hành động. ví dụ không được có hai trigger BEFORE UPDATE cho một bảng tuy nhiên có thể có một trigger BEFORE UPDATE và một trigger BEFORE INSERT cho một bảng

Trigger_stmt là một câu lệnh hay tập lệnh thực thi khi trigger chạy. Nếu bạn muốn chạy nhiều câu lệnh thì bạn phải đặt chúng trong cặp từ BEGIN và END.

Hiện tại thì MySQL chưa hỗ trợ trigger mặc định cho khoá ngoại vấn đề nầy có lẽ sẽ được giải quyết nhanh ;) ráng chờ hén.

Ví dụ:
CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);

DELIMITER |

/*
Lệnh DELIMITER là lệnh dùng để định lại kí tự kết thúc câu lệnh.
Trong câu lệnh trên ta định nghĩa lại kí tự kết thúc câu lệnh là
dấu thăng "|" bởi vì trong câu lệnh tạo trigger tiếp sau ta sẽ cần dùng
kí tự ";"
*/

CREATE TRIGGER testref BEFORE INSERT ON test1
FOR EACH ROW BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
END;
|

/* kết thúc câu lệnh đánh dấu "|" */

DELIMITER ;

/* định nghĩa lại kí hiệu kết thúc câu lệnh là ";" */

INSERT INTO test3 (a3) VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL), (NULL), (NULL), (NULL), (NULL);

INSERT INTO test4 (a4) VALUES
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0);

mysql> INSERT INTO test1 VALUES (1), (3), (1), (7), (1), (8), (4), (4);
Query OK, 8 rows affected (0.01 sec)
Records: 8 Duplicates: 0 Warnings: 0

Kết quả:
mysql> SELECT * FROM test1;
+------+
| a1 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 8 |
| 4 |
| 4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test2;
+------+
| a2 |
+------+
| 1 |
| 3 |
| 1 |
| 7 |
| 1 |
| 8 |
| 4 |
| 4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test3;
+----+
| a3 |
+----+
| 2 |
| 5 |
| 6 |
| 9 |
| 10 |
+----+
5 rows in set (0.00 sec)

mysql> SELECT * FROM test4;
+----+------+
| a4 | b4 |
+----+------+
| 1 | 3 |
| 2 | 0 |
| 3 | 1 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
| 7 | 1 |
| 8 | 1 |
| 9 | 0 |
| 10 | 0 |
+----+------+
10 rows in set (0.00 sec)
Bạn truy cập các thành phần của một dòng thông qua từ khoá NEW và OLD, NEW đại diện cho dòng vừa thêm vào (hay sắp thêm vào) và OLD đại diện cho dòng vừa bị xoá (hay sẽ bị xoá). NEW.col_name, OLD.col_name

Bây giờ ta nói về DEFINER : chỉ ra user define trigger. ví dụ ta có thể ghi như sau: DEFINER = CURRENT_USER, hay DEFINER = nha@localhost ....


No comments: