SQL Server có UPDATE()
mà bạn có thể sử dụng trong trình kích hoạt DML của mình để kiểm tra xem một cột cụ thể đã được cập nhật hay chưa.
Mặc dù hàm này chỉ chấp nhận một cột, nhưng không có gì ngăn bạn bao gồm nhiều UPDATE()
mệnh đề với AND
hoặc OR
để kiểm tra cập nhật nhiều cột.
Ví dụ
Đây là bảng:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0,
c4 int DEFAULT 0
);
Và đây là trình kích hoạt:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) OR UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Trong trường hợp này, c4
cột sẽ chỉ tăng lên nếu c1
hoặc c2
các cột đã được cập nhật. Điều này sẽ xảy ra ngay cả khi chỉ một trong hai cột đó được cập nhật (do tôi sử dụng OR
trái ngược với AND
).
Bây giờ, hãy kiểm tra trình kích hoạt bằng cách chèn dữ liệu vào c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Kết quả:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Như mong đợi, c4
cũng được cập nhật khi c1
đã được cập nhật.
Điều này cũng áp dụng bất cứ khi nào c2
được cập nhật.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
Và tất nhiên, nó cũng sẽ áp dụng khi cả hai đều được cập nhật.
Tuy nhiên, nó sẽ không áp dụng nếu chúng tôi cập nhật c3
(nhưng không phải c1
hoặc c2
).
UPDATE t1
SET c3 = c3 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 1 | 2 | +------+------+------+------+------+
Yêu cầu cập nhật cả hai cột
Chúng tôi có thể thay đổi OR
thành AND
để chỉ định rằng c4
cột chỉ được cập nhật nếu cả hai c1
và c2
đang được cập nhật.
Hãy thay đổi trình kích hoạt của chúng tôi để chỉ định điều này:
ALTER TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) AND UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Bây giờ hãy cập nhật c1
chỉ.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 2 | 1 | 1 | 2 | +------+------+------+------+------+
Vì vậy, c1
đã được cập nhật như đã chỉ định, nhưng c4
đã không.
Điều tương tự cũng sẽ xảy ra nếu chúng tôi cập nhật c2
nhưng không phải c1
.
Nhưng bây giờ hãy cập nhật cả c1
và c2
.
UPDATE t1
SET c1 = c1 + 1, c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Kết quả:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 3 | 2 | 1 | 3 | +------+------+------+------+------+
Đúng như dự đoán, lần này c4
cũng đã được cập nhật.
Cập nhật không thành công
Điều quan trọng cần lưu ý là UPDATE()
chức năng chỉ cho biết liệu một INSERT
hoặc UPDATE
cố gắng được thực hiện trên một cột cụ thể của bảng hoặc dạng xem. Nó vẫn sẽ trả về true nếu nỗ lực không thành công.
Hàm COLUMNS_UPDATED
Một cách khác để kiểm tra các bản cập nhật trên nhiều cột là sử dụng COLUMNS_UPDATED
chức năng.
Hàm này trả về một varbinary mẫu bit cho biết các cột được chèn hoặc cập nhật của bảng hoặc chế độ xem.
Để biết thêm thông tin, hãy xem tài liệu Microsoft cho COLUMNS_UPDATED
.