क्या पीएल / पीजीक्यूसी में एक सरल तरीका है यह जांचने के लिए कि क्या कोई प्रश्न वापस नहीं आया है?


16

मैं वर्तमान में PL / pgSQL के साथ थोड़ा प्रयोग कर रहा हूं और जानना चाहता हूं कि क्या ऐसा कुछ करने के लिए और अधिक सुंदर तरीका है:

select c.data into data from doc c where c.doc_id = id and c.group_cur > group_cur order by c.id desc limit 1;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        select c.data into data from doc c where c.doc_id = id and c.global_cur > global_cur order by c.id desc limit 1;
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN NULL;

जवाबों:


21

अपवाद ब्लॉक त्रुटियों को फंसाने के लिए हैं, स्थितियों की जाँच नहीं। दूसरे शब्दों में, यदि संकलित समय में कुछ स्थिति को संभाला जा सकता है, तो इसे त्रुटि के रूप में नहीं फँसाया जाना चाहिए बल्कि साधारण प्रोग्राम लॉजिक द्वारा हल किया जाना चाहिए।

PL / PgSQL डॉक्यूमेंटेशन के एरैपर्स सेक्शन में फंसने पर आप ऐसे टिप पा सकते हैं:

युक्ति: एक ब्लॉक वाला एक खंड खंड में प्रवेश करने और एक के बिना एक ब्लॉक से बाहर निकलने के लिए काफी अधिक महंगा है। इसलिए, आवश्यकता के बिना निष्कासन का उपयोग न करें।

अपवादों (खराब), या IF / THEN / ELSIF (बेहतर) का उपयोग करने के बजाय, आप इसे एक क्वेरी में फिर से लिख सकते हैं:

SELECT c.data into data
FROM  doc c
WHERE c.doc_id = id
  and (
    c.group_cur > group_cur
    or
    c.global_cur > global_cur
  )
ORDER BY
  -- this will make group always preferred over global
  case when c.group_cur > group_cur then 1 else 2 end ASC,
  -- and this is your normal ordering
  c.id DESC
limit 1;

यदि आप वास्तव में दो प्रश्न चाहते हैं, तो आप परीक्षण के लिए विशेष ध्वनि चर का उपयोग कर सकते हैं यदि पिछली क्वेरी ने कोई परिणाम दिया हो:

select c.data into data
from doc c
where c.doc_id = id and c.group_cur > group_cur
order by c.id desc limit 1;
if not found then
    select c.data into data
    from doc c
    where c.doc_id = id and c.global_cur > global_cur
    order by c.id desc limit 1;
    if not found then return null; end if;
end if;

अप्रचलित आरटीएफएम लिंक folllow :-)

चर के विवरण के लिए इसे देखें FOUND, और इसके लिए IF/ THENब्लॉक करें।


13

आप एक विशेष प्रकार के बूलियन के चर की जांच कर सकते हैं। प्रलेखन से:

प्रत्येक PL / pgSQL फ़ंक्शन कॉल के भीतर फ़ॉउड झूठी शुरू होता है। यह निम्न प्रकार के कथनों में से प्रत्येक द्वारा निर्धारित किया गया है:

यदि कोई पंक्ति नहीं दी जाती है, तो एक सही INTO स्टेटमेंट फ़ॉउंड को सही सेट करता है।

यदि कोई पंक्ति निर्मित नहीं हुई है, तो एक पूर्ण कथन एक या अधिक पंक्तियों को उत्पन्न करने (और डिस्क्राइब करने) के लिए सही है।

UPDATE, INSERT और DELETE कथनों को सही माना जाता है यदि कोई पंक्ति प्रभावित नहीं होती है, तो कम से कम एक पंक्ति प्रभावित होती है।

यदि कोई पंक्ति वापस नहीं आती है, तो FETCH का कथन सत्य को सेट करता है, यदि यह एक पंक्ति लौटाता है, तो गलत है।

यदि यह सफलतापूर्वक कर्सर को गलत ढंग से रिपॉजिट करता है, तो एक MOVE स्टेटमेंट सही है।

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

RETURN QUERY और RETURN QUERY EXECUTE कथनों को सही मानते हैं यदि क्वेरी कम से कम एक पंक्ति में लौटती है, तो कोई पंक्ति वापस न होने पर झूठी।

अन्य PL / pgSQL स्टेटमेंट FOUND की स्थिति को नहीं बदलते हैं। विशेष रूप से ध्यान दें कि EXECUTE GET DIAGNOSTICS का आउटपुट बदलता है, लेकिन FOUND नहीं बदलता है।

प्रत्येक PL / pgSQL फ़ंक्शन के भीतर FOUND एक स्थानीय चर है; इसमें कोई भी परिवर्तन केवल वर्तमान फ़ंक्शन को प्रभावित करता है।


लेकिन select intoकोई रिटर्न नहीं डेटा अभी भी एक अपवाद, सही उठाएगा?
जैक का कहना है कि topanswers.xyz

3
आम तौर पर नहीं, यह अपवाद तभी बढ़ाता है जब STRICT क्लॉज निर्दिष्ट किया जाता है, जैसे SELECT * INTO
STRICT

आह हां, मेरा बुरा - हालांकि इसका मतलब यह नहीं है कि ओपी उदाहरण में अपवाद हैंडलर कभी भी आग नहीं लगाएगा? :-)
जैक का कहना है कि topanswers.xyz

1
@JackDouglas: कोई भी डेटा आम तौर पर अपवाद का कारण नहीं होता है (ऊपर विशेष रूप से STRICT संशोधक जैसे मामलों को छोड़कर)। ओपी को वहां गलत धारणा थी।
एरविन ब्रान्डेसटेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.