2010-10-13 12 views
6

करते समय एक्सेस अवरुद्ध करना मुझे एक टेबल को ड्रॉप और फिर से बनाना होगा, जो एक महंगे दृश्य को "कैश" करने के लिए मौजूद है। दृश्य बदल सकता है और मैं रखरखाव को यथासंभव आसान बनाना चाहता हूं, इसलिए मैं नई तालिका को दृश्य के नवीनतम संस्करण को प्रतिबिंबित करना चाहता हूं।एसक्यूएल सर्वर - ड्रॉप और एक टेबल को मनोरंजन करें -

मैं भी पढ़ने की त्रुटियों को रोकने में सक्षम होना चाहता हूं, प्रक्रिया को तालिका तक पहुंचने का प्रयास करना चाहिए, जबकि इसे छोड़ने और फिर से बनाने के बीच में है। मैं एक लेनदेन का उपयोग कर रहा हूं, लेकिन मुझे यकीन नहीं है कि क्या वह उस विभाजित दूसरे के लिए 'गिराए गए' टेबल पर काम करेगा, जो अस्तित्व में नहीं है।

मैंने ड्रॉप/रीवेट व्यू चलाने के दौरान एक लूप में दृश्य से 30 x चयन किया है। अब तक कोई त्रुटि नहीं है।

मैंने डालने के साथ एक ट्रंकेट/हटाया है, लेकिन भविष्य में संभावित रूप से देखने वाले संभावित कॉलमों की आवश्यकता है कि मैं इसे यथासंभव लचीला रखूं, और निश्चित कॉलम इससे मदद नहीं करेंगे।

क्या कोई मुझे बता सकता है कि क्या लेनदेन गिराए जाने पर तालिका को पढ़ने के उपयोग से सुरक्षित रखेगा और यह सुरक्षित है, या यदि कोई बेहतर तरीका है?

ड्रॉप/बहलाना कोड:

BEGIN TRAN 

    BEGIN TRY 

     DROP TABLE Persisted_View_1 

     SELECT * INTO Persisted_View_1 

     FROM View_1 

    END TRY 
    BEGIN CATCH 

     RAISERROR('The procedure proc_PersistView1 failed to commit, the transaction was rolled back', 16, 1) 

     IF @@TRANCOUNT > 0 
     BEGIN 
      ROLLBACK TRAN 
     END 

    END CATCH 

     IF @@TRANCOUNT > 0 
     BEGIN 
      COMMIT TRAN 
     END 

    GO 

अद्यतन: संशोधित क्वेरी निम्नलिखित Brads उत्तर:

ALTER PROCEDURE proc_Drop_Recreate_Persisted_View_MyData 

AS 
BEGIN 

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 

    BEGIN TRAN 

     BEGIN TRY 

      -- Re create 

      SELECT * INTO Persisted_View_MyData_Temp FROM View_MyData 

      -- Create index on product ID 

      CREATE CLUSTERED INDEX [IX_ProductID_ProductTypeID] ON [dbo].[Persisted_View_MyData_Temp] 
      (
       [productID] ASC, 
       [productTypeID] ASC 
      ) 
      WITH 
      (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

      -- Check and drop table 

      IF EXISTS (SELECT Id FROM sysObjects WHERE Name like 'Persisted_View_MyData') 
      BEGIN   
       DROP TABLE Persisted_View_MyData  
      END   

      EXEC sp_rename 'Persisted_View_MyData_Temp', 'Persisted_View_MyData' 

     END TRY 
     BEGIN CATCH 

      RAISERROR('The procedure proc_PersistViewMyData failed to commit, the transaction was rolled back', 16, 1) 

      IF @@TRANCOUNT > 0 
      BEGIN 
       ROLLBACK TRAN 
      END 

     END CATCH 

      IF @@TRANCOUNT > 0 
      BEGIN 
       COMMIT TRAN 
      END 


END 
+2

इस मैन्युअल कैशिंग तालिका का उपयोग करने के बजाय, क्या आप इसे अनुक्रमित दृश्य बनाकर दृश्य को पूरा कर सकते हैं? फिर एसक्यूएल को आपके लिए इन सभी विवरणों का ख्याल रखना चाहिए। (ध्यान दें कि दृश्य में कुछ संरचनाएं इसे रद्द कर सकती हैं, जैसे यूनियन या ग्रुप बीईएस) – BradC

+0

@ ब्रैडसी, क्या आप "अनुक्रमित दृश्य" को देखने के तरीके पर और टिप्पणी कर सकते हैं? – Brad

+0

@ ब्रैड ने मेरी टिप्पणी को एक उत्तर में विस्तारित किया। निचे देखो। – BradC

उत्तर

8

मैं उस प्रक्रिया का उपयोग करता हूं जिसे मैं ड्रॉप-फ्लिप- फ्लॉप। तालिका बनाने के दौरान मैंने इस प्रक्रिया का सफलतापूर्वक उपयोग किया है और कुछ समय लगता है और मैं नहीं चाहता कि सभी पुनर्निर्माण प्रक्रिया के दौरान सभी एप्लिकेशन/उपयोगकर्ताओं को टेबल की आवश्यकता हो।

  1. कुछ पूर्व/पोस्ट ठीक साथ तालिका के नए संस्करण बनाएं (जैसे <TableName>_New)
  2. ड्रॉप मौजूदा आइटम (यानी DROP TABLE <TableName>)
  3. मूल तालिका के नाम करने के लिए नए तालिका का नाम (EXEC sql_rename...) [REF]

मैं आमतौर पर इस तर्क के साथ एक संग्रहीत प्रक्रिया बना देता हूं और इसे नौकरी में शेड्यूल करता हूं।


* नोट: इस प्रक्रिया का पूरा लाभ लेने के लिए, आप किसी भी अनुक्रमित आपने चरण 1 और 2 के बीच नए मेज पर की जरूरत है इसका मतलब है कि आप पहले से करना होगा बनाने की आवश्यकता होगी/स्क्रिप्ट फिर से चलने पर समस्याओं में भागने से बचने के लिए उन्हें पोस्ट-फिक्स भी करें और तालिका के साथ उनका नाम बदलें।

अतिरिक्त सुरक्षा के लिए, आप चरण 2 और 3 के आसपास एक लेनदेन बना सकते हैं। अलगाव स्तर को Serialized पर सेट करना इसे सबसे सुरक्षित बना देगा, लेकिन मुझे कोई अनुभव नहीं है अगर यह वास्तव में त्रुटियों को रोक देगा। लेनदेन का उपयोग किए बिना मैंने कभी भी किसी भी समस्या में भाग नहीं लिया है।

+0

धन्यवाद, मैंने उपरोक्त प्रक्रिया में संशोधन किया है। उम्मीद है कि यह सुंदर बुलेट सबूत है। – gb2d

+0

क्या मैंने सही तरीके से लेनदेन अलगाव स्तर निर्धारित किया है? – gb2d

+0

मुझे लगता है कि आप '_Temp' तालिका बनाने के बाद 'TRAN BEGIN' (और' TRY BEGIN') को नीचे ले जा सकते हैं और यदि यह पाया जाता है तो '_Temp' तालिका ड्रॉप करने के लिए शुरुआत में तर्क जोड़ें। – Brad

0

लेनदेन अलगाव धारावाहिक के स्तर सेट करें। इसका मतलब यह है कि जब आप लेनदेन शुरू करते हैं तो लॉक की गई पंक्तियों को इस तरह से किया जाता है कि अन्य लोग तब तक नहीं पढ़ सकते जब तक कि ट्रैनी

+0

क्या आप लाभ समझा सकते हैं? – gb2d

3

यह काम करेगा, लेकिन @ ब्रैड पॉइंट्स की तरह, आपके पास पुनर्निर्मित होने पर अवरोध की एक विस्तृत अवधि हो सकती है।उनका नया/बूढ़ा बूढ़ा/नाम बदलना बहुत अच्छा काम करेगा।

एक और चाल मैं का उपयोग किया है विचारों पर आधारित है:

  • आप दो स्थायी टेबल, MyTable0 और MyTable1
  • आप कहीं यह दर्शाता है जो तालिका "वर्तमान" है एक संकेतक की दुकान है, और जो ऑफ़लाइन है
  • आप एक ऐसा दृश्य (CREATE VIEW MyTable as SELECT * from MyTable0 के रूप में सरल रूप में) "वर्तमान" तालिका के विरुद्ध परिभाषित
  • जब यह अद्यतन करने के लिए समय आ गया है, आप ऑफ़लाइन तालिका में अपनी डेटा लोड, है
  • आरयू n एक ALTER देखें अब वर्तमान तालिका को देख करने के लिए (एक बयान के रूप में, यह तो आप घोषित लेनदेन के साथ उपद्रव करने की आवश्यकता न पड़े, एक अंतर्निहित लेन-देन में लिपटे है),
  • और उसके अनुसार सूचक को अद्यतन (Indicator = (Indicator + 1) % 2)

(मैं एक बार इस विचार पर आधारित एक चार रास्ता तालिका प्रणाली थी, पिछले डेटा, मौजूदा डेटा, भविष्य डेटा प्रीमियम ग्राहकों के लिए उपलब्ध है, और "अगले लोड के लिए इंतज़ार कर"। के लिए)

+0

@Phillip, दिलचस्प विचार के लिए +1 ... – Brad

+0

इस के करीब आने का एक और दिलचस्प तरीका है। – gb2d

3

मैं विस्तार करेंगे मेरी एक पूर्ण उत्तर के रूप में टिप्पणी करें: ड्रॉप-फ्लिप-फ्लॉप को लागू करने से पहले, मैं यह देखने के लिए पहले जांच करूंगा कि क्या आप केवल दृश्य को इंडेक्स कर सकते हैं:

Indexed views in SQL 2000
Indexed views in SQL 2005
Indexed views in SQL 2008

असल में, दृश्य की स्थिति के एक विशिष्ट समूह को पूरा करता है, तो आप बस एक संकुल अनुक्रमणिका को देखने के लिए जोड़ सकते हैं, और यह वास्तव में परिणाम देख सकते हैं जो की एक भौतिक प्रतिलिपि की बचत होती है प्रत्येक बार अंतर्निहित तालिकाओं को संशोधित किया जाता है अद्यतन किया जाता है।

दूसरे शब्दों में, एसक्यूएल आपके लिए सभी काम कर रहा है कि अब आप मैन्युअल रूप से कर रहे हैं।

दुर्भाग्यवश, सभी विचार भौतिक नहीं हैं। एक अनुक्रमित दृश्य नहीं हो सकता:

  • DISTINCT
  • व्युत्पन्न टेबल्स या सबक्वेरी
  • मौजूद है/नहीं मौजूद है
  • यूनिअन
  • टॉप
  • बाहरी
द्वारा शामिल
  • आदेश

    और ओटी का एक गुच्छा उपरोक्त लिंक पर आप उसकी चीजें पढ़ सकते हैं।

  • +0

    एक अच्छे समाधान के लिए +1 (यदि विशेष परिस्थितियों में व्यवहार्य है) – Brad

    +0

    मैंने अनुक्रमित विचारों को देखा, जो एक कठिन समाधान होता, लेकिन जल्दी से पता चला कि आपके द्वारा उल्लिखित प्रतिबंध मेरे मामले में लागू होते हैं, इसलिए अनुक्रमित विचार नहीं हो सकते उपयोग किया गया। +1 – gb2d

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