Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tạo một trình kích hoạt “Thay thế cho” trong SQL Server

Khi bạn tạo trình kích hoạt trong SQL Server, bạn có tùy chọn kích hoạt nó cùng với câu lệnh kích hoạt (tức là câu lệnh SQL đã kích hoạt trình kích hoạt) hoặc kích hoạt nó thay thế của tuyên bố đó.

Để kích hoạt trình kích hoạt thay thế của câu lệnh kích hoạt, hãy sử dụng INSTEAD OF đối số.

Điều này trái ngược với việc sử dụng FOR hoặc AFTER tranh luận. Khi bạn sử dụng các đối số đó, trình kích hoạt 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.

Ví dụ

Tạo một bảng mẫu:

CREATE TABLE t1 (
    id int IDENTITY(1,1) NOT NULL,
    c1 int DEFAULT 0,
    c2 int DEFAULT 0,
    c3 int DEFAULT 0
);

Tạo trình kích hoạt:

CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);

Chèn một hàng mẫu:

INSERT INTO t1 (c1, c2, c3) 
VALUES (1, 1, 1);

SELECT * FROM t1;

Đây là những gì chúng tôi có cho đến nay:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 1    |
+------+------+------+------+

Bây giờ chúng ta hãy chạy một UPDATE câu lệnh chống lại bảng (điều này sẽ kích hoạt trình kích hoạt).

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Kết quả:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 2    |
+------+------+------+------+

Như mong đợi, UPDATE câu lệnh trong câu lệnh kích hoạt đã được thay thế bằng câu lệnh trong câu lệnh kích hoạt.

Trình kích hoạt của tôi đã chỉ định rằng bất kỳ khi nào có một nỗ lực cập nhật bảng, hãy cập nhật c3 thay vào đó.

Chỉ chạy khi một cột cụ thể được cập nhật

Bạn cũng có thể sử dụng UPDATE() chức năng chỉ định mã chỉ chạy khi một cột cụ thể được cập nhật.

Ví dụ:chúng tôi có thể thay đổi trình kích hoạt của mình như sau:

ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;

Bây giờ hãy chạy UPDATE trước đó tuyên bố một lần nữa:

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Kết quả:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 3    |
+------+------+------+------+

Một lần nữa, c3 cột được tăng dần.

Tuy nhiên, bây giờ hãy thử 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    | 1    | 1    | 3    |
+------+------+------+------+

Không có gì thay đổi. c3 cột vẫn giữ nguyên.

Thậm chí không phải là c2 cột được cập nhật. Điều này là do, trình kích hoạt vẫn chạy thay vì câu lệnh kích hoạt.

Chạy trình kích hoạt thay vì XÓA

Chúng tôi có thể sửa đổi trình kích hoạt để chạy thay vì bất kỳ DELETE nào tuyên bố.

ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);

Bây giờ, hãy thử xóa tất cả các hàng và sau đó chọn tất cả các hàng từ bảng.

DELETE FROM t1;

SELECT * FROM t1;

Kết quả:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 4    |
+------+------+------+------+

Lưu ý rằng để trình kích hoạt này hoạt động bình thường, tôi phải truy vấn deleted trong trình kích hoạt của tôi (trái ngược với inserted trong các ví dụ trước).

Hai bảng này được tạo và quản lý bởi SQL Server.

deleted bảng lưu trữ bản sao của các hàng bị ảnh hưởng trong khi DELETEUPDATE 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.

inserted bảng lưu trữ bản sao của các hàng bị ảnh hưởng trong khi INSERTUPDATE các câu lệnh. Trong một giao dịch chèn hoặc cập nhật, các hàng mới được thêm vào cả bảng đã chèn 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.

Một số hạn chế cần lưu ý

Bạn có thể xác định tối đa một INSTEAD OF kích hoạt mỗi INSERT , UPDATE hoặc DELETE trên bảng hoặc dạng xem.

Bạn không thể xác định INSTEAD OF kích hoạt trên các chế độ xem có thể cập nhật sử dụng WITH CHECK OPTION .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Toán tử OR Ngắn mạch trong SQL Server

  2. datetime so với smalldatetime trong SQL Server:Sự khác biệt là gì?

  3. Làm cách nào để tạo một thủ tục được lưu trữ sẽ tùy chọn tìm kiếm các cột?

  4. Cách ánh xạ nhiều phân vùng thành một nhóm tệp trong SQL Server (T-SQL)

  5. Yêu cầu không thành công với trạng thái HTTP 401:IN SSRS trái phép