2009-02-25 7 views
6

में लूप करना इतना मुश्किल क्यों है, मुझे पता है कि यह किया जा सकता है, मैं इसे अक्सर करता हूं, लेकिन टी-एसक्यूएल में लूप करना इतना मुश्किल क्यों है? मैं एक कारण के बारे में सोच सकता हूं कि मैं एक क्वेरी परिणाम सेट के माध्यम से विश्लेषण करना चाहता हूं और कुछ ऐसा करता हूं जो लूप के बिना किया जा सकता है, फिर भी मेरे लूप को सेटअप और निष्पादित करने के लिए कोड> 20 लाइनें है।टी-एसक्यूएल

मुझे यकीन है कि दूसरों के समान विचार हैं तो हम अभी भी लूप करने के लिए एक आसान तरीका क्यों नहीं हैं?

एक तरफ: हमें अंत में SQL2008 में एक यूपीएसईआरटी (उर्फ मेर्ज) मिला है, इसलिए शायद सभी आशाएं खो नहीं जाएंगी।

उत्तर

22

एसक्यूएल एक सेट-आधारित, declarative language है; एक प्रक्रियात्मक या imperative language नहीं। टी-एसक्यूएल दोनों को झुकाव करने की कोशिश करता है, लेकिन यह अभी भी मूल रूप से सेट-आधारित प्रतिमान पर बनाया गया है।

+0

क्या आपको ये सही रास्ता मिल गया है? – AnthonyWJones

+0

ओह! आप सही हैं, मैंने गलत लिंक में अपने लिंक चिपकाए :) धन्यवाद –

1

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

2

टी-एसक्यूएल एक अनिवार्य भाषा होने के लिए डिज़ाइन नहीं किया गया है। यह घोषणात्मक होने के लिए डिज़ाइन किया गया है। इसकी घोषणात्मक प्रकृति ऑप्टोमाइज़र को विभिन्न कार्यों को टुकड़ा करने और उन्हें पैरारल में चलाने की अनुमति देती है और अन्य तरीकों से चीजों को एक क्रम में करते हैं जो सबसे अधिक कुशल है।

-2

मैं डीबी में एक विशेषज्ञ नहीं हूं लेकिन मेरा मानना ​​है कि डेटाबेस लेनदेन की परमाणु प्रकृति लूप को हासिल करना मुश्किल करेगी क्योंकि लेनदेन पूरा हो जाएगा या यह बिल्कुल नहीं होना चाहिए। राज्य बनाए रखना अजीब हो सकता है!

Wikipedia Article on Atomicity

0

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

जबकि, सबसे आम पाशन संरचना है कर्सर भी इस्तेमाल किया जा सकता है, लेकिन अपने स्वयं के समस्याओं

... जबकि का एक उदाहरण (यदि आपको इसकी आवश्यकता नहीं हो सकता है, लेकिन दूसरों हो सकता है (पुनःआवंटन लिए/बंद भूल) है)

DECLARE @iterator INT 
SET @iterator = 0 

WHILE @iterator < 20 
BEGIN 
    SELECT * FROM table WHERE rowKey = @iterator 
/*do stuff*/ 
    @iterator = @iterator + 1 
END 

वास्तविक सवाल यह है कि "यह क्या है कि आप ऐसा करने की कोशिश कर रहे हैं जो बस एक सेट आधारित तरीके से नहीं किया जा सकता है?"

10

मैं कारणों में से एक टन मैं एक क्वेरी परिणाम सेट के माध्यम से पार्स और कुछ है कि बस एक पाश

बिना और के विशाल बहुमत के लिए नहीं किया जा सकता क्या करना चाहते हैं, उसके बारे में सोच सकते मैं या तो आपको दिखा सकता हूं कि इसे सेट-आधारित ऑपरेशन में कैसे किया जाए या समझाएं कि यह डेटाबेस के बजाए आपके क्लाइंट कोड में क्यों किया जाना चाहिए। एसक्यूएल में एक लूप करने की आवश्यकता दुर्लभ है।

+1

मैं मानता हूं कि उन्हें क्लाइंट कोड में किया जाना चाहिए; हालांकि, जब हम लाखों अभिलेखों को संसाधित कर रहे हैं तो यह डेटाबेस में सब कुछ करने के लिए 100x (1000x?) तेज़ है, भले ही यह करने के लिए उचित "स्थान" न हो। –

+1

एक उदाहरण: डेटाबेस में प्रत्येक "फिटनेस" के माध्यम से लूप करें और एक संग्रहित प्रक्रिया करें जो एक तालिका में प्रवेश करती है और फिटनेस के मानों के आधार पर किसी अन्य को अपडेट करती है। हमें इसे नियमित रूप से चलाने की ज़रूरत है, क्योंकि मानों की गणना की जाने वाली सारणी नियमित रूप से बदल जाती हैं। ग्राहक कोड = 1 दिन, एसक्यूएल = 1hr। –

+1

> "मैं मानता हूं कि उन्हें क्लाइंट कोड में किया जाना चाहिए, हालांकि," ... यह केवल इसका एक हिस्सा है। दूसरा सेट आधारित होने के लिए refactoring है। अपने "फिटनेस" उदाहरण के लिए, आपको पूरी तालिका पर काम करने के लिए अपनी संग्रहीत प्रक्रिया को फिर से लिखने में सक्षम होना चाहिए। –

1

लगभग सब कुछ आधार पर सेट किया जाता है, एक नंबर तालिका

क्यों 20 लाइनों का उपयोग करके देखें? यह सब आपको

select *,identity(int, 1,1) as Someid into #temp 
from sysobjects 

declare @id int, @MaxId int 
select @id = 1,@MaxId = max(Someid) from #temp 

while @id < @MaxId 
begin 
-- do your stuff here 
print @id 
set @id [email protected] + 1 
end 
1

यह निर्भर करता है कि आप एक लूप में क्या करना चाहते हैं।थोड़ी देर के पाश का उपयोग कर बिल्कुल मुश्किल नहीं है:

declare @i int 
set @i = 20 
while @i>0 begin 
... do some stuff 
set @i = @i-1 
end 

यह केवल बोझिल हो जाता है जब कर्सर, जो वैसे भी बचा जाना चाहिए का उपयोग कर।

1

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

+0

मुझे यह पसंद है। मैं जांच करने जा रहा हूँ। –

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