我試圖創建一個觸發器,它做了三兩件事:1。 防止數據刪除在特定表 2.爲用戶生成 的錯誤信息3.將嘗試刪除的數據與來自SQL的會話信息一起記錄。觸發募集錯誤,防止刪除和審計嘗試
這是我到目前爲止的代碼:
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
上面的代碼能夠防止刪除,引發錯誤的用戶。但是,任何事都不會被輸入到審計表中。如果我註釋掉RAISEERROR行,觸發器會正確地將項目添加到審計表中,但當然數據將被刪除。我在想我必須缺少一些簡單的東西(如果我提出錯誤,會被刪除不可用?),或者誤解概念的某些元素。請告訴我我的方式的錯誤! :)
編輯:亞倫伯特蘭有正確的答案,我必須在提出錯誤之前提交我的審計數據。該RAISERROR基本捲回的一切,包括審計:
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
http://stackoverflow.com/questions/3266401/delete-records-within-instead-of-delete-trigger – granadaCoder