2013-12-10 11 views
5

Tôi đang cố tạo trình kích hoạt thực hiện ba việc: 1. Ngăn xóa dữ liệu trên một bảng cụ thể 2. Tạo thông báo lỗi cho người dùng 3. Ghi lại dữ liệu đã được cố gắng xóa cùng với thông tin phiên từ SQL.Trình kích hoạt để tăng lỗi, tránh xóa và kiểm tra nỗ lực

Đây là mã tôi có cho đến nay:

CREATE TRIGGER [dbo].[MyTable_prevent_delete_and_audit] 
ON [dbo].[MyTable] 
INSTEAD OF DELETE AS 
     BEGIN 
      DECLARE @SESSIONINFO nvarchar(200) 
      SELECT @SESSIONINFO = (RTRIM(LTRIM(CAST(login_time as nvarchar(20)))) + ' ' 
      + RTRIM(LTRIM(hostname)) + ' ' + RTRIM(LTRIM(program_name)) + ' ' 
      + RTRIM(LTRIM(cmd)) + ' ' + RTRIM(LTRIM(loginame))) from sys.sysprocesses WHERE spid = @@SPID 
      INSERT INTO [dbo].[MyTable_AUDIT] ([Field1],[Field1],[SESSIONINFO]) 
      SELECT [Field1],[Field1],@SESSIONINFO FROM deleted 
      RAISERROR ('Removing MyTable entries prevented by trigger. Contact your administrator', 16, 1) 
     END 
     RETURN 
GO 

Đoạn mã trên có thể ngăn chặn việc xóa, và nâng cao lỗi cho người dùng. Tuy nhiên, không có gì được đưa vào bảng kiểm toán. Nếu tôi nhận xét ra dòng RAISEERROR, trigger sẽ thêm đúng các mục vào bảng kiểm toán, nhưng tất nhiên dữ liệu sẽ bị xóa. Tôi nghĩ rằng tôi đã có được một cái gì đó thiếu đơn giản (bị xóa không có sẵn nếu tôi đang nâng cao một lỗi?), Hoặc hiểu lầm một số yếu tố của khái niệm này. Xin cho tôi xem lỗi của tôi! :)

Chỉnh sửa: Aaron Bertrand có câu trả lời đúng, tôi phải cam kết dữ liệu kiểm tra của mình trước khi tăng lỗi. RAISERROR về cơ bản cuộn mọi thứ trở lại, bao gồm cả việc kiểm tra:

CREATE TRIGGER [dbo].[MyTable_prevent_delete_and_audit] 
ON [dbo].[MyTable] 
INSTEAD OF DELETE AS 
     BEGIN 
      DECLARE @SESSIONINFO nvarchar(200) 
      SELECT @SESSIONINFO = (RTRIM(LTRIM(CAST(login_time as nvarchar(20)))) + ' ' 
      + RTRIM(LTRIM(hostname)) + ' ' + RTRIM(LTRIM(program_name)) + ' ' 
      + RTRIM(LTRIM(cmd)) + ' ' + RTRIM(LTRIM(loginame))) from sys.sysprocesses WHERE spid = @@SPID 
      INSERT INTO [dbo].[MyTable_AUDIT] ([Field1],[Field1],[SESSIONINFO]) 
      SELECT [Field1],[Field1],@SESSIONINFO FROM deleted 
      COMMIT TRANSACTION; 
      RAISERROR ('Removing MyTable entries prevented by trigger. Contact your administrator', 16, 1) 
     END 
     RETURN 
GO 
+0

http://stackoverflow.com/questions/3266401/delete-records-within-instead-of-delete-trigger – granadaCoder

Trả lời

4

Hãy thử cam kết INSERT trước khi tăng lỗi. Nếu không, việc tăng lỗi sẽ quay trở lại mọi thứ mà trình kích hoạt đã làm và mọi thứ mà câu lệnh gọi ra trình kích hoạt đã làm.

INSERT INTO [dbo].[MyTable_AUDIT] ([Field1],[Field1],[SESSIONINFO]) 
    SELECT [Field1],[Field1],@SESSIONINFO FROM deleted; 

COMMIT TRANSACTION; 

RAISERROR ('Removing MyTable entries prevented by trigger. ...', 16, 1); 
+0

Đó là nó - tôi cần phải cam kết các dữ liệu trước khi nâng lỗi. Cảm ơn bạn! – cninsd

Các vấn đề liên quan