2009-08-04 11 views
5

नहीं my previous questionएसक्यूएल सर्वर 2005 पर डेटाटाइम को अंतिम डालने/अपडेट/डिलीट करने के लिए कैसे करें?

का डुप्लिकेट वहाँ किसी भी तरह से जब एक तालिका/डेटाबेस एक सम्मिलित/अपडेट करने के लिए किया था नवीनतम दिनांक प्राप्त करने के लिए है/Sql सर्वर 2005 को हटाना चाहते हैं? पसंदीदा रूप से ट्रिगर बनाने के बिना ..

मुझे पता है कि जब आपको प्रति पंक्ति अंतिम अद्यतन की आवश्यकता होती है, तो आपको ट्रिगर्स की आवश्यकता होती है। लेकिन मुझे यकीन नहीं है कि अगर आपको पूरी तालिका के लिए अंतिम अपडेट प्राप्त करना है तो उनकी ज़रूरत है या नहीं।

+1

जवाब में स्वीकार कर लिया पर सबसे अच्छा भ्रामक है। –

उत्तर

8

आप आसानी से अंतिम सम्मिलित/अपडेट किया गया/नष्ट कर दिया गया तिथियां जाओ सकता है:

CREATE FUNCTIOn fn_TablesLastUpdateDate(@Date NVARCHAR(20)) 

RETURNS @table TABLE(TableName NVARCHAR(40), LastUpdated Datetime) 

AS 

BEGIN 


IF(@Date='') OR (@Date Is Null) OR (@Date='0') 

    BEGIN 
     INSERT INTO @table 
     SELECT TOP 100 PERCENT TABLENAME,LASTUPDATED FROM 
     (
      SELECT B.NAME AS 'TABLENAME', MAX(STATS_DATE (ID,INDID)) AS LASTUPDATED 
      FROM SYS.SYSINDEXES AS A 
        INNER JOIN SYS.OBJECTS AS B ON A.ID = B.OBJECT_ID 
      WHERE B.TYPE = 'U' AND STATS_DATE (ID,INDID) IS NOT NULL 
      GROUP BY B.NAME 
     ) AS A 
     ORDER BY LASTUPDATED DESC 
    END 
ELSE 

    BEGIN 
     INSERT INTO @table 
     SELECT TOP 100 PERCENT TABLENAME,LASTUPDATED FROM 
     (
      SELECT B.NAME AS 'TABLENAME', MAX(STATS_DATE (ID,INDID)) AS LASTUPDATED, 
        CONVERT(VARCHAR, MAX(STATS_DATE (ID,INDID)), 103) as Date 
      FROM SYS.SYSINDEXES AS A 
        INNER JOIN SYS.OBJECTS AS B ON A.ID = B.OBJECT_ID 
      WHERE B.TYPE = 'U' AND STATS_DATE (ID,INDID) IS NOT NULL 
      GROUP BY B.NAME 
     ) AS A 
     WHERE [email protected] 
     ORDER BY LASTUPDATED DESC 
    END 
RETURN 

END 



-- SELECT * from fn_TablesLastUpdateDate('06/11/2012') 
+0

यदि आपके पास व्यवस्थापक या उन्नत अनुमति नहीं है और फिर भी आपके परिणाम प्राप्त होते हैं तो आप आंतरिक चयन कथन चला सकते हैं। महान समाधान –

+1

मायाब मुझे कुछ याद आया लेकिन एसक्यूएल-सर्वर 2008 में यह पंक्तियों को डालने/अपडेट/हटाए जाने पर 'LASTUPDATED' में कोई भी परिवर्तन नहीं दिखाता है। केवल जब टेबल संरचना बदल दी गई थी (कॉलम/इंडेक्स जोड़े गए आदि ..)। क्या ओपी का इरादा है? – ZigiZ

+0

@ZigiZ: शायद आप इसे 'sys.objects.modify_date' कॉलम से भ्रमित कर रहे हैं, जो टेबल के लिए संरचना की अंतिम परिवर्तन तिथि दिखाता है। इस कोड में 'LASTUPDATED' कॉलम में मान [' STATS_DATE' फ़ंक्शन] के परिणामों पर आधारित हैं (http://technet.microsoft.com/en-us/library/ms190330.aspx "STATS_DATE (ट्रांजैक्ट-एसक्यूएल) ")। –

2

को देखते हुए कोई जवाब अभी तक नहीं है, यहाँ मेरी 2 सेंट हैं:

  • सम्मिलित के लिए, मैं डिफ़ॉल्ट मान GETDATE()
  • अपडेट के लिए के साथ एक दिनांक समय क्षेत्र का प्रयोग करेंगे, मैं भी एक दिनांक समय का प्रयोग करेंगे प्रत्येक बार अद्यतन होने पर ट्रिगर द्वारा फ़ील्ड संशोधित किया जाता है।
  • हटाएं के लिए, रिकॉर्ड उपलब्ध नहीं होगा, इसलिए आप इसे क्वेरी नहीं कर सकते।

मैंने ट्रिगर से बचने के लिए टाइमस्टैम्प का उपयोग करने के बारे में सोचा, लेकिन आप टाइमस्टैम्प को डेटाटाइम में परिवर्तित नहीं कर सकते हैं।

संपादित करें: या हो सकता है आप एक "metatable" जहां ट्रिगर में आप परिवर्तन की बचत होगी उपयोग कर सकते हैं तारीखें

CREATE TABLE metatable (
table_name VARCHAR(40) NOT NULL PRIMARY KEY, 
last_insert DATETIME NOT NULL, 
last_update DATETIME NOT NULL, 
last_delete DATETIME NOT NULL 
) 

INSERT metatable VALUES ('table1', GETDATE(), GETDATE(), GETDATE()) 

CREATE TRIGGER trg_table1_ins ON table1 FOR INSERT AS BEGIN 
    UPDATE metatable SET last_insert = GETDATE() WHERE table_name = 'table1' 
END 

CREATE TRIGGER trg_table1_upd ON table1 FOR UPDATE AS BEGIN 
    UPDATE metatable SET last_update = GETDATE() WHERE table_name = 'table1' 
END 

CREATE TRIGGER trg_table1_del ON table1 FOR DELETE AS BEGIN 
    UPDATE metatable SET last_delete = GETDATE() WHERE table_name = 'table1' 
END 

मैं इसे चलाता बिना उपयोगी

+1

बस अवरुद्ध करने के लिए बाहर देखो। यदि आपके पास एक ही समय में चलने वाले कुछ लेन-देन होते हैं जो एक ही तालिका को बदलते हैं (अलग पंक्तियां जो अवरुद्ध नहीं करती हैं), तो उन्हें उस तालिका के लिए एक लॉग तालिका पंक्ति को अपडेट करने के लिए अपनी बारी का इंतजार करना होगा। –

+0

हाँ, आप सही हैं, क्या आप कोड को संशोधित कर सकते हैं ताकि यह आपके द्वारा उल्लिखित परिवर्तनों को प्रतिबिंबित कर सके? मुझे यह सुनिश्चित करने के लिए कि –

1

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

+0

के लिए परेशान नहीं किया जाएगा, LastChgDate एक डेटाटाइम प्रकार होगा और आपको इसे प्रत्येक INSERT/UPDATE को GETDATE() पर सेट करने की आवश्यकता होगी। साथ ही, "DELETEs" को "डी" में स्थिति परिवर्तन के साथ अद्यतन के रूप में संभाला जाएगा, और उसके बाद अंतिम परिवर्तन समय के लिए पूछताछ की जा सकती है। –

+0

एक लॉग तालिका के बीच आगे और आगे जा रहा है और वास्तविक तालिका में डेटाटाइम कॉलम बोझिल लगता है –

1

ठीक है, आप "LastUpdateDate" के साथ एक कॉलम रख सकते हैं जो किसी भी सम्मिलन या अद्यतन पर वर्तमान सर्वर दिनांक/समय पर सेट है। फिर आप सबसे हालिया LastUpdateDate के साथ पंक्ति के लिए पूछ सकते हैं।

5

पिछले दो उत्तरों के अनुसार, SQL सर्वर में वास्तव में कोई अंतर्निहित कार्यक्षमता नहीं है जो आपकी आवश्यकताओं के लिए आसानी से उपलब्ध है।

गतिशील प्रबंधन विचारों का एक टन है जो आपको कुछ हितों के बारे में बता सकता है, उदा। sys.dm_db_index_usage_stats जो आपको बताता है कि किसी दिए गए इंडेक्स की आखिरी तलाश या अपडेट कब होता है।

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

क्षमा करें मैं आपको कोई बेहतर समाचार नहीं दे सकता - यह वही तरीका है जो अभी है।

एसक्यूएल सर्वर 2008 में, आप अतिरिक्त नई सुविधाओं है, कि अपनी आवश्यकताओं में से कुछ को कवर कर सकते हैं - बाहर की जाँच:

मार्क

2

कम से अधिक अवधि (सर्वर स्टार्टअप के बाद से) आप sys.dm_db_index_usage_stats last_user_update column जांचते हैं। लेकिन चूंकि यह केवल सर्वर स्टार्टअप के बाद अद्यतनों की गणना करता है, इसलिए इसका उपयोग लंबे समय तक नहीं किया जा सकता है।

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

0

सरल! पहले "LastUpdated" कॉलम जोड़ें। इसे GetDate() का डिफ़ॉल्ट दें। यह सम्मिलित वक्तव्य का ख्याल रखेगा। दूसरा, एक अद्यतन ट्रिगर जोड़ें जो GetDate() को LastUpdated अद्यतन करता है। अपडेट अब कवर किए गए हैं। अंत में थोड़ा सा/बूलियन फ़ील्ड जोड़ें 0 के डिफ़ॉल्ट के साथ हटाया गया है। क्या कोई उपयोगकर्ता पंक्ति को हटाना चाहता है, बिट को फ़्लिप करें। चूंकि जब आप एक पंक्ति को "हटाते हैं", तो आप वास्तव में IsDeleted फ़ील्ड को अपडेट कर रहे हैं (और इसलिए अद्यतन कार्रवाई का उपयोग कर रहे हैं), Deletes अब टाइमस्टैम्प हैं।

मेज पर सबसे हाल की गतिविधि प्राप्त करने के लिए: को केवल टाइमस्टैम्प मिलती है:

SELECT MAX(LastUpdated) FROM MyTable 

और अधिक जानकारी प्राप्त करने के लिए:

SELECT MAX(LastUpdated), ID /*or whatever you need to know*/ FROM MyTable 
+0

बेशक यदि आप ISDeleted बिट फ़ील्ड जोड़ते हैं, तो आपके सभी मौजूदा कोड को यह सुनिश्चित करने के लिए फिर से किया जाना होगा कि हटाए गए रिकॉर्ड का उपयोग नहीं किया जाता है प्रश्नों। – HLGEM

+0

माना जाता है कि यह दर्द मुक्त नहीं होगा, लेकिन यह तालिका पर आखिरी गतिविधि दिखाएगा, इससे कोई फर्क नहीं पड़ता कि यह क्या था। – Pulsehead

1

मैं मिश्रण करने के लिए ट्रैकिंग बदलें जोड़ना होगा - के रूप में डेटा कैप्चर चेंज का विरोध करने के लिए, यह केवल एंटरप्राइज़ सुविधा नहीं है।

http://msdn.microsoft.com/en-us/library/cc280462.aspx

इसी sys.dm_db_index_usage_stats करने पर इसके बारे में पढ़ें, डेटा नहीं वहाँ हमेशा के लिए (हालांकि यह सर्वर पुनरारंभ बच जाते हैं और विन्यास योग्य है) है और आप निकालने और सूचना के विशेष टुकड़ा आप कर रहे हैं लागू करने के लिए होगा खोज रहे हैं

MDD

12
SELECT t.name, 
     user_seeks, 
     user_scans, 
     user_lookups, 
     user_updates, 
     last_user_seek, 
     last_user_scan, 
     last_user_lookup, 
     last_user_update 
FROM sys.dm_db_index_usage_stats i 
     JOIN sys.tables t 
     ON (t.object_id = i.object_id) 
WHERE database_id = DB_ID() 
संबंधित मुद्दे