2009-03-03 15 views
18

स्वैपिंग मैं टेबल पर सबसे अच्छे तरीके से स्वैप करना चाहता हूं।
मेरे पास आईपीटीओ कंट्री टेबल है, और मैं एक बाहरी सीएसवी फ़ाइल के अनुसार साप्ताहिक आधार पर एक नया खाता बनाता हूं जो मैं आयात करता हूं।एमएस-एसक्यूएल टेबल

सबसे तेज़ तरीका है मैं स्विच करने के लिए मिल गया है निम्नलिखित कर रहा था:

sp_rename IpToCountry IpToCountryOld 
go 
sp_rename IpToCountryNew IpToCountry 
go 

इस के साथ समस्या यह है कि टेबल अभी भी बीच में पहुँचा जा सकता है।
मैं SQL में इस समस्या से कैसे संपर्क करूं?
sp_getapplock और sp_releaseapplock का उपयोग करने पर विचार किया जाता है, लेकिन मैं जितनी जल्दी हो सके टेबल फ़ंक्शन से पढ़ना चाहता हूं।

+1

मैं SQL सर्वर 2000 का उपयोग कर रहा हूं। IpToCountryOld अप्रासंगिक है और वास्तव में इसे छोटा कर दिया गया था और गिरा दिया जा सकता था। मैं नाम बदल रहा हूं क्योंकि यह तेज़ है, फिर मैं पुरानी टेबल हटा देता हूं ... –

उत्तर

16

मान लें कि आप मौजूदा तालिका में अपडेट/डालने में असमर्थ हैं, तो आप view का उपयोग कर तालिका में सभी पहुंच क्यों नहीं लपेटते हैं?

उदाहरण के लिए, आप शुरू में अपने डेटा को एक मेज IpToCountry20090303 कहा जाता है में संग्रहीत कर सकता है, और आपके विचार कुछ इस तरह होगा:

CREATE VIEW IpToCountry 
AS 
SELECT * FROM IpToCountry20090303 

जब नए डेटा में आता है, आप बना सकते हैं और पॉप्युलेट IpToCountry20090310 तालिका।

ALTER VIEW IpToCountry 
AS 
SELECT * FROM IpToCountry20090310 

स्विच, पूरी तरह से परमाणु हो जाएगा किसी भी स्पष्ट ताला या लेन-देन की आवश्यकता के बिना: एक बार मेज से भर जाता है तो बस अपने दृश्य को अपडेट। एक बार दृश्य अपडेट हो जाने के बाद, आप बस पुरानी तालिका को छोड़ सकते हैं (या यदि आप चाहें तो इसे रखें)।

+0

क्या यह वास्तव में इतना आसान है, यद्यपि? http://stackoverflow.com/questions/3716546/why-cant-sql-server-alter-a-view-in-a-stored-procedure – mg1075

0

IpToCountryOld का क्या होता है? क्या आप इसे फेंक देते हैं? इस मामले में, IpToCountry को छोटा क्यों न करें और मेरा नया डेटा आयात न करें।

यदि आपको डेटा रखने की आवश्यकता है, तो तालिका पर लोड तिथि को संग्रहीत करने और WHERE क्लॉज में कहीं भी "वर्तमान" लोड तिथि को संग्रहीत करने के बारे में कैसे? फिर डेटा सफलतापूर्वक लोड होने पर आप वर्तमान दिनांक स्विच करते हैं।

आप यह नहीं कहते कि आप किस डीबी का उपयोग कर रहे हैं, इसलिए मुझे नहीं पता कि इसका कितना उपयोग है, लेकिन क्या आपके पास तालिका का संदर्भ देने वाली कोई संग्रहित प्रक्रियाएं हैं? चेतावनी दीजिये कि कुछ प्लेटफार्मों पर एसपी को टेबल के आंतरिक संदर्भों का उपयोग करके संकलित किया जाता है जो नाम के साथ नहीं बदलेगा, इसलिए जोखिम है कि एसपीएस आपके नए डेटा को पुन: संकलित किए बिना नहीं उठाएंगे। विचारों और संग्रहीत पार्स किए गए प्रश्नों के लिए भी यह सच हो सकता है।

+0

हाय माइक, मैं SQL सर्वर 2000 का उपयोग कर रहा हूं। असल में, पुरानी तालिका अप्रासंगिक है। डेटा आयात में कई सेकंड लगते हैं (एक नई तालिका + अनुक्रमण के लिए)। मैं न्यूनतम सिस्टम क्षति के साथ डेटा को प्रतिस्थापित करना चाहता हूं ... –

0

क्या आप ऑफलाइन घंटों के दौरान एक टेबल पर आयात नहीं कर सकते?

या क्यों न केवल डेटा अपडेट करें, यानी मौजूदा रिकॉर्ड अपडेट करें और रिकॉर्ड के आधार पर रिकॉर्ड पर किसी भी नए को जोड़ें क्योंकि आप डेटा आयात करने के लिए लूप करते हैं। यह तालिका को लाइव रहने और पूर्ण तालिकाओं को जोड़ने और छोड़ने के समग्र प्रभाव को कम करने की अनुमति देगा।

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

+0

डेटा आईपी पते है (आईआईपी, आईआईपी (साथ में वे पीके हैं), देश, क्षेत्र, शहर)। चूंकि आईपी श्रेणियां हमेशा बदलती हैं, हटाएं और डालने के साथ अद्यतन नरक होगा। मैं इसे बंद घंटों के दौरान कर सकता हूं, लेकिन प्रतिस्थापन अभी भी डाउनटाइम का कारण बन जाएगा। मैं जाने के लिए अनुशंसित तरीके से पता लगाने की कोशिश कर रहा हूं ... –

1

जो आप प्राप्त करना चाहते हैं उसे लागू करने के लिए एक और तरीका तालिका विभाजन का उपयोग होगा, एक तकनीक जो SQL सर्वर के एंटरप्राइज़ संस्करण में उपलब्ध है।

तालिका का नाम वही बना सकता है।आपके टेबल आयात पूर्ण होने के बाद, आप बस अपने पुराने डेटा वाले विभाजन को स्विच करें और नए विभाजन में स्विच करें।

निम्नलिखित श्वेत पत्र में वह सारी जानकारी शामिल है जिसे आपको प्रारंभ करने की आवश्यकता होगी।

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

चीयर्स, जॉन

+0

हाय जॉन, यह कुछ रोचक सामग्री है। हालांकि SQL2000 में मुझे अभी भी विभाजन विभाजन का उपयोग करने के लिए मजबूर होना होगा, लेकिन यह जानना अच्छा है। मेरे पास कुछ पढ़ने के लिए है :) –

1

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

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

इसके विपरीत, sp_rename मेरे लिए स्केल पर अच्छा काम करता है: यह आपको लॉकिंग और इसके दायरे पर नियंत्रण देता है। स्वैप से पहले अवरुद्ध करने के मुद्दे को हल करने के लिए, नीचे दिखाए गए अनुसार इसे आजमाएं। चेहरे के मूल्य पर यह उच्च मात्रा में समान पैमाने पर समस्या प्रतीत होता है ... लेकिन मैंने इसे अभ्यास में नहीं देखा है। तो, मेरे लिए काम करता है ... लेकिन फिर, हर किसी की जरूरतें और अनुभव अलग हैं।

DECLARE @dummylock bit 
BEGIN TRANSACTION 
BEGIN TRY 
    -- necessary to obtain exclusive lock on the table prior to swapping 
    SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX)) 
    -- may or may not be necessary in your case 
    SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX)) 
    exec sp_rename 'A', 'TEMP' 
    exec sp_rename 'B', 'A' 
    exec sp_rename 'TEMP', 'B' 
    COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    -- other error handling here if needed 
    ROLLBACK TRANSACTION 
END CATCH 
+0

आप sp_getapplock और sp_releaseapplock के साथ ऐसा ही कर सकते हैं, जो ओपी – gbn

+0

@gbn नहीं चाहता है, मुझे नहीं लगता कि sp_getapplock इस तरह काम करता है। sp_getapplock कोड के ब्लॉक के दो एक साथ निष्पादन को रोक देगा, लेकिन जब तक कि प्रत्येक आदेश जो * पढ़ता है * वह डेटा उसी लॉक (संभवतः साझा मोड में) का उपयोग नहीं करता है, तो पहले तालिका में निष्पादित होने से पढ़ने को रोकने के लिए कुछ भी नहीं है मौजूद। Sp_getapplock में संसाधन का नाम केवल एक मनमाना स्ट्रिंग है, और जब तक कि * उस * तालिका तक पहुंच * sp_getapplock द्वारा गेट नहीं की जाती है, तो बुरी चीजें हो सकती हैं।टेबल पर टैबब्लैक का उपयोग करके स्वयं कोई भी पाठ नहीं हो सकता है, और आपको उन्हें रोकने के लिए और कुछ भी करने की ज़रूरत नहीं है। – Glazed

+0

@BLowery, क्या आपको लेनदेन की अवधि के लिए तालिका विशेष लॉक रखने के लिए होल्डॉक निर्दिष्ट करने की भी आवश्यकता नहीं है? अन्यथा ताला केवल कथन की अवधि के लिए आयोजित किया जाएगा। आप सभी आदेशों पर होल्डॉक को मजबूर करने के लिए सर्जिकल के लेनदेन अलगाव स्तर को भी निर्दिष्ट कर सकते हैं। या, क्या यह तथ्य है कि आप एक चर के मान को आवंटित कर रहे हैं स्वचालित रूप से ताला पकड़? मैंने वास्तव में कभी भी इस सटीक तकनीक की कोशिश नहीं की है। मैं आम तौर पर 'टेबल से हटाएं (टैबब्लैक, होल्डॉक)' जैसी चीजें करता हूं और फिर तालिका को फिर से भरता हूं। मुझे पता है कि होल्डॉक की आवश्यकता है। – Glazed

0

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

हर जगह आपकी तालिका का संदर्भ दिया जाता है, आप टेबल नाम के लिए एक संग्रहीत प्रक्रिया को कॉल कर सकते हैं।

संग्रहीत प्रक्रिया वैकल्पिक रूप से नई तालिका बनायेगी या प्रदान किए गए पैरामीटर के आधार पर पुरानी तालिकाओं को वापस कर देगी।

+0

अपने उत्तरों को स्पष्ट करने के लिए कुछ स्रोत कोड प्रदान करना सबसे अच्छा है – Mike

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