2013-12-10 11 views
5

मैं एक ट्रिगर जो तीन काम करता है बनाने के प्रयास कर रहा हूँ करने के लिए: 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 

ऊपर कोड हटाए से रोकने के लिए, और उपयोगकर्ता के लिए त्रुटि को बढ़ाने के लिए सक्षम है। हालांकि, ऑडिट तालिका में कभी भी कुछ भी दर्ज नहीं किया जाता है। यदि मैं रायसरर लाइन पर टिप्पणी करता हूं तो ट्रिगर सही ढंग से ऑडिट तालिका में आइटम जोड़ता है, लेकिन निश्चित रूप से डेटा हटा दिया जाता है। मुझे लगता है कि मुझे कुछ सरल याद आना है (अगर मैं कोई त्रुटि उठा रहा हूं तो हटाया नहीं गया है?), या अवधारणा के कुछ तत्वों को गलत समझना। कृपया मुझे अपने तरीकों की त्रुटि दिखाओ! :)

संपादित करें: हारून बर्ट्रैंड का सही उत्तर है, मुझे त्रुटि उठाने से पहले अपना ऑडिट डेटा देना है। 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 
+0

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

उत्तर

4

कोशिश त्रुटि ऊपर उठाने से पहले INSERT करने से। अन्यथा, त्रुटि को उठाकर ट्रिगर ने जो भी किया और सब कुछ जो ट्रिगर को ट्रिगर किया था, वापस ले गया।

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

कि यह था - मैं त्रुटि ऊपर उठाने से पहले डेटा प्रतिबद्ध करने के लिए की जरूरत है। धन्यवाद! – cninsd

संबंधित मुद्दे