Trong SQL Server, bạn có thể sử dụng CREATE TRIGGER
câu lệnh để tạo trình kích hoạt.
Trình kích hoạt là một loại thủ tục được lưu trữ đặc biệt tự động chạy khi một sự kiện xảy ra trong máy chủ cơ sở dữ liệu.
Bạn có thể tạo trình kích hoạt DML, trình kích hoạt DDL hoặc trình kích hoạt đăng nhập.
Bài viết này cung cấp một ví dụ về cách tạo trình kích hoạt DML.
Trình kích hoạt DML là gì?
Trình kích hoạt DML là trình kích hoạt chạy khi người dùng cố gắng sửa đổi dữ liệu thông qua sự kiện ngôn ngữ thao tác dữ liệu (DML).
Các sự kiện DML bao gồm INSERT
, UPDATE
hoặc DELETE
các câu lệnh. Trình kích hoạt DML có thể được sử dụng để thực thi các quy tắc nghiệp vụ và tính toàn vẹn của dữ liệu, truy vấn các bảng khác và bao gồm các câu lệnh T-SQL phức tạp.
Trình kích hoạt và câu lệnh kích hoạt nó được coi là một giao dịch duy nhất, có thể được khôi phục lại từ bên trong trình kích hoạt.
Ví dụ
Dưới đây là một ví dụ để chứng minh cách hoạt động của trình kích hoạt DML.
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Trong ví dụ này, tôi tạo một bảng và tôi cũng tạo một trình kích hoạt sẽ được kích hoạt bất cứ khi nào một hàng được chèn hoặc cập nhật trong bảng đó.
Trong trường hợp này, trình kích hoạt thêm 1 vào c3
cột bất cứ khi nào dữ liệu được chèn hoặc cập nhật.
Tôi đã gọi trình kích hoạt trg_t1
. Tôi đã theo dõi phần đó với ON t1
, có nghĩa là trình kích hoạt sẽ được chạy trên bảng có tên t1
.
Ngoài ra, bạn có thể chỉ định một chế độ xem để trình kích hoạt chạy, mặc dù bạn chỉ có thể tham chiếu một chế độ xem bằng một INSTEAD OF
kích hoạt (trong trường hợp này, thay thế AFTER
với INSTEAD OF
). Ngoài ra, bạn không thể xác định trình kích hoạt DML trên các bảng tạm thời cục bộ hoặc toàn cầu.
AFTER
chỉ định rằng trình kích hoạt DML chỉ kích hoạt khi tất cả các hoạt động được chỉ định trong câu lệnh SQL kích hoạt đã khởi chạy thành công. Ngoài ra, bạn có thể chỉ định FOR
đây.
Một giải pháp thay thế khác là sử dụng INSTEAD OF
, sẽ chạy trình kích hoạt thay thế của câu lệnh SQL kích hoạt. Do đó, điều này sẽ ghi đè các hành động của các câu lệnh kích hoạt.
inserted
Bảng?
Trong trình kích hoạt của mình, tôi có thể tìm ra hàng nào đã được cập nhật bằng cách truy vấn inserted
bảng.
SQL Server tạo và quản lý một bảng được gọi là inserted
, là một bảng tạm thời, thường trú trong bộ nhớ, lưu trữ các bản sao của các hàng bị ảnh hưởng trong khi INSERT
và UPDATE
các câu lệnh. Trong giao dịch chèn hoặc cập nhật, các hàng mới được thêm vào cả inserted
bảng và bảng kích hoạt. Các hàng trong bảng được chèn là bản sao của các hàng mới trong bảng trình kích hoạt.
SQL Server cũng tạo và duy trì một bảng tương tự được gọi là đã xóa, bảng này lưu trữ các bản sao của các hàng bị ảnh hưởng trong quá trình DELETE
và UPDATE
các câu lệnh. Trong khi thực hiện DELETE
hoặc UPDATE
câu lệnh, các hàng bị xóa khỏi bảng trình kích hoạt và được chuyển sang bảng đã xóa.
Chạy trình kích hoạt
Bây giờ bảng và trình kích hoạt của nó đã được tạo, hãy chạy một số câu lệnh SQL sẽ kích hoạt nó.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Kết quả:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 0 | 1 | +------+------+------+------+
Vì vậy, chúng ta có thể thấy rằng trình kích hoạt đã hoạt động như mong đợi. Khi tôi chèn một hàng, tôi chỉ chỉ định một giá trị cho c1
nhưng trình kích hoạt đảm bảo rằng c3
cột cũng đã được cập nhật.
Lưu ý rằng giá trị mặc định cho tất cả các cột là 0
(như được chỉ định khi tôi tạo bảng) và trình kích hoạt đã thêm 1 vào đó.
Hãy thực hiện UPDATE
hoạt động trên cùng một cột.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 0 | 2 | +------+------+------+------+
Một lần nữa, c3
cũng đã được cập nhật bởi trình kích hoạt.
Bây giờ chúng ta hãy cập nhật c2
cột.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 3 | +------+------+------+------+
Vì vậy, một lần nữa, c3
được cập nhật bởi trình kích hoạt.
Trình kích hoạt cụ thể này được kích hoạt bất cứ khi nào bất kỳ cột nào khác trong cùng một hàng được cập nhật.
Bạn cũng có thể sử dụng IF UPDATE(column_name)
để kiểm tra bản cập nhật cho một cột hoặc COLUMNS_UPDATED()
để kiểm tra các bản cập nhật trên nhiều cột.