2013-12-10 17 views
5

üç şey yapar bir tetikleyici oluşturmaya çalışıyor koyaCağım: 1. Belirli bir masaya verilerinin silinmesini önler 2. kullanıcı için bir hata mesajı üretir 3. SQL'den oturum bilgisi ile birlikte silinmeye çalışılan verileri kaydeder. Tetik, hata yükseltmek silmek önlemek ve denetim girişimi

Bu

var bugüne kadar kodudur:

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 

Yukarıdaki kod silinmesini önlemek ve kullanıcı için hata yükseltmek yapabiliyor. Bununla birlikte, denetim masasına hiçbir şey girilmemiştir. RAISEERROR satırını açıklarsam, tetiğin doğru şekilde denetim tablosuna öğeler ekler, ancak elbette veriler silinir. Düşünüyorum ki basit bir şey eksik olmalıyım (bir hataya neden olurum varsa silinmez) ya da kavramın bazı unsurlarını yanlış anlamışım. Lütfen bana yollarımın hatasını göster! :)

Düzeltme: Aaron Bertrand'ın doğru cevabı var, hatayı yükseltmeden önce denetim verilerinimi vermem gerekiyor. RAISERROR esas itibariyle denetimden dahil her şeyi geri rulolar:

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

cevap

4

deneyin hatasını artırmadan önce INSERT işlemekle. Aksi takdirde, hatayı yükseltmek tetikleyicinin yaptığı her şeyi geri alır ve tetikleyiciyi çalıştıran ifadeyi yaptı.

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

İşte budur - Ben hata yükselterek önce verileri işlemek için gerekli. Teşekkür ederim! – cninsd