する:1.特定のテーブルにデータの削除を禁止し 2. は、ユーザー のためのエラーメッセージを生成します3.削除しようとしたデータをSQLのセッション情報とともに記録します。トリガーは、私は3つのことを行い、トリガーを作成しようとしてる、エラーが発生し、削除防止し、及び監査の試み
これは私がこれまで持っているコードです:上記のコードは削除を防止し、ユーザーのためにエラーを発生させることが可能である
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行をコメントアウトすると、トリガーは監査テーブルに項目を正しく追加しますが、もちろんデータは削除されます。私は、単純なものが欠けていなければならないと思っています(私はエラーを起こしているなら削除できませんか?)、または概念のいくつかの要素を誤解しています。私の方法の誤りを私に見せてください! :)
編集:Aaron Bertrandが正しい答えを示しています。エラーを発生させる前に監査データをコミットする必要があります。 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