Trong SQL Server, trình kích hoạt là các đối tượng cơ sở dữ liệu sẽ được thực thi bất cứ khi nào một sự kiện kích hoạt xảy ra trên cơ sở dữ liệu hoặc máy chủ. Trình kích hoạt đóng một vai trò quan trọng trong việc đạt được các yêu cầu kinh doanh như cảnh báo những người được nhắm mục tiêu dựa trên điều kiện đạt được, bắt đầu một công việc hoặc các hoạt động khác. Trong bài viết trước về Trình kích hoạt DML, chúng ta đã nói về Trình kích hoạt, các loại Trình kích hoạt và các tùy chọn Trình kích hoạt khác nhau có sẵn cho Trình kích hoạt DML. Trong bài viết này, chúng ta sẽ khám phá các trình kích hoạt SQL DDL và LOGON.
Trình kích hoạt DDL
Kích hoạt DDL có thể được kích hoạt cho nhiều sự kiện Máy chủ hoặc Cơ sở dữ liệu Phạm vi bao gồm cả lệnh DDL và DCL. DDL là viết tắt của Ngôn ngữ Định nghĩa Dữ liệu được sử dụng để CREATE, ALTER, DROP bất kỳ đối tượng nào và DCL là viết tắt của các câu lệnh Ngôn ngữ điều khiển dữ liệu như lệnh GRANT, DENY và REVOKE. Dưới đây là các đặc điểm của SQL DDL Trigger.
- Kích hoạt DDL có thể được tạo ở Cấp cơ sở dữ liệu hoặc cấp phiên bản Máy chủ bao gồm nhiều hoạt động DDL hoặc các hoạt động tương tự DDL, ví dụ:Các lệnh DCL.
- Trình kích hoạt DDL chỉ có thể được gọi hoặc kích hoạt dưới dạng loại Trình kích hoạt CHO hoặc SAU. SQL Server không hỗ trợ INSTEAD OF DDL Trigger và chúng ta có thể biết cách ngăn một số hoạt động DDL thông qua DDL Trigger.
- SQL Server có các chức năng tích hợp như EVENTDATA () và IS_MEMBER () để sử dụng trong các trình kích hoạt DDL nhằm lấy thêm thông tin liên quan đến các sự kiện Trình kích hoạt.
- Hàm EVENTDATA () trả về thông tin chi tiết đầy đủ về các sự kiện trong phạm vi Cơ sở dữ liệu hoặc Máy chủ ở định dạng XML trong phạm vi của bộ kích hoạt DDL hoặc trình kích hoạt Đăng nhập trong phạm vi Cơ sở dữ liệu hoặc Máy chủ. Hàm EVENTDATA () trả về Chi tiết sự kiện đầy đủ cho phiên thực hiện các hoạt động DDL hoặc Đăng nhập. EVENTDATA () trả về các chi tiết bên dưới
- EventType - Loại Sự kiện kích hoạt trình kích hoạt DDL có sẵn trong bảng sys.trigger_event_types.
- PostTime - Thời gian Sự kiện được kích hoạt hoặc đăng.
- SPID - ID phiên của sự kiện.
- ServerName - Tên phiên bản SQL Server mà sự kiện được kích hoạt.
- LoginName - Tên đăng nhập SQL Server đã thực hiện sự kiện.
- UserName - Tên người dùng của Đăng nhập sẽ là dbo theo mặc định.
- DatabaseName - Tên Cơ sở dữ liệu mà dưới đó Trình kích hoạt DDL đã được kích hoạt.
- Tên lược đồ - Tên giản đồ của Đối tượng bị tác động.
- ObjectName - Tên đối tượng bị ảnh hưởng.
- ObjectType - Loại Đối tượng SQL Server như Bảng, Dạng xem, Thủ tục được Lưu trữ.
- TSQLCommand - Tập lệnh T-SQL được thực thi bởi người dùng gọi ra Trình kích hoạt DDL.
- SetOptions - Tùy chọn SET được Người dùng hoặc Khách hàng sử dụng như SSMS trong khi Lệnh TSQLC được thực thi.
- CommandText - Các câu lệnh DDL hoặc DCL thực tế với Sự kiện DDL được chỉ định trong bảng sys.trigger_event_types.
- Hàm IS_MEMBER () trả về liệu người dùng hiện tại có phải là thành viên của nhóm Windows hoặc vai trò của Cơ sở dữ liệu SQL Server hay không.
- Hàm EVENTDATA () trả về thông tin chi tiết đầy đủ về các sự kiện trong phạm vi Cơ sở dữ liệu hoặc Máy chủ ở định dạng XML trong phạm vi của bộ kích hoạt DDL hoặc trình kích hoạt Đăng nhập trong phạm vi Cơ sở dữ liệu hoặc Máy chủ. Hàm EVENTDATA () trả về Chi tiết sự kiện đầy đủ cho phiên thực hiện các hoạt động DDL hoặc Đăng nhập. EVENTDATA () trả về các chi tiết bên dưới
- Hệ thống DMV sys.trigger lưu trữ danh sách tất cả các trình kích hoạt trong phạm vi Cơ sở dữ liệu. Chúng tôi có thể sử dụng truy vấn dưới đây để tìm nạp thông tin chi tiết của tất cả các trình kích hoạt DDL trong phạm vi Cơ sở dữ liệu.
SELECT *
FROM sys.triggers
WHERE type = 'TR';
- Hệ thống DMV sys.server_triggers lưu trữ danh sách tất cả các trình kích hoạt trong phạm vi Máy chủ và chúng tôi có thể sử dụng truy vấn dưới đây để tìm nạp thông tin chi tiết về tất cả các trình kích hoạt DDL trong phạm vi Máy chủ.
SELECT *
FROM sys.server_triggers;
- Bạn có thể xem định nghĩa của Trình kích hoạt DDL nếu trình kích hoạt không được mã hóa bằng cách sử dụng bất kỳ tùy chọn nào dưới đây từ sys.sql_modules hoặc sử dụng hàm OBJECT_DEFINITION () hoặc sử dụng quy trình lưu trữ sp_helptext.
SELECT OBJECT_SCHEMA_NAME(object_id, db_id()) Schema_name, OBJECT_NAME(object_id) Trigger_Name, definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID(<trigger_name>);
SELECT OBJECT_DEFINITION (OBJECT_ID(<trigger_name>)) AS ObjectDefinition;
EXEC sp_helptext '<trigger_name>';
- Tất cả các Sự kiện DDL có thể có trong bảng sys.trigger_event_types và bạn có thể xem bằng cách sử dụng truy vấn bên dưới.
SELECT *
FROM sys.trigger_event_types;
Cú pháp của Trình kích hoạt DDL là:
CREATE TRIGGER <trigger_name>
ON < ALL SERVER | DATABASE >
[ WITH <DDL_trigger_option> [ ,...n ] ]
{ FOR | AFTER } <event_type>
AS { sql_statement | EXTERNAL NAME <method specifier> }
Tạo trình kích hoạt DDL theo phạm vi cơ sở dữ liệu
Hãy tạo trình kích hoạt Phạm vi cơ sở dữ liệu để theo dõi tất cả các Tạo bảng và đăng nhập vào bảng Ghi nhật ký có tên Track_DDL_Changes bằng cách sử dụng tập lệnh bên dưới.
CREATE TABLE Track_DDL_Changes (EventData xml, PostDtm datetime)
GO
CREATE TRIGGER TR_D_CREATETABLE
ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
INSERT INTO Track_DDL_Changes
SELECT EVENTDATA(),GETDATE()
END
GO
Hãy tạo một bảng mới có tên trigger_test và xác minh xem sự kiện CREATE TABLE đã được kiểm tra hay chưa bằng cách sử dụng tập lệnh bên dưới.
CREATE TABLE Trigger_Test ( a int, b datetime);
Việc chọn dữ liệu từ bảng Track_DDL_Changes cho thấy sự kiện CREATE_TABLE ở trên đã được ghi lại thành công như được hiển thị bên dưới:
Việc nhấp vào giá trị EventData sẽ mở ra giá trị XML EVENTDATA () trong một cửa sổ mới như được hiển thị bên dưới.
Chúng tôi có thể xác minh thông tin chi tiết đầy đủ về sự kiện kích hoạt thông qua hàm EVENTDATA () và do đó hàm EVENTDATA () sẽ đóng một vai trò quan trọng đối với bất kỳ trình kích hoạt DDL hoặc LOGON nào.
Chúng tôi có thể nâng cao hơn nữa Trình kích hoạt DDL của mình với sự trợ giúp của hàm EVENTDATA () và phân tích cú pháp XML và ngăn không cho bất kỳ ai tạo bất kỳ bảng nào trong cơ sở dữ liệu thử nghiệm bằng cách sử dụng tập lệnh được cung cấp bên dưới:
CREATE TRIGGER TR_D_PREVENT_CREATETABLE
ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
SELECT EVENTDATA().value
('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
RAISERROR ('Creation of New tables restricted in this database, Kindly contact DBA.', 16, 1)
ROLLBACK
END
GO
Tạo trình kích hoạt Phạm vi cơ sở dữ liệu đã hoàn tất thành công và hãy xác minh bằng cách tạo một bảng khác bằng cách sử dụng tập lệnh bên dưới.
CREATE TABLE Trigger_Test1 (a int, b datetime);
Trình kích hoạt đã ngăn chúng tôi tạo các bảng mới trên cơ sở dữ liệu này và cũng để lại một thông điệp có ý nghĩa cho người dùng. Tương tự, chúng tôi có thể xử lý bất kỳ sự kiện DDL hoặc phạm vi Máy chủ nào khác để phù hợp với yêu cầu.
Để loại bỏ trình kích hoạt DDL trong phạm vi cơ sở dữ liệu, chúng ta cần sử dụng cú pháp dưới đây:
DROP TRIGGER <trigger_name> ON DATABASE;
Và để loại bỏ trình kích hoạt mà chúng tôi đã tạo ngay bây giờ, tập lệnh sẽ là
DROP TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
Để xem các kích hoạt DDL trong phạm vi cơ sở dữ liệu trong SSMS, hãy mở rộng Cơ sở dữ liệu thử nghiệm -> Khả năng lập trình -> Kích hoạt cơ sở dữ liệu như được hiển thị bên dưới.
Tương tự như Trình kích hoạt DML SQL, Trình kích hoạt DDL có thể bị loại bỏ, tắt hoặc bật bằng cách chỉ cần nhấp chuột phải vào tên Trình kích hoạt như được hiển thị bên dưới.
Thông qua T-SQL, chúng ta có thể bỏ hoặc tắt hoặc bật trình kích hoạt DDL trong phạm vi cơ sở dữ liệu bằng cú pháp dưới đây:
-- DROP Database scoped DDL Trigger
DROP TRIGGER <trigger_name> ON DATABASE;
-- Enable Database scoped DDL Trigger
ENABLE TRIGGER <trigger_name> ON DATABASE;
-- Disable Database scoped DDL Trigger
DISABLE TRIGGER <trigger_name> ON DATABASE;
Để tắt trình kích hoạt mà chúng tôi đã tạo, chúng tôi có thể cần sử dụng tập lệnh bên dưới.
-- DROP Database scoped DDL Trigger
DROP TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
-- Enable Database scoped DDL Trigger
ENABLE TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
-- Disable Database scoped DDL Trigger
DISABLE TRIGGER TR_D_PREVENT_CREATETABLE ON DATABASE;
Tạo trình kích hoạt DDL trong phạm vi máy chủ
Kích hoạt DDL phạm vi máy chủ tuân theo cú pháp tương tự như kích hoạt DDL phạm vi cơ sở dữ liệu ngoại trừ các sự kiện sẽ dựa trên phạm vi Máy chủ.
Hãy thử tạo trình kích hoạt DDL trong phạm vi máy chủ để ngăn bất kỳ người dùng nào tạo cơ sở dữ liệu mới trên phiên bản máy chủ này bằng cách sử dụng tập lệnh bên dưới.
CREATE TRIGGER TR_S_PREVENT_CREATEDATABASE
ON ALL SERVER
FOR CREATE_DATABASE
AS
BEGIN
SELECT EVENTDATA().value
('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
RAISERROR ('Creation of New Databases restricted in this Instance, Kindly contact DBA.', 16, 1)
ROLLBACK
END
GO
Khi cố gắng tạo cơ sở dữ liệu mới bằng lệnh dưới đây, chúng tôi sẽ nhận được lỗi như hình dưới đây.
CREATE DATABASE DATABASE_TEST;
Trong SSMS, Trình kích hoạt DDL có phạm vi máy chủ trong Trình kích hoạt trong phần Đối tượng máy chủ như được hiển thị bên dưới.
Chúng tôi có thể bỏ, tắt hoặc bật trình kích hoạt DDL phạm vi máy chủ bằng cách chỉ cần nhấp chuột phải vào Trình kích hoạt DDL phạm vi máy chủ như được hiển thị bên dưới.
Thông qua T-SQL, chúng ta có thể Thả hoặc Tắt hoặc Bật bằng lệnh dưới đây.
-- DROP Server scoped DDL Trigger
DROP TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;
-- Disable Server scoped DDL Trigger
DISABLE TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;
-- Enable Server scoped DDL Trigger
ENABLE TRIGGER TR_S_PREVENT_CREATEDATABASE ON ALL SERVER;
Mục đích của Trình kích hoạt DDL
- Để kiểm tra bất kỳ sự kiện DDL nào xảy ra trên cấp cơ sở dữ liệu hoặc máy chủ.
- Để ngăn bất kỳ sự kiện DDL nào xảy ra trên cấp cơ sở dữ liệu hoặc máy chủ.
- Để cảnh báo bất cứ khi nào có bất kỳ sự kiện DDL nào xảy ra trên cấp cơ sở dữ liệu hoặc máy chủ.
Kích hoạt đăng nhập
Kích hoạt đăng nhập như tên chỉ ra được thực thi cho các sự kiện LOGON trong SQL Server. Khi giai đoạn Xác thực hoàn tất cho sự kiện Đăng nhập, tập lệnh Kích hoạt LOGON sẽ được thực thi ngoài hoạt động Đăng nhập. Nếu đăng nhập không được xác thực thành công, thì trình kích hoạt LOGON sẽ không được kích hoạt. Trình kích hoạt đăng nhập sẽ được liệt kê trong SSMS dưới phần Kích hoạt của Đối tượng máy chủ. Cú pháp của Trình kích hoạt LOGON như sau:
CREATE TRIGGER <schema_name.trigger_name>
ON ALL SERVER
{ FOR| AFTER } LOGON
AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier > [ ; ] }
Tạo trình kích hoạt
Hãy tạo một trình kích hoạt LOGON đơn giản để nắm bắt thêm thông tin về sự kiện LOGON từ hàm EVENTDATA () như được hiển thị bên dưới.
CREATE TABLE Track_LOGON_EVENTS (EventData xml, PostDtm datetime)
GO
CREATE TRIGGER TR_LOGON
ON ALL SERVER
FOR LOGON
AS
BEGIN
INSERT INTO Track_LOGON_EVENTS
SELECT EVENTDATA(),GETDATE();
END
GO
Trình kích hoạt LOGON ở trên sẽ nắm bắt tất cả chi tiết về hoạt động đăng nhập tương tự như những gì chúng tôi đã nhận thấy khi sử dụng hàm EVENTDATA () trong Trình kích hoạt DDL. Chúng ta nên cẩn thận khi lập kế hoạch sử dụng trình kích hoạt LOGON vì nếu có bất kỳ lỗi logic nào bên trong trình kích hoạt, nó sẽ không cho phép bất kỳ ai hoặc hầu hết người dùng kết nối với phiên bản của SQL Server.
Để DROP, Tắt hoặc Bật trình kích hoạt LOGON, chúng ta có thể sử dụng tập lệnh bên dưới.
-- DROP LOGON Trigger
DROP TRIGGER TR_LOGON ON ALL SERVER;
-- Disable LOGON Trigger
DISABLE TRIGGER TR_LOGON ON ALL SERVER;
-- Enable LOGON Trigger
ENABLE TRIGGER TR_LOGON ON ALL SERVER;
Mục đích của Trình kích hoạt LOGON
- Để kiểm tra mọi sự kiện LOGON đang diễn ra trên máy chủ.
- Để ngăn chặn bất kỳ sự kiện LOGON nào xảy ra trên máy chủ
- Để cảnh báo bất cứ khi nào có bất kỳ sự kiện LOGON nào xảy ra trên máy chủ.
Thuộc tính trình kích hoạt
sp_settriggerorder
sp_settriggerorder được sử dụng để xác định thứ tự thực thi trình kích hoạt chỉ cho trình kích hoạt đầu tiên và cuối cùng. Nếu có nhiều hơn 2 trình kích hoạt DML trong một bảng, giả sử có 5 trình kích hoạt DML, thì chúng tôi có thể xác định trình kích hoạt DML đầu tiên và trình kích hoạt DML cuối cùng nhưng không thể xác định thứ tự của 3 trình kích hoạt ở giữa.
Lưu ý: Đặt tùy chọn ĐẦU TIÊN hoặc CUỐI CÙNG dành riêng cho một danh mục Sự kiện cụ thể cho trình kích hoạt DML. Ví dụ trong một bảng có 3 trình kích hoạt CHÈN, chúng ta có thể xác định trình kích hoạt CHÈN nào là ĐẦU TIÊN và trình kích hoạt CHÈN nào là CUỐI CÙNG. Nếu bạn có 3 trình kích hoạt trên một bảng như CHÈN, CẬP NHẬT và XÓA, thì không cần đặt điều kiện thứ tự Kích hoạt.
Cú pháp để thiết lập thứ tự kích hoạt sẽ như sau:
exec sp_settriggerorder @triggername = '<trigger_schema_name.trigger_name>'
, @order = 'FIRST' | 'LAST'
, @stmttype = '<trigger event type>'
, @namespace = 'DATABASE' | 'SERVER' | 'NULL'
Đối với trình kích hoạt DDL, chúng ta có thể xác định trình kích hoạt Phạm vi máy chủ đầu tiên và cuối cùng, sau đó xác định trình kích hoạt Phạm vi cơ sở dữ liệu đầu tiên và cuối cùng. Ví dụ:nếu chúng ta có 5 trình kích hoạt Phạm vi máy chủ và 5 trình kích hoạt Phạm vi cơ sở dữ liệu, thì thứ tự có thể được xác định như sau:
- Kích hoạt đầu tiên cho trình kích hoạt DDL trong phạm vi máy chủ
- 3 kích hoạt DDL có phạm vi máy chủ khác theo thứ tự ngẫu nhiên
- Lần kích hoạt cuối cùng cho lần kích hoạt DDL trong phạm vi máy chủ.
- Kích hoạt đầu tiên cho trình kích hoạt DDL có phạm vi cơ sở dữ liệu (Một trên mỗi cơ sở dữ liệu)
- 3 Kích hoạt DDL có phạm vi cơ sở dữ liệu khác theo thứ tự ngẫu nhiên
- Kích hoạt cuối cùng cho trình kích hoạt DDL có phạm vi cơ sở dữ liệu.
Đối với việc đặt tùy chọn đầu tiên hoặc tùy chọn cuối cùng, các trình kích hoạt DDL trong phạm vi cơ sở dữ liệu có thể được sắp xếp trong cơ sở dữ liệu và các Kích hoạt DDL trong phạm vi Máy chủ ở cấp Phiên bản.
Mặc dù SQL Server cho phép chúng tôi tạo nhiều trình kích hoạt trên một bảng, nhưng chúng tôi khuyên bạn nên phân tích các yêu cầu của trình kích hoạt một cách cẩn thận để bảo trì và khắc phục sự cố tốt hơn.
Trình kích hoạt đệ quy
SQL Server cũng hỗ trợ gọi các trình kích hoạt một cách đệ quy cho các trình kích hoạt DML. Trình kích hoạt đệ quy có thể được phân loại là trực tiếp hoặc gián tiếp như hình dưới đây.
Trình kích hoạt đệ quy trực tiếp - Người dùng hoặc Ứng dụng cập nhật bản ghi trong Bảng A. CẬP NHẬT Kích hoạt A trong Bảng A được kích hoạt và cập nhật lại Bảng A. Vì bản ghi trong Bảng A đã được cập nhật qua Trình kích hoạt, nó sẽ lại gọi CẬP NHẬT Kích hoạt A và điều này sẽ xảy ra một cách đệ quy.
Hãy tạo Trình kích hoạt đệ quy trực tiếp trên bảng Bán hàng bằng cách sử dụng tập lệnh dưới đây:
CREATE TRIGGER TR_UPD_Recursive_Sales ON Sales
FOR UPDATE
AS
BEGIN
UPDATE Sales
SET SalesDate = GETDATE()
WHERE SalesId = (SELECT SalesId FROM Inserted)
END
GO
Thực thi tập lệnh dưới đây:
UPDATE Sales
SET SalesDate = GETDATE()
WHERE SalesId = 3;
Trình kích hoạt đệ quy gián tiếp - Người dùng hoặc Ứng dụng cập nhật bản ghi trong Bảng A. Trình kích hoạt CẬP NHẬT A trong Bảng A được kích hoạt và cập nhật bản ghi trong Bảng B. Nếu Bảng B có trình kích hoạt CẬP NHẬT để cập nhật bản ghi trở lại Bảng A, nó sẽ gọi trình kích hoạt CẬP NHẬT trong Bảng A sẽ diễn ra một cách đệ quy.
Hãy tạo một Trình kích hoạt đệ quy gián tiếp trên bảng IDR_Test1 và IDR_Test2 bằng cách sử dụng tập lệnh dưới đây:
DROP TABLE IDR_Test1
DROP TABLE IDR_Test2
CREATE TABLE IDR_Test1 (PK int NOT NULL);
GO
INSERT INTO IDR_Test1
values (10),(20)
GO
CREATE TABLE IDR_Test2 (PK int NOT NULL);
GO
INSERT INTO IDR_Test2
values (10),(20)
GO
CREATE TRIGGER TR_IDR_Test1
ON IDR_Test1
FOR UPDATE
AS
BEGIN
UPDATE IDR_Test2
SET PK = 30
WHERE PK IN (SELECT PK FROM inserted);
END
GO
CREATE TRIGGER TR_Temp2
ON IDR_Test2
FOR UPDATE
AS
BEGIN
UPDATE IDR_Test1
SET PK = 30
WHERE PK IN (SELECT PK FROM inserted);
END
GO
Thực thi tập lệnh dưới đây:
UPDATE IDR_Test1
SET PK = 1
WHERE PK = 10;
Để tránh những loại kích hoạt đệ quy này ở cấp Cơ sở dữ liệu, SQL Server có một tùy chọn được gọi là RECURSIVE_TRIGGERS ở mọi cấp cơ sở dữ liệu để phá vỡ kích hoạt Trình kích hoạt đệ quy. Theo mặc định, tùy chọn kích hoạt đệ quy được đặt thành Sai cho cơ sở dữ liệu. Chỉ bật theo yêu cầu sau khi xem xét cẩn thận các tác động đến hiệu suất hoặc các thay đổi dữ liệu liên quan.
Trong SSMS, nhấp chuột phải vào Cơ sở dữ liệu thử nghiệm của chúng tôi -> Chọn Thuộc tính -> Nhấp vào Tùy chọn và cuộn xuống để xem tùy chọn Trình kích hoạt đệ quy được bật hay không như hình bên dưới. Đối với Cơ sở dữ liệu thử nghiệm, nó được đặt thành Sai vì Sai là giá trị mặc định cho tùy chọn Trình kích hoạt đệ quy. Để bật tùy chọn Trình kích hoạt đệ quy cho một cơ sở dữ liệu cụ thể, chỉ cần nhấp vào giá trị thả xuống, thay đổi thành Đúng và nhấp vào OK.
Thông qua T-SQL, chúng tôi có thể xác minh tùy chọn Kích hoạt đệ quy của cơ sở dữ liệu Kiểm tra bằng cách kiểm tra cột is_recursive_triggers_on từ sys.databases DMV như được hiển thị bên dưới.
select name, is_recursive_triggers_on
from sys.databases
where name = 'test'
Để thay đổi tùy chọn Trình kích hoạt đệ quy cho cơ sở dữ liệu (Kiểm tra trong ví dụ của tôi), chúng tôi có thể thực thi tập lệnh bên dưới.
ALTER DATABASE [Test] SET RECURSIVE_TRIGGERS ON WITH NO_WAIT
GO
Để vô hiệu hóa nó trở lại trạng thái sai (trạng thái mặc định) cho cơ sở dữ liệu (Kiểm tra trong ví dụ của tôi), hãy thực thi tập lệnh bên dưới.
ALTER DATABASE [Test] SET RECURSIVE_TRIGGERS OFF WITH NO_WAIT
GO
Trình kích hoạt lồng nhau
Trình kích hoạt đệ quy là một ví dụ cổ điển về Trình kích hoạt lồng nhau nhưng có thể có một số trường hợp khác dẫn đến việc lồng nhiều trình kích hoạt. SQL Server cho phép lồng các trình kích hoạt xuống tối đa 32 cấp và bất kỳ trình kích hoạt nào vượt quá mức lồng đó sẽ bị SQL Server hủy bỏ. SQL Server có cấu hình toàn phiên bản để tắt tùy chọn trình kích hoạt lồng nhau. Xin lưu ý rằng việc lồng SQL Server kích hoạt sử dụng mã CLR hoặc mã được quản lý không nằm dưới giới hạn 32 cấp vì nó nằm ngoài phạm vi của SQL Server. Theo mặc định, tùy chọn trình kích hoạt lồng nhau sẽ được bật trên tất cả các phiên bản SQL Server và chúng tôi có thể tắt tùy chọn này theo yêu cầu.
Chúng tôi có thể xác minh xem tùy chọn trình kích hoạt lồng nhau có được bật ở cấp phiên bản trong SSMS hay không bằng cách thực hiện theo các bước bên dưới:
Nhấp chuột phải vào Máy chủ -> Chọn Thuộc tính -> Nhấp vào Nâng cao
Để tắt hoặc tắt tùy chọn trình kích hoạt lồng nhau, hãy nhấp vào trình đơn thả xuống và thay đổi nó thành Sai và nhấp vào OK .
Thông qua T-SQL, chúng tôi có thể xác minh xem tùy chọn Trình kích hoạt lồng nhau có được bật hay không bằng cách kiểm tra cột value_in_use trong DMV sys.configurations để biết tên cấu hình trình kích hoạt lồng nhau.
Để tắt tùy chọn này, chúng ta cần sử dụng sp_configure quy trình hệ thống được lưu trữ như được hiển thị bên dưới:
EXEC sp_configure 'nested triggers', 0;
GO
RECONFIGURE;
GO
Trong bất kỳ trình kích hoạt DML hoặc DDL nào, để tìm cấp độ lồng nhau hiện tại Máy chủ SQL có một hàm tích hợp có tên TRIGGER_NESTLEVEL để trả về số trình kích hoạt được thực thi cho câu lệnh hiện tại đã kích hoạt trình kích hoạt bao gồm cả chính nó. Cú pháp của hàm TRIGGER_NESTLEVEL sẽ là:
SELECT TRIGGER_NESTLEVEL ( object_id, <trigger_type> , <trigger_event_category> )
Trong đó object_id là id đối tượng của trình kích hoạt, trigger_type sẽ là SAU cho trình kích hoạt SAU và IOT cho trình kích hoạt INSTEAD OF và trigger_event_category sẽ là DML hoặc DDL.
Ví dụ:nếu chúng ta chỉ cần cho phép cấp độ lồng nhau đến 10 và tăng lỗi sau 10 cấp, thì chúng ta có thể thực hiện điều đó trên trình kích hoạt thử nghiệm như sau:
IF ((SELECT TRIGGER_NESTLEVEL(OBJECT_ID('test_trigger'), 'AFTER’, 'DML’)) > 10)
RAISERROR ('Trigger test_trigger nested more than 10 levels.',16, -1)
TIẾP CẬN
Để mã hóa định nghĩa hoặc logic trình kích hoạt, tùy chọn WITH ENCRYPTION có thể được sử dụng trong định nghĩa trình kích hoạt tương tự như tất cả các đối tượng SQL Server khác.
Điều khoản EXECUTE AS
Để thực thi trình kích hoạt bằng cách sử dụng ngữ cảnh bảo mật cụ thể, mệnh đề EXECUTE AS có thể được sử dụng trong định nghĩa trình kích hoạt.
KHÔNG ĐỂ THAY THẾ
Để xác định rằng trình kích hoạt DML sẽ không được gọi trong khi thực thi thông qua các thay đổi sao chép, thuộc tính NOT FOR REPLICATION sẽ được đặt cho tất cả các đối tượng trong cơ sở dữ liệu người đăng ký.
Kết luận
Cảm ơn bạn đã xem qua bài viết đầy sức mạnh về Trình kích hoạt DDL và Trình kích hoạt đăng nhập, nơi chúng tôi đã hiểu mục đích của trình kích hoạt DDL và Logon, cách tạo hoặc thả, tắt hoặc bật các trình kích hoạt này cùng với cách sử dụng hàm EVENTDATA () cho theo dõi các hoạt động DDL hoặc Logon. Ngoài ra, chúng tôi đã tìm hiểu cách đặt thứ tự Thực thi của nhiều trình kích hoạt DML hoặc DDL SQL cùng với trình kích hoạt Đệ quy và Lồng nhau một cách chi tiết và cách xử lý các trình kích hoạt Đệ quy hoặc Lồng nhau một cách cẩn thận.