2008-11-18 13 views
9

में ट्रैकिंग परिवर्तनों को मुझे एक ऐसे समाधान को विकसित करने के लिए कार्य किया गया है जो किसी डेटाबेस में परिवर्तन ट्रैक करता है।SQL सर्वर 2005 डेटाबेस

  • अद्यतन
  • वर्ष मूल्य
  • नया मान
  • क्षेत्र प्रभावित
  • व्यक्ति कर परिवर्तन
  • रिकॉर्ड आईडी
  • तालिका की तारीख:

    अद्यतन के लिए मैं पर कब्जा करने की जरूरत है रिकॉर्ड

  • में है

हटाए लिए:

  • कर नष्ट
  • व्यक्ति की तारीख
  • शीर्षक/विवरण/रिकॉर्ड की आईडी नष्ट कर दिया हटा दें। जिन टेबलों पर मैं ट्रैकिंग कर रहा हूं, उनमें शीर्षक या विवरण फ़ील्ड है। रिकॉर्ड हटा दिए जाने से पहले मैं इसे कैप्चर करना चाहता हूं।
  • तालिका रिकॉर्ड

में था आवेषण के लिए:

  • डालने की तारीख
  • व्यक्ति कर परिवर्तन
  • रिकॉर्ड आईडी
  • तालिका रिकॉर्ड है
  • में

मैं करने के कुछ तरीकों के बारे में सोचा है इस:

  • मैं किसी भी अद्यतन के लिए संग्रहित प्रक्रियाओं का उपयोग कर रहा हूँ/हटाता/आवेषण। मैं एक सामान्य "ट्रैकिंग" तालिका बनाउंगा। इसमें सभी डेटा कैप्चर करने के लिए पर्याप्त फ़ील्ड होंगे। फिर मैं प्रत्येक संग्रहित प्रो में "ट्रैकिंग तालिका में रिकॉर्ड डालने" के प्रभाव में एक और पंक्ति जोड़ूंगा।
    • नकारात्मक पक्ष यह है: सभी अद्यतन// आवेषण सभी एक ही तालिका में गड़बड़ कर रहे हैं हटाने से nulled क्षेत्रों
    • कैसे मैं बैच अद्यतन ट्रैक करते हैं/हटाता/आवेषण के
    • बहुत सारे? < ---- यह कोई मुद्दा नहीं हो सकता है। मैं वास्तव में इस तरह की कोई चीज नहीं करता हूं।
    • मैं उपयोगकर्ता को अद्यतन करने पर कैप्चर कैसे करूं। डेटाबेस सिर्फ एक खाता देखता है।
    • संपादित करने के लिए बहुत सारे मौजूदा कोड संपादित करें।
  • आखिरकार, मैं एक ट्रिगर बना सकता हूं जिसे अपडेट/डिलीट/आवेषण के बाद बुलाया जाता है। पहले समाधान के रूप में एक ही डाउनसाइड्स को छोड़कर: मुझे उतना कोड संपादित करना होगा। मुझे यकीन नहीं है कि मैं अपडेट कैसे ट्रैक करूंगा। ऐसा लगता है कि हाल ही में अपडेट किए गए रिकॉर्ड देखने के लिए ट्रिगर्स का उपयोग करने का कोई तरीका नहीं है।

मैं asp.net, सी #, SQL सर्वर 2005, IIS6, खिड़कियां 2003 उपयोग कर रहा हूँ मैं मैं कुछ भी नहीं खरीद सकते हैं मुझे इस के साथ मदद करने के लिए इतनी उदासी कोई बजट नहीं है।

आपके उत्तरों के लिए धन्यवाद!

उत्तर

4

एक ट्रिगर सभी जानकारी कारणों में से एक गुच्छा के लिए की जरूरत नहीं होती है - लेकिन कोई उपयोगकर्ता आईडी पक्की दलील है ।

मैं कहूंगा कि आप एक सामान्य स्पॉट के साथ सही रास्ते पर हैं जहां कहीं भी बदलाव किया जाता है। यदि आप अपने इंटरफेस के लिए एसपी पर मानकीकृत कर रहे हैं तो आप खेल से आगे हैं - ट्रैक में नहीं आने वाले बदलाव में छेड़छाड़ करना मुश्किल होगा।

इसे एकाउंटिंग एप्लिकेशन में ऑडिट ट्रेल के बराबर के रूप में देखें - यह जर्नल है - प्रत्येक लेनदेन के साथ एक एकल तालिका दर्ज की गई है। वे जमा, निकासी, समायोजन इत्यादि के लिए अलग पत्रिकाओं को लागू नहीं करेंगे और यह वही सिद्धांत है।

4

मुझे इस मुद्दे को साइड-चरण से नफरत है और मुझे पता है कि आपके पास कोई बजट नहीं है, लेकिन सबसे आसान समाधान SQL सर्वर 2008 में अपग्रेड करना होगा। इसमें यह सुविधा built in है। मैंने सोचा कि कम से कम किसी अन्य व्यक्ति के लिए इसका उल्लेख किया जाना चाहिए जो इस प्रश्न में आता है, भले ही आप इसे स्वयं नहीं इस्तेमाल कर सकें।

(SQL 2008 के परिनियोजन योग्य संस्करण के अलावा, इस सुविधा उद्यम में ही उपलब्ध है।)

+0

मैं नहीं दिख रहा है जहां यह प्रयोक्ता आईडी कब्जा - यह क्योंकि logged- कहीं इंजेक्ट किया जा करने के लिए होगा डेटाबेस में उपयोगकर्ता के लिए एक मैच नहीं है। – dkretz

+0

इस बारे में उत्सुक। कोई भी जानता है कि एसक्यूएल 2008 उपयोगकर्ता आईडी कैप्चर करेगा? या यह सिर्फ संभव नहीं है? – pdiddy

1

एक तरीका मैंने इसे संभाला है (हालांकि मैं इसे ईमानदारी से अनुशंसा नहीं करता) इसे उपयोगकर्ता आईडी/उपयोगकर्ता नाम/पैरामीटर के रूप में जो भी हो, संग्रहीत प्रक्रियाओं के माध्यम से इसे संभालना है। संग्रहित प्रक्रिया लॉगिंग प्रक्रिया को कॉल करेगी, जिसने केंद्रीय लॉग तालिका में प्रासंगिक विवरण लिखे थे।

यहाँ है, जहां यह एक सा whacky मिला है हालांकि ...

आवेषण/अद्यतन के लिए, प्रासंगिक पंक्ति (यों) XML डेटा के रूप में तालिका में संग्रहीत एक बार सम्मिलित/अपडेट सफलतापूर्वक पूरा कर लिया था रहे थे। DELETEs के लिए, पंक्ति को DELETE चलने से पहले संग्रहीत किया गया था (हालांकि, वास्तव में, वे इसे DELETE कथन के आउटपुट से प्राप्त कर सकते थे - कम से कम SQL सर्वर 2005 के साथ)।

यदि मुझे सही याद है, तो तालिका में केवल कुछ कॉलम थे: उपयोगकर्ता आईडी, लॉगिंग का दिनांक समय, लेनदेन प्रकार (आई/यू/डी), एक्सएमएल डेटा जिसमें संबंधित पंक्तियां, तालिका का नाम और प्राथमिक कुंजी मान शामिल है (मुख्य रूप से उन रिकॉर्ड्स की त्वरित खोज के लिए प्रयोग किया जाता था जो वे चाहते थे)।

कई एक बिल्ली त्वचा के लिए तरीके, हालांकि ...

मेरी सलाह रखने के लिए सरल है। यदि आपको आवश्यकता हो तो इसे बाद में विस्तृत करें।

यदि आपके पास ऐसा करने की क्षमता है, तो उपयोगकर्ताओं को संग्रहीत प्रक्रियाओं के माध्यम से केवल टेबल पर क्रियाशील कथन करने में सक्षम होने के लिए लॉक करें और फिर वहां से लॉगिंग (हालांकि आप चाहते हैं) को संभालें।

0

हमने अपना खुद का निर्माण किया और केवल उपयोगकर्ता और पीसी को प्रत्येक ऐड/अपडेट संग्रहीत प्रक्रिया में पारित करने की आवश्यकता थी। तो यह मूल रिकॉर्ड एडीएन चर को पॉप्युलेट करने और उन्हें पारित चर में तुलना करने और डेटा को हमारी तालिका में लॉगिंग करने की बात है। हटाए जाने के लिए हमारे पास मूल सारणी + एक टाइमस्टैम्प फ़ील्ड की प्रतिलिपि है, इसलिए रिकॉर्ड कभी भी वास्तव में हटाया नहीं जाता है और जब भी हमें आवश्यकता होती है उसे पुनर्स्थापित किया जा सकता है (स्पष्ट रूप से एफके रिश्तों और इस तरह के डिलीट नियमित जांच)।

जोड़ें/अपडेट करें लॉग तालिका datetime, TABLE_NAME, स्तंभ, record_id, old_value, new_value, user_id, कंप्यूटर

हम nulls इतना सम्मिलित कभी नहीं की तरह लग रहा है कि हम परिवर्तित उन्हें तार खाली करने के लिए, old_value कॉलम में '{new entry}' के साथ नई प्रविष्टियां चिह्नित की जाती हैं। रिकॉर्ड_आईडी एक ही रिकॉर्ड (फ़ील्ड 1 + '।' + फील्ड 2 + ...)

0

सबसे पहले, अपने सभी तालिकाओं में कम से कम इन कॉलमों को डेटा में जोड़ा जाना चाहिए, कॉलम दिनांकित, UserCreated, DateModified, UserModified। संभवतः आप एक "स्थिति" या "अंतिम क्रिया" कॉलम जोड़ना चाहेंगे ताकि आप कभी भी एक पंक्ति को हटा नहीं सकें जिसे आपने इसे हटाए गए/सम्मिलित/अद्यतन स्थिति में सेट किया है। इसके बाद आप एक "इतिहास तालिका" बना सकते हैं जो पहली तालिका की एक सटीक प्रति है। फिर किसी भी अपडेट या डिलीट पर ट्रिगर को हटाए गए तालिका प्रविष्टियों को इतिहास तालिका में दिनांकित, दिनांकित, उपयोगकर्ता संशोधित, और स्थिति फ़ील्ड को एक ही समय में बदलते हैं।

0

मैं एसक्यूएल सर्वर में एक सेटअप जहां हम दृश्यों का उपयोग हमारे डेटा है, जो आवेषण, अपडेट प्रबंधित होगा उपयोग करने के लिए होता है और इसके बजाय ट्रिगर के साथ हटा देता था।

उदाहरण के लिए: एक बजाय दृश्य पर ट्रिगर हटाने के रूप में नष्ट अंतर्निहित तालिका में रिकॉर्ड को चिह्नित करना होगा, और दृश्य हटा रिकॉर्ड नहीं दिखाने के लिए फ़िल्टर किया गया था।

सभी ट्रिगर में, हम एक संशोधन दिनांक और उपयोगकर्ता नाम अपडेट किया गया। समस्या यह है कि डेटाबेस उपयोगकर्ता नाम लॉग करता है, जो कि अंतिम अनुप्रयोग उपयोगकर्ता नाम के समान नहीं है।

दृश्य को काम करने के लिए स्कीमा को बाध्य करने की आवश्यकता है।

0

उपयोगकर्ताओं प्रवेश करने के बारे में है कि बदलता है डीबी: रूप में आप अपने DB के लिए की जरूरत है आप के रूप में कई एसक्यूएल उपयोगकर्ता बना सकते हैं और आप उस जानकारी का उपयोग विभिन्न DB कनेक्शन आरंभ करने के लिए कर सकते हैं अगर आप अपने कार्यक्रम/स्क्रिप्ट के सत्रों और प्रतिबंधित/पंजीकृत पहुँच का उपयोग डीबी के साथ किसी भी ऑपरेशन से पहले सेटिंग्स (यानी उपयोगकर्ता नाम), ।

कम से कम है कि PHP के लिहाज से स्क्रिप्ट के लिए संभव होना चाहिए, लेकिन मैं asp.net के लिए गलत हो सकता है।

3

मैं आपको प्रत्येक तालिका में 2 कॉलम का उपयोग करने का सुझाव दूंगा। नाम rowhistory और isDeleted और डेटा प्रकार एक्सएमएल और बिट किया जाएगा। कभी हुई पंक्तियां हटाना, हमेशा उपयोग झंडा isDeleted अब जाना अद्यतन के साथ चलाता है। मैं तुम्हें मैं इस एक मेज पृष्ठ

CREATE TABLE te_Page([Id] [int] IDENTITY(1,1) NOT NULL, [Name] [varchar](200) NOT NULL, [Description] [varchar](200) NULL,[CreatedBy] [uniqueidentifier] NULL, [CreatedDate] [datetime] NOT NULL, [UpdatedBy] [uniqueidentifier] NULL, [UpdatedDate] [datetime] NULL, [IsDeleted] [bit] NULL, [RowHistory] [xml] NULL, CONSTRAINT [PK_tm_Page] PRIMARY KEY CLUSTERED ([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] 

कहा जाता है एक ही के लिए उदाहरण दे देंगे अब तालिका तुम सब करने की जरूरत है प्रतिलिपि नीचे दिए गए कोड पेस्ट है और अपने कार्य पृष्ठ तालिका के लिए किया जाता है बनाने के बाद। यह उसी पंक्ति में पंक्ति के इतिहास को रिकॉर्ड करना शुरू कर देगा जो पुराने और नए मानों के साथ अपडेट किया गया है।

   ALTER Trigger [dbo].[Trg_Te_Page]  
     On [dbo].[te_Page]     
     After Update     
     As     
     --If @@rowcount = 0 Or Update(RowHistory)  
     --Return  

     Declare @xml NVARCHAR(MAX)  
     Declare @currentxml NVARCHAR(MAX) 
     Declare @node NVARCHAR(MAX)  
     Declare @ishistoryexists XML  

     Declare @FormLineAttributeValueId int 

     -- new Values 
     Declare @new_Name varchar(200) 
     Declare @new_Description varchar(200) 

     Declare @new_CreatedBy UNIQUEIDENTIFIER  
     Declare @new_CreatedDate DATETIME  
     Declare @new_UpdatedBy UNIQUEIDENTIFIER  
     Declare @new_UpdatedDate DATETIME  
     Declare @new_IsDeleted BIT 

     --old values 
     Declare @old_Name varchar(200) 
     Declare @old_Description varchar(200) 

     Declare @old_CreatedBy UNIQUEIDENTIFIER  
     Declare @old_CreatedDate DATETIME  
     Declare @old_UpdatedBy UNIQUEIDENTIFIER  
     Declare @old_UpdatedDate DATETIME  
     Declare @old_IsDeleted BIT 


     -- declare temp fmId 
     Declare @fmId int 
     -- declare cursor 
     DECLARE curFormId cursor 
     FOR select Id from INSERTED 
     -- open cursor  
     OPEN curFormId 
     -- fetch row 
     FETCH NEXT FROM curFormId INTO @fmId 

     WHILE @@FETCH_STATUS = 0 
     BEGIN 

     Select 
     @FormLineAttributeValueId = Id, 
     @old_Name = Name, 
     @old_Description = [Description], 

     @old_CreatedBy = CreatedBy,  
     @old_CreatedDate =CreatedDate, 
     @old_UpdatedBy =UpdatedBy,  
     @old_UpdatedDate =UpdatedDate, 
     @old_IsDeleted = IsDeleted, 
     @currentxml = cast(RowHistory as NVARCHAR(MAX)) 
     From DELETED where [email protected] 



     Select  
     @new_Name = Name, 
     @new_Description = [Description], 

     @new_CreatedBy = CreatedBy,  
     @new_CreatedDate =CreatedDate, 
     @new_UpdatedBy =UpdatedBy,  
     @new_UpdatedDate =UpdatedDate, 
     @new_IsDeleted = IsDeleted 
     From INSERTED where [email protected] 

     set @old_Name = Replace(@old_Name,'&','&amp;') 
     set @old_Name = Replace(@old_Name,'>','&gt;') 
     set @old_Name = Replace(@old_Name,'<','&lt;')  
     set @old_Name = Replace(@old_Name,'"','&quot;') 
     set @old_Name = Replace(@old_Name,'''','&apos;')   

     set @new_Name = Replace(@new_Name,'&','&amp;')  
     set @new_Name = Replace(@new_Name,'>','&gt;') 
     set @new_Name = Replace(@new_Name,'<','&lt;')  
     set @new_Name = Replace(@new_Name,'"','&quot;') 
     set @new_Name = Replace(@new_Name,'''','&apos;') 

     set @old_Description = Replace(@old_Description,'&','&amp;') 
     set @old_Description = Replace(@old_Description,'>','&gt;') 
     set @old_Description = Replace(@old_Description,'<','&lt;')  
     set @old_Description = Replace(@old_Description,'"','&quot;') 
     set @old_Description = Replace(@old_Description,'''','&apos;')   

     set @new_Description = Replace(@new_Description,'&','&amp;')  
     set @new_Description = Replace(@new_Description,'>','&gt;') 
     set @new_Description = Replace(@new_Description,'<','&lt;')  
     set @new_Description = Replace(@new_Description,'"','&quot;') 
     set @new_Description = Replace(@new_Description,'''','&apos;') 

     set @xml = ''  

     BEGIN  

     -- for Name 
     If ltrim(rtrim(IsNull(@new_Name,''))) != ltrim(rtrim(IsNull(@old_Name,'')))  
     set @xml = @xml + '<ColumnInfo ColumnName="Name" OldValue="'+ @old_Name + '" NewValue="' + @new_Name + '"/>'  

     -- for Description 
     If ltrim(rtrim(IsNull(@new_Description,''))) != ltrim(rtrim(IsNull(@old_Description,'')))  
     set @xml = @xml + '<ColumnInfo ColumnName="Description" OldValue="'+ @old_Description + '" NewValue="' + @new_Description + '"/>'  

     -- CreatedDate  
     If IsNull(@new_CreatedDate,'') != IsNull(@old_CreatedDate,'') 
     set @xml = @xml + '<ColumnInfo ColumnName="CreatedDate" OldValue="'+ cast(isnull(@old_CreatedDate,'') as varchar(100)) + '" NewValue="' + cast(isnull(@new_CreatedDate,'') as varchar(100)) + '"/>'  

     -- CreatedBy  
     If cast(IsNull(@new_CreatedBy,'00000000-0000-0000-0000-000000000000')as varchar (36)) != cast(IsNull(@old_CreatedBy,'00000000-0000-0000-0000-000000000000')as varchar(36))  
     set @xml = @xml + '<ColumnInfo ColumnName="CreatedBy" OldValue="'+ cast(IsNull(@old_CreatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36)) + '" NewValue="' + cast(isnull(@new_CreatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36))+ 
     '"/>'  

     -- UpdatedDate  
     If IsNull(@new_UpdatedDate,'') != IsNull(@old_UpdatedDate,'')  
     set @xml = @xml + '<ColumnInfo ColumnName="UpdatedDate" OldValue="'+ cast(IsNull(@old_UpdatedDate,'') as varchar(100)) + '" NewValue="' + cast(IsNull(@new_UpdatedDate,'') as varchar(100)) + '"/>'  

     -- UpdatedBy  
     If cast(IsNull(@new_UpdatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36)) != cast(IsNull(@old_UpdatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36))  
     set @xml = @xml + '<ColumnInfo ColumnName="UpdatedBy" OldValue="'+ cast(IsNull(@old_UpdatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36)) + '" NewValue="' + cast(IsNull(@new_UpdatedBy,'00000000-0000-0000-0000-000000000000') as varchar(36))+ 
     '"/>'  

     -- IsDeleted 
     If cast(IsNull(@new_IsDeleted,'') as varchar(10)) != cast(IsNull(@old_IsDeleted,'') as varchar(10))  
     set @xml = @xml + '<ColumnInfo ColumnName="IsDeleted" OldValue="'+ cast(IsNull(@old_IsDeleted,'') as varchar(10)) + '" NewValue="' + cast(IsNull(@new_IsDeleted,'') as varchar(10)) + '" />'  

     END  

     Set @xml = '<RowInfo TableName="te_Page" UpdatedBy="' + cast(IsNull(@new_UpdatedBy,'00000000-0000-0000-0000-000000000000') as varchar(50)) + '" UpdatedDate="' + Convert(Varchar(20),GetDate()) + '">' + @xml + '</RowInfo>'  
     Select @ishistoryexists = RowHistory From DELETED  

     --print @ishistoryexists 


     If @ishistoryexists is null  
     Begin  
     Set @xml = '<History>' + @xml + '</History>'  
     Update te_Page  
     Set  
     RowHistory = @xml  
     Where  
     Id = @FormLineAttributeValueId  

     End  

     Else  
     Begin  
     set @xml = REPLACE(@currentxml, '<History>', '<History>' + @xml) 
     Update te_Page 
     Set 
     RowHistory = @xml 
     Where 
     Id = @FormLineAttributeValueId  
     End 


     FETCH NEXT FROM curFormId INTO @fmId 
     END 


     CLOSE curFormId 
     DEALLOCATE curFormId 

अब जब भी आप अपने डेटा rowhistory स्तंभ में संग्रहीत किया जाएगा किसी भी अद्यतन प्रदर्शन करेंगे