SQL Server 2008 में लूप करते समय करें


120

do whileSQL सर्वर 2008 में लूप को लागू करने के लिए कोई विधि है ?


5
राहुल द्वारा दिया गया उत्तर सही है लेकिन वास्तव में आप क्या हासिल करना चाहते हैं? आधारित समाधानों की तुलना में लूप महंगे हैं। शायद एक लूप से पूरी तरह से बचना संभव है।
लेवेन केर्सेमेकर्स

यदि संभव हो तो छोरों का उपयोग न करें और मैं अनुमान लगाऊंगा कि 95% समय या इससे अधिक संभव है कि उनसे बचें। लूप्स और कर्सर्स प्रदर्शन हत्यारे हैं और कभी भी उन लोगों द्वारा नहीं लिखा जाना चाहिए जो कम से कम पांच साल के प्रदर्शन ट्यूनिंग के साथ एक अनुभवी डीबीए नहीं हैं।
HLGEM

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

जवाबों:


190

मुझे MS SQL Server 2008 में DO-WHILE IN के बारे में निश्चित नहीं है लेकिन आप अपने WHILE लूप लॉजिक को बदल सकते हैं, ताकि DO-WHILE लूप की तरह उपयोग कर सकें।

उदाहरण यहाँ से लिए गए हैं: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-ward-loop-with-continue-and-break-swords/

  1. WHILE लूप का उदाहरण

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
    END
    GO

    परिणाम सेट:

    1
    2
    3
    4
    5
  2. BREAK कीवर्ड के साथ WHILE लूप का उदाहरण

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
        IF @intFlag = 4
            BREAK;
    END
    GO

    परिणाम सेट:

    1
    2
    3
  3. WHIN लूप का उदाहरण CONTINUE और BREAK कीवर्ड के साथ

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
        CONTINUE;
        IF @intFlag = 4 -- This will never executed
            BREAK;
    END
    GO

    परिणाम सेट:

    1
    2
    3
    4
    5

लेकिन डेटाबेस स्तर पर छोरों से बचने की कोशिश करें । संदर्भ


17
वही उदाहरण यहाँ दिए गए हैं, क्या आप इस वेबसाइट के लेखक हैं? blog.sqlauthority.com/2007/10/24/…
अनार खलीलोव

1
वह नहीं है, लेकिन यह क्यों मायने रखता है? सही उत्तर दिया गया था। एक अन्य वेबसाइट से लिंक करना एक दर्द है, यहाँ उत्तर को कॉपी और पेस्ट करना सहायक है।
ज्योफ ग्रिसवल्ड

61

यदि आप GOTOकीवर्ड से बहुत नाराज नहीं हैं , तो इसका उपयोग T-SQL में a DO/ simulate करने के लिए किया जा सकता है WHILE। Pseudocode में लिखे गए बल्कि निरर्थक उदाहरण पर विचार करें:

SET I=1
DO
 PRINT I
 SET I=I+1
WHILE I<=10

यहाँ गोटो का उपयोग करते हुए बराबर T-SQL कोड है:

DECLARE @I INT=1;
START:                -- DO
  PRINT @I;
  SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10

GOTOसक्षम समाधान और मूल DO/ WHILEस्यूडोकोड के बीच एक से एक मैपिंग पर ध्यान दें । WHILEलूप का उपयोग करते हुए एक समान कार्यान्वयन इस तरह दिखेगा:

DECLARE @I INT=1;
WHILE (1=1)              -- DO
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF NOT (@I<=10) BREAK; -- WHILE @I<=10
 END

अब, आप निश्चित रूप से इस विशेष उदाहरण को एक साधारण WHILEलूप के रूप में फिर से लिख सकते हैं , क्योंकि यह DO/ WHILEनिर्माण के लिए इतना अच्छा उम्मीदवार नहीं है । उदाहरण के लिए प्रयोज्यता के बजाय संक्षिप्तता पर जोर दिया गया था, क्योंकि वैध मामलों की आवश्यकता होती है a DO/ WHILEदुर्लभ हैं।


REPEAT / UNTIL, कोई भी (T-SQL में काम नहीं करता है)?

SET I=1
REPEAT
  PRINT I
  SET I=I+1
UNTIL I>10

... और GOTOटी-एसक्यूएल में आधारित समाधान:

DECLARE @I INT=1;
START:                    -- REPEAT
  PRINT @I;
  SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10

कीवर्ड के GOTOमाध्यम से और तर्क व्युत्क्रम के रचनात्मक उपयोग के माध्यम से NOT, मूल स्यूडोकोड और GOTOआधारित समाधान के बीच एक बहुत करीबी रिश्ता है । WHILEलूप का उपयोग करने वाला एक समान समाधान जैसा दिखता है:

DECLARE @I INT=1;
WHILE (1=1)       -- REPEAT
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF @I>10 BREAK; -- UNTIL @I>10
 END

एक तर्क दिया जा सकता है कि REPEAT/ UNTIL, के मामले के लिएWHILE आधारित समाधान सरल है, क्योंकि यदि स्थिति उलटी नहीं है। दूसरी ओर यह अधिक क्रियात्मक भी है।

यदि यह सभी के उपयोग के आसपास तिरस्कार के लिए नहीं था GOTO , तो ये कुछ समय के लिए मुहावरेदार समाधान भी हो सकते हैं, जब ये विशेष (बुराई) लूपिंग निर्माण स्पष्टता के लिए टी-एसक्यूएल कोड में आवश्यक होते हैं।

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


6
+1: निश्चित रूप से स्वीकृत उत्तर की तुलना में बेहतर प्रश्न का उत्तर देता है।
लुई कोट्टमन

मैं WHILE (1 = 1) दृष्टिकोण को पसंद करता हूं, क्योंकि यह खतरनाक GOTO का उपयोग किए बिना उद्देश्य को कार्यात्मक रूप से फिट करता है।
kad81

दोनों विधियां मान्य हैं। मुझे गोटो का उपयोग करते हुए छद्म लूप पसंद है, यह काफी चतुर है।
ज्यॉफ ग्रिस्वाल्ड

18

मैं एक बार से अधिक यह लेख पढ़ याद करने लगते हैं, और जवाब केवल है पास मैं क्या जरूरत है।

आमतौर पर जब मुझे लगता है कि मुझे DO WHILEटी-एसक्यूएल में जरूरत पड़ने वाली है , क्योंकि मैं एक कर्सर को परेशान कर रहा हूं, और मैं काफी हद तक इष्टतम स्पष्टता (बनाम इष्टतम गति) की तलाश में हूं। T-SQL में जो a WHILE TRUE/ fit लगता है IF BREAK

यदि यह ऐसा परिदृश्य है जो आपको यहां लाया है, तो यह स्निपेट आपको एक पल बचा सकता है। अन्यथा, मेरा स्वागत है, मुझे। अब मैं निश्चित हो सकता हूं कि मैं यहां एक से अधिक बार गया हूं। :)

DECLARE Id INT, @Title VARCHAR(50)
DECLARE Iterator CURSOR FORWARD_ONLY FOR
SELECT Id, Title FROM dbo.SourceTable
OPEN Iterator
WHILE 1=1 BEGIN
    FETCH NEXT FROM @InputTable INTO @Id, @Title
    IF @@FETCH_STATUS < 0 BREAK
    PRINT 'Do something with ' + @Title
END
CLOSE Iterator
DEALLOCATE Iterator

दुर्भाग्य से, टी-एसक्यूएल इस अनंत लूप की तुलना में, लूप ऑपरेशन को एकल-परिभाषित करने के लिए एक क्लीनर तरीका प्रदान नहीं करता है।


एक कर्सर का उपयोग करना कभी भी एक अच्छा विकल्प नहीं है क्योंकि यह बहुत अधिक संसाधन लेता है जिसकी वास्तव में आवश्यकता होती है।
हंटरट्रीट

10
@greektreat: डाउनवोट के लिए धन्यवाद :), लेकिन मैं उलझन में हूँ! यदि "एक कर्सर कभी अच्छा विकल्प नहीं होता है", तो यह हमेशा एक अच्छा विकल्प होना चाहिए, इसलिए नीचे की ओर क्यों? गंभीरता से, हालांकि, स्पष्ट रूप से शाप देने वालों के कई व्यावहारिक उपयोग हैं: निजी तालिकाओं के खिलाफ, छोटे कार्यों के लिए जहां रखरखाव कार्यों के लिए स्पष्टता / संक्षिप्तता> प्रदर्शन, जहां निर्धारक संचालन उपलब्ध नहीं हैं, कुछ परिचालन के लिए परमाणु लेनदेन के रूप में होना चाहिए, आदि। मेरे हाल के मामले में, मैं एक आने वाली तालिका चर, मेरी संग्रहीत प्रक्रिया के लिए निजी ingesting था। एक पूर्ण वचनबद्धता कभी भी एक अच्छा विचार नहीं है!
शैनन

5
@grictreat: सारांश में, कभी-कभी डेटा को पुनरावृत्त करना केवल विकल्प है। मुझे लगता है कि आप अभी भी तर्क कर सकते हैं कि यह उस मामले में एक अच्छा विकल्प नहीं है, लेकिन इसका मतलब यह नहीं है कि इस तरह का कोड अनावश्यक है और डाउनटाउन की जरूरत है।
शैनन

1
मुझे लगता है कि इंटरनेट पर लोगों की एक कठोर सेना है जो एसक्यूएल में लूप और कर्सर का उपयोग करने वाले अन्य लोगों के बारे में बहुत, बहुत गुस्से में हैं। इस वेबसाइट पर अगर आप एसक्यूएल में लूप का उपयोग करने के बारे में 30 सेकंड के लिए उल्लेख करते हैं, तो बाद में आपका इनबॉक्स अज्ञानी लोगों से भर जाएगा, जो आपको किसी भी परिस्थिति में उनका उपयोग नहीं करने के लिए कह रहे हैं ...
जियोफ ग्रिसवल्ड

4

यदि आप चाहते हैं कि आपका कोड थोड़ा अधिक पठनीय हो तो आप एक निकास चर का उपयोग कर सकते हैं:

DECLARE @Flag int = 0
DECLARE @Done bit = 0

WHILE @Done = 0 BEGIN
    SET @Flag = @Flag + 1
    PRINT @Flag
    IF @Flag >= 5 SET @Done = 1
END

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


मेरा मतलब है ... हम एक ऐसे युग में रहते हैं जहां हमारे डेटाबेस सर्वरों में किसी भी समय 10 और 20 सीपीयू कोर निष्क्रिय होते हैं, और जहां हमारे स्टोरेज कंट्रोलर्स के पास गिगाबिट्स में मापा बैंडविड्थ उपलब्ध हैं, इसलिए मुझे यकीन नहीं है कि यह पारंपरिक है " ज्ञान "कि" लूप = बीएडी "अभी भी लागू होता है।
ज्योफ ग्रिसवल्ड

1

केवल जबकि लूप आधिकारिक तौर पर SQL सर्वर द्वारा समर्थित है। पहले से ही जवाब है लूप के दौरान डीओ के लिए । मैं SQL सर्वर में विभिन्न प्रकार के लूप प्राप्त करने के तरीकों पर उत्तर का विवरण दे रहा हूं।

यदि आप जानते हैं, तो आपको लूप के पहले पुनरावृत्ति को पूरा करने की आवश्यकता है, फिर आप SQL सर्वर का DO..WHILE या REPEAT..UNTIL संस्करण आज़मा सकते हैं ।

DO.HILE लूप

DECLARE @X INT=1;

WAY:  --> Here the  DO statement

  PRINT @X;

  SET @X += 1;

IF @X<=10 GOTO WAY;

REPEAT..UNTIL लूप

DECLARE @X INT = 1;

WAY:  -- Here the REPEAT statement

  PRINT @X;

  SET @X += 1;

IFNOT(@X > 10) GOTO WAY;

पाश के लिए

DECLARE @cnt INT = 0;

WHILE @cnt < 10
BEGIN
   PRINT 'Inside FOR LOOP';
   SET @cnt = @cnt + 1;
END;

PRINT 'Done FOR LOOP';

संदर्भ


यह stackoverflow.com/a/46362450/8239061 से कॉपी-पेस्ट-रिकॉर्डर जैसा लगता है ।
सीक्रेटअजेंटमैन

@SecretAgentMan: दोनों जवाब अलग-अलग सवालों के जवाब दे रहे हैं। दोनों उत्तरों में दिया गया अतिरिक्त डेटा।
सोमनाथ मुलुक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.