2013-06-11 10 views
8

मैं उपयोगकर्ता मेज पर नीचे की तरह एक ट्रिगर है लूप करने के लिए एक ट्रिगर के अंदर पाश लेखा परीक्षा तालिका में डालने के लिए जो के साथ स्तंभ अद्यतन किया गया था और पिछले मूल्य:जबकि एसक्यूएल में तालिका के सभी स्तंभों

ALTER TRIGGER [dbo].[trgAfterUpdate] ON [dbo].[tbl_User] 
AFTER UPDATE 
AS 


    declare @fieldname varchar(128) ; 
    declare @OldValue varchar(255); 
    declare @CreateUser varchar(100) ; 
    declare @User_Key int; 

    select @CreateUser =i.user_name from deleted i; 
    SELECT @User_Key = i.user_key from inserted i; 

    if update(user_name) 
     begin 
      select @OldValue=j.user_name from deleted j; 
      set @fieldname = 'user_name'; 

      insert into tbl_Audit(user_key, field_name, previuos_Value, user_name) 
      values(@User_Key ,@fieldname,@OldValue, @CreateUser); 

     end 

लेकिन मेरे प्रश्न हैं कि मेरी टेबल पर 100 फ़ील्ड हैं। यदि शर्तें हैं तो मैं 100 नहीं लिख सकता। और मुझे एक सुझाव की आवश्यकता है कि इसमें लूप के दौरान उपयोग कैसे करें, और यह प्रदर्शन को कैसे प्रभावित करेगा।

धन्यवाद

+0

क्यों न सिर्फ इस बात के लिए एक्सएमएल का उपयोग करें? – JNK

+1

क्या आप कृपया विस्तृत कर सकते हैं? मुझे यकीन नहीं है कि एक्सएमएल – user1882705

+0

का उपयोग करके AUDIT तालिका में डालने के लिए कैसे पूरी पंक्ति को 'एक्सएमएल' के जरिये एक्सएमएल में कनवर्ट करें और अपनी ऑडिट तालिका में बस स्टोर और एक्सएमएल कॉलम को कनवर्ट करें। – JNK

उत्तर

15

प्रयास करें इस एक -

ALTER TRIGGER [dbo].[trgAfterUpdate] 

    ON [dbo].[tbl_User] 
    AFTER UPDATE 

AS BEGIN 

    SET NOCOUNT ON 
    SET XACT_ABORT ON 

    DECLARE @DocumentUID UNIQUEIDENTIFIER 

    DECLARE cur CURSOR FORWARD_ONLY READ_ONLY LOCAL FOR 
     SELECT DocumentUID, ... 
     FROM INSERTED 

    OPEN cur 

    FETCH NEXT FROM cur INTO @DocumentUID, ... 

    WHILE @@FETCH_STATUS = 0 BEGIN 

     DECLARE 
       @BeforeChange XML 
      , @AfterChange XML 

     SELECT @BeforeChange = (
      SELECT * 
      FROM DELETED 
      WHERE [DocumentUID] = @DocumentUID 
      FOR XML RAW, ROOT 
     ) 
     , @AfterChange = (
      SELECT * 
      FROM INSERTED 
      WHERE [DocumentUID] = @DocumentUID 
      FOR XML RAW, ROOT 
     ) 

     INSERT INTO dbo.LogUser (DocumentUID, BeforeChange, AfterChange) 
     SELECT @DocumentUID, @BeforeChange, @AfterChange 

     -- your business logic 

     FETCH NEXT FROM cur INTO @DocumentUID, ... 

    END 

    CLOSE cur 
    DEALLOCATE cur 

END 
+0

मुझे पूरी पंक्ति की आवश्यकता नहीं है। मुझे केवल उस फ़ील्ड की आवश्यकता है जिसे संशोधित किया गया है और इसका पिछला मूल्य। हालांकि आपके उत्तर के लिए धन्यवाद ... – user1882705

+0

आपको केवल '@ पहले चेंज' और '@ AfterChange' मानों के बीच अंतर खोजने की आवश्यकता है । – Devart

+0

क्या आप मुझे इन दो एक्सएमएल चरों की तुलना करने का सबसे अच्छा तरीका बता सकते हैं – user1882705

0

इस एक के समान क्वेरी का उपयोग कर प्रयास करें - यह तो उत्पन्न होगा किसी तालिका के सभी स्तंभों के लिए बयान।

नोट: यह पूरी तरह से परीक्षण नहीं किया गया है और शायद अधिक समायोजन की आवश्यकता है लेकिन आप इसके पीछे विचार देखते हैं।

select 'if update(' + C.name + ') 
    begin 
     select @OldValue=j.' + C.name + ' from deleted j; 
     set @fieldname = ''' + C.name + '''; 

     insert into tbl_Audit(user_key, field_name, previuos_Value, user_name) 
     values(@User_Key ,@fieldname,@OldValue, @CreateUser); 
    end' 
from sys.all_columns C 
inner join sys.tables T on C.object_id = T.object_id 
where T.name = 'table_name' and T.schema_id = SCHEMA_ID('schema_name') 

हैं जबकि पाश के साथ नहीं जाना होगा, क्योंकि यह शायद पर्फ़ समस्याएं हो सकती हैं ...

+0

तो आपकी क्वेरी में मुझे बस table_name को मेरे टेबल नाम से प्रतिस्थापित करने की आवश्यकता है जो tbl_User सही है? – user1882705

+0

क्या आप मुझे बता सकते हैं कि इस ट्रिगर को कैसे डिबग करें? यह मेरी मेज पर काम नहीं कर रहा है। – user1882705

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