नियमित लूप के बजाय स्पष्ट कर्सर का उपयोग क्यों करें?


12

मैं एक साल के लिए (ओरेकल डीबी के लिए) बेसिक वेब ऐप्स लिख रहा हूं, और चूंकि फ़ंक्शन बहुत सरल हैं, हम में से ज्यादातर अपना डेटा प्राप्त करने के लिए नियमित रूप से लूप्स के साथ चिपके रहते हैं:

for i in (select * from STUDENTS) loop
      htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;

लेकिन, श्रोताओं को चीजें करने का 'सही' तरीका लगता है। मुझे इस बारे में बहुत सारी जानकारी मिल सकती है कि शाप देने वाले क्या हैं और उनके माध्यम से लूप करने के विभिन्न तरीके हैं, लेकिन मुझे कोई ठोस कारण नहीं मिल सकता है कि उन्हें नियमित रूप से छोरों पर उपयोग करने के लिए क्यों। क्या यह प्रक्रिया की जरूरतों पर निर्भर है? क्या ऐसे निहित लाभ हैं जिनकी मुझे जानकारी होनी चाहिए?


इस प्रकार का FORसिर्फ एक और तरीका है कि कर्सर का उपयोग करें। डॉक्स देखें: docs.oracle.com/cd/E11882_01/appdev.112/e10472/… फिर भी, क्या htp.prn () करता है?
dezso

यह हमारे आउटपुट कार्यों में से एक है। तो, क्या आपको पसंद है कि किस विधि का उपयोग करना है?
इनि

इस तरह की चीजों के लिए FORलूप बहुत अधिक पठनीय है, मुझे लगता है। मैं 'असली' कोर्स का इस्तेमाल तभी करता हूं जब मुझे पीछे की तरफ कदम बढ़ाना होता है, न कि सिर्फ आगे की ओर। मैंने वह अन्य प्रश्न पूछा क्योंकि मैं इसके बजाय एक टेबल फ़ंक्शन की कल्पना कर सकता हूं htp.prn()
dezso

यह ध्यान देने योग्य है कि कर्सर के दोनों रूपों का शुद्ध SQL समाधान के लिए हीन प्रदर्शन है - विशेष रूप से डीएमएल बयानों के लिए प्रासंगिक।
डेविड एल्ड्रिज

जवाबों:


7

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

  1. लूप के लिए एक अंतर्निहित कर्सर पर लूप के लिए एक स्पष्ट कर्सर का उपयोग क्यों करें?

    • लूप के लिए एक स्पष्ट कर्सर का उपयोग करें जब क्वेरी का पुन: उपयोग किया जाएगा, अन्यथा एक अंतर्निहित कर्सर पसंद किया जाता है।
  2. फ़ॉरच के बजाय लूप का उपयोग फ़ॉर लूप के बजाय एक स्पष्ट फ़ेच के साथ क्यों करें?

    • जब आपको बल्क कलेक्ट करने की आवश्यकता हो या जब आपको डायनेमिक एसक्यूएल की आवश्यकता हो, तो लूप के अंदर एक फेट का उपयोग करें।

यहाँ प्रलेखन से कुछ उपयोगी जानकारी दी गई है।

लूप के लिए इंप्लिमेंटेड कॉसर का उदाहरण

BEGIN
   FOR vItems IN (
      SELECT last_name
      FROM employees
      WHERE manager_id > 120
      ORDER BY last_name
   ) 
   LOOP
      DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
   END LOOP;
END;
/

LOOP के लिए स्पष्ट कर्सर का उदाहरण

DECLARE
   CURSOR c1 IS
      SELECT last_name
      FROM employees
      WHERE manager_id > 120
      ORDER BY last_name;
BEGIN
   FOR vItems IN c1 LOOP
      DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
   END LOOP;
END;
/

अव्यवस्थित कर्सर

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

एक अंतर्निहित कर्सर अपने संबंधित बयान के चलने के बाद बंद हो जाता है; हालाँकि, इसका विशेषता मान तब तक उपलब्ध रहता है जब तक एक और SELECT या DML स्टेटमेंट नहीं चलता है।

निहित कर्सर विशेषताएँ हैं: SQL% ISOPEN, SQL% FOUND, SQL% NOTFOUND, SQL% ROWCOUNT, SQL% BULK_ROWCOUNT, SQL% BULK_EXCEPTIONS

स्पष्ट कर्सर

एक स्पष्ट कर्सर एक सत्र कर्सर है जिसे आप बनाते हैं और प्रबंधित करते हैं। आपको एक स्पष्ट कर्सर घोषित और परिभाषित करना होगा, इसे एक नाम देना और इसे एक क्वेरी के साथ जोड़ना होगा (आमतौर पर, क्वेरी कई पंक्तियों को लौटाती है)। फिर आप इनमें से किसी भी तरीके से सेट किए गए क्वेरी परिणाम को संसाधित कर सकते हैं:

स्पष्ट कर्सर खोलें (OPEN स्टेटमेंट के साथ), परिणाम सेट से पंक्तियाँ प्राप्त करें (FETCH स्टेटमेंट के साथ), और स्पष्ट कर्सर को बंद करें (CLOSE स्टेटमेंट के साथ)।

LOOP स्टेटमेंट के लिए एक कर्सर में स्पष्ट कर्सर का उपयोग करें (देखें "क्वेरी स्टेटमेंट के लिए कर्सर के साथ क्वेरी रिजल्ट सेट प्रोसेसिंग")।

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

एक अंतर्निहित कर्सर के विपरीत, आप अपने नाम से एक स्पष्ट कर्सर या कर्सर चर का संदर्भ ले सकते हैं। इसलिए, एक स्पष्ट कर्सर या कर्सर चर को नामित कर्सर कहा जाता है।

लोड स्टेटमेंट के लिए कर्सर

LOOP स्टेटमेंट के लिए कर्सर आपको सेलेक्ट स्टेटमेंट चलाने देता है और फिर परिणाम सेट की पंक्तियों के माध्यम से तुरंत लूप करता है। यह कथन एक अंतर्निहित या स्पष्ट कर्सर का उपयोग कर सकता है।


1
प्रबलित श्रापकर्ता 10g से एक बार में 100 पंक्तियों को प्राप्त करते हैं।
डेविड एल्ड्रिज

16

आपके द्वारा पोस्ट किया गया कोड कर्सर का उपयोग कर रहा है। यह एक अंतर्निहित कर्सर लूप का उपयोग कर रहा है।

ऐसे मामले हैं जहां एक स्पष्ट कर्सर लूप का उपयोग किया जाता है (यानी घोषणा अनुभाग में एक CURSOR चर घोषित करना) या तो क्लीनर कोड या बेहतर प्रदर्शन का उत्पादन करता है

  1. यदि आपके पास अधिक जटिल प्रश्न हैं, जिन्हें आप विचारों में शामिल नहीं कर सकते हैं, तो यह कोड को पढ़ने में आसान बना सकता है यदि आपका लूप ओवररेट करता है student_cursorएक 30 लाइन एसक्यूएल बयान को शामिल करने के बजाय जो तर्क का एक गुच्छा एम्बेड करता है। उदाहरण के लिए, यदि आप उन सभी छात्रों को प्रिंट कर रहे थे, जिन्हें स्नातक में उत्तीर्ण किया गया था और जो कि उनके अकादमिक रिकॉर्ड में शामिल थे, उनके डिग्री प्रोग्राम की आवश्यकताएं, शैक्षणिक होल्ड पर जानकारी के साथ टेबल, अति पुस्तकालय की पुस्तकों के बारे में जानकारी के साथ टेबल, अवैतनिक शुल्क, प्रशासनिक ओवरराइड्स इत्यादि के बारे में जानकारी के साथ तालिकाओं में यह कोड को फिर से भरने के लिए समझ में आएगा, ताकि यह क्वेरी उस कोड के बीच में अटक न जाए जो उपयोगकर्ता को सूची प्रस्तुत करने से संबंधित है। इसमें एक ऐसा दृश्य बनाना शामिल हो सकता है जो इस सारे तर्क को ध्वस्त कर दे। या इसमें एक स्पष्ट कर्सर बनाना शामिल हो सकता है जिसे या तो वर्तमान PL / SQL ब्लॉक के हिस्से के रूप में घोषित किया गया था या कुछ उच्च-स्तरीय PL / SQL ब्लॉक (यानी एक पैकेज में घोषित कर्सर) ताकि यह पुन: प्रयोज्य हो। या इसमें एनकैप्सुलेशन और पुन: प्रयोज्यता के लिए कुछ और करना शामिल हो सकता है (कहते हैं, इसके बजाय एक पाइपलाइन टेबल फ़ंक्शन बनाना)।
  2. यदि आप PL / SQL में बल्क ऑपरेशन का उपयोग करना चाहते हैं, तो आप आमतौर पर स्पष्ट कर्सर का उपयोग करना चाहते हैं। यहाँ एक StackOverflow थ्रेड है जो स्पष्ट और अंतर्निहित कर्सर के बीच प्रदर्शन अंतरों पर चर्चा करता है । यदि आप सब कर रहे हैं, तो कॉल कर रहा है htp.prn, BULK COLLECTशायद आप कुछ भी नहीं खरीदते हैं। अन्य मामलों में, हालांकि, इसके परिणामस्वरूप पर्याप्त प्रदर्शन में सुधार हो सकता है।

2

मैं देख रहा हूं कि कई डेवलपर्स पुरानी आदत से बाहर आने वाले अभिशापों के बजाय स्पष्ट कर्सर का उपयोग कर रहे हैं। ऐसा इसलिए है क्योंकि ओरेकल संस्करण 7 में यह हमेशा जाने के लिए अधिक कुशल तरीका था। आजकल आम तौर पर आसपास के दूसरे तरीके हैं। विशेष रूप से ऑप्टिमाइज़र के साथ कि अगर जरूरत हो तो थोक संग्रह के लिए लूप के लिए निहित कर्सर को फिर से लिख सकते हैं।


0

हाल ही में मुझे स्पष्ट कर्सर में निहित लूप के लिए प्रश्नों के एक समूह को फिर से लिखना पड़ा। कारण यह था कि प्रश्नों ने लिंक के माध्यम से बाहरी डेटाबेस से डेटा प्राप्त किया था और इस डेटाबेस में हमारे स्थानीय डेटाबेस की तुलना में एक अलग एन्कोडिंग था। जब अंतर्निहित कर्सर से डेटा को स्थानीय रूप से परिभाषित रिकॉर्ड प्रकार में मिस्टीरियस रुक-रुक कर त्रुटियों को स्थानांतरित किया जाता है (केवल कुछ विशिष्ट पंक्तियों पर)। हमारे डीबीए ने हमें यह समझाया, हम खुद इस बात की तह तक नहीं पहुंच पाए। ऐसा लगता है कि यह Oracle में एक बग है जो रिपोर्ट किया गया है।

हमें स्पष्ट कर्सर का उपयोग करके सब कुछ फिर से लिखने की सलाह दी गई थी और त्रुटि हो गई थी।

प्राथमिक कारण यह नहीं है कि आप निहित पर स्पष्ट उपयोग करना चाहते हैं, लेकिन एक नोट के लायक है।

EDIT: Oracle 12c


क्या आप बग और / या नोट संख्या में जोड़ सकते हैं ताकि इसे पढ़ने वालों को लक्षणों के बारे में अधिक पता चल सके और यदि / जब यह हल हो जाए?
लेह रिफ़ेल

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