2011-01-26 4 views
27

मैं एक मेज से सम्मिलित करने के लिए कोशिश कर रहा हूँ दूसरे में द्वाराSQL सर्वर 2005 ROW_NUMBER() के आदेश के बिना

DECLARE @IDOffset int; 
SELECT @IDOffset = MAX(ISNULL(ID,0)) FROM TargetTable 

INSERT INTO TargetTable(ID, FIELD) 
SELECT [Increment] + @IDOffset ,FeildValue 
FROM SourceTable 
WHERE [somecondition] 

TargetTable.ID का उपयोग कर एक पहचान स्तंभ है, जिसके कारण मैं ऑटो के लिए एक रास्ता खोजने के लिए नहीं है इसे स्वयं बनाओ।

मुझे पता है कि मैं एक कर्सर का उपयोग कर सकता हूं, या एक पहचान कॉलम और फील्डवेल्यू फ़ील्ड के साथ एक टेबल वैरिएबल बना सकता हूं, इसे पॉप्युलेट करें, फिर इसे अपने insert into...select में उपयोग करें, लेकिन यह बहुत ही कुशल नहीं है। मैंने वृद्धि के लिए ROW_NUMBER फ़ंक्शन का उपयोग करने का प्रयास किया, लेकिन मेरे पास वास्तव में SourceTable में फ़ील्ड द्वारा वैध ऑर्डर नहीं है जिसका उपयोग मैं कर सकता हूं, और SourceTable (यदि संभव हो) का मूल क्रम रखना चाहता हूं।

क्या कोई भी कुछ सुझा सकता है?

+2

स्रोत मेज पर क्लस्टर सूचकांक क्या है? मुझे लगता है कि जब आप "स्रोतटेबल के मूल क्रम" कहते हैं तो आप यही बात कर रहे हैं? यदि यह एक ढेर है तो कोई विशेष आदेश नहीं है। –

उत्तर

70

आप एक स्पष्ट आदेश निर्दिष्ट करने के रूप में इस से बचने कर सकते हैं:

INSERT dbo.TargetTable (ID, FIELD) 
SELECT 
    Row_Number() OVER (ORDER BY (SELECT 1)) 
     + Coalesce(
     (SELECT Max(ID) FROM dbo.TargetTable WITH (TABLOCKX, HOLDLOCK)), 
     0 
    ), 
    FieldValue 
FROM dbo.SourceTable 
WHERE {somecondition}; 

हालांकि, कृपया ध्यान दें कि केवल एक तरह से एक आदेश और की गारंटी नहीं देता है कि किसी भी मूल डेटा आदेश संरक्षित किया जाएगा निर्दिष्ट करने से बचना है। अन्य कारक हैं जो परिणाम को ऑर्डर करने का कारण बन सकते हैं, जैसे बाहरी क्वेरी में ORDER BY। इसे पूरी तरह से समझने के लिए, किसी को यह समझना चाहिए कि "किसी विशेष तरीके से" आदेश नहीं दिया गया अवधारणा "मूल आदेश को बनाए रखने" जैसा नहीं है (जिसे किसी विशेष तरीके से आदेश दिया गया है!)। मेरा मानना ​​है कि एक शुद्ध संबंधपरक डेटाबेस परिप्रेक्ष्य से, बाद की अवधारणा , परिभाषा (हालांकि डेटाबेस कार्यान्वयन हो सकता है जो इसका उल्लंघन करता है, SQL सर्वर उनमें से एक नहीं है) मौजूद नहीं है।

लॉक संकेतों का कारण उस मामले को रोकने के लिए है जहां क्वेरी का निष्पादन के कुछ हिस्सों में, आप जिस मूल्य का उपयोग करने की योजना बना रहे हैं उसका उपयोग करके अन्य प्रक्रिया को सम्मिलित करते हैं।

नोट: कई लोग (SELECT NULL) का उपयोग करते हैं ताकि "विंडोिंग फ़ंक्शन के खंड द्वारा ऑर्डर में अनुमत कोई स्थिरांक" प्रतिबंध न हो। किसी कारण से, मैं 1NULL से अधिक पसंद करता हूं।

इसके अलावा: मुझे लगता है कि एक पहचान कॉलम बहुत बेहतर है और इसके बजाय इसका उपयोग किया जाना चाहिए। संपूर्ण तालिकाओं को विशेष रूप से लॉक करने के लिए सहमति के लिए अच्छा नहीं है। ख़ामोश।

+0

@Emtucifor: पहला एक सही काम करता है। दूसरे के लिए, तथ्य यह है कि यह किसी भी मामले में एक परिणाम, एक पंक्ति लौटाता है। यदि तालिका खाली है, तो यह शून्य लौटाता है, इसलिए उप-चयन करने की कोई आवश्यकता नहीं है, बस MAX() पर ISNULL() का उपयोग करें, लेकिन इसके अंदर नहीं। मैंने किसी भी तरह इसे पहले खारिज करने में कामयाब रहा था, असल में मैंने शायद इसे बहुत सोच नहीं दिया होगा। एक मात्र संयोग मुझे अन्यथा सीखने देता है जब मैं एसओ पर किसी की पोस्ट पढ़ता हूं (अब याद नहीं है)। मैंने अपना सुधार पोस्ट करने से पहले इसे चेक किया। यह बेहतर क्यों है? खैर, यह बस आसान दिख रहा है, और पढ़ने के लिए इतना आसान है, मुझे लगता है। –

+0

यह बाहरी रूप से सही नहीं है, अगर बाहरी क्वेरी में 'ऑर्डर बाय' क्लॉज है, या अन्य किनारे के मामलों में यहां देखा जा सकता है: http://stackoverflow.com/q/18961789/521799 –

+0

@LukasEder मेरा उत्तर सही था , लेकिन शायद यह उतना पूरा नहीं था जितना हो सकता था।अगर कोई "मूल ऑर्डरिंग संरक्षित" ढूंढ रहा था और यह अनजान था कि यह SQL सर्वर में एक बकवास अवधारणा है, तो वे इसे प्राप्त करने के लिए इस कोड का उपयोग करने का प्रयास कर सकते हैं - लेकिन असफल हो जाएंगे। मैंने अब इस पहलू को संबोधित करने के लिए अपना जवाब अपडेट कर दिया है। – ErikE

2

आप order by (select null) इस तरह का उपयोग करके आदेश की अनदेखी कर सकते हैं:

declare @IDOffset int; 
select @IDOffset = max(isnull(ID, 0)) from TargetTable 

insert into TargetTable(ID, FIELD) 
select row_number() over (order by (select null)) + @IDOffset, FeildValue 
    from SourceTable 
where [somecondition] 
+1

उस उत्तर की तुलना में जो पहले से ही पांच साल से यहां रहा था, यह क्या जोड़ता है? यह कोई नया दृष्टिकोण प्रदान नहीं करता है। यह कोई नया स्पष्टीकरण प्रदान नहीं करता है। यह कुछ नया प्रदान नहीं करता है। – hvd