2016-10-11 14 views
6

मैं पीएल/पीजीएसक्यूएल में कुछ घोंसले (या आंतरिक) कार्यों के साथ एक फ़ंक्शन बनाना चाहता हूं। इस तरह मैं समस्या को छोटे टुकड़ों में तोड़ सकता हूं लेकिन मेरे छोटे टुकड़े इस समारोह के बाहर सुलभ नहीं हैं।मैं पीएल/पीजीएसक्यूएल में नेस्टेड फ़ंक्शन कैसे बना सकता हूं?

क्या पीएल/पीजीएसक्यूएल में ऐसा करना संभव है? यदि हां, तो कैसे?

+0

आप ऐसा क्यों करेंगे? मेरे लिए अव्यवहारिक लगता है। आप बिना किसी फ़ंक्शन के समस्या को छोटे टुकड़ों में तोड़ सकते हैं या यदि आपको वास्तव में इसकी आवश्यकता है - उन पर विशेषाधिकार समायोजित करें। –

उत्तर

2

नेस्टेड फ़ंक्शंस PLpgSQL द्वारा समर्थित नहीं हैं। अनुकरण का कोई अर्थ नहीं है और यह अनुत्पादक है।

+1

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

+0

@ ग्रेगरी एरियनियस: मैंने कुछ उदाहरण के साथ खेलना शुरू किया, यह "आंतरिक" फ़ंक्शन को हर बार "बाहरी" फ़ंक्शन बनाता है ("बाहरी" फ़ंक्शन के रूप में) उसी समय में "बाहरी" फ़ंक्शन के रूप में बनाता है, इसलिए अजीब त्रुटियां होती हैं। यह बिल्कुल "आंतरिक कार्य" नहीं है, और इसके पास "बाहरी" के आंतरिक दायरे तक पहुंच नहीं है। –

7

यह प्रयास करें:

CREATE OR REPLACE FUNCTION outer() RETURNS void AS $outer$ 
DECLARE s text; 
BEGIN 
    CREATE OR REPLACE FUNCTION inner() RETURNS text AS $inner$ 
    BEGIN 
    RETURN 'inner'; 
    END; 
    $inner$ language plpgsql; 

    SELECT inner() INTO s; 
    RAISE NOTICE '%', s; 

    DROP FUNCTION inner(); 
END; 
$outer$ language plpgsql; 

postgres में 9.5 SELECT outer(); आउटपुट

psql:/vagrant/f.sql:14: NOTICE: inner 

संपादित करें: यदि आप बाहरी समारोह के अंत में आंतरिक समारोह ड्रॉप नहीं है यह व्यक्तियों को दिखाई देंगे बाकी डेटाबेस।

+2

कुछ और चीजों को इस बात की ओर इशारा करते हुए इंगित करने के लिए: आप आंतरिक और बाहरी दोनों कार्यों के लिए 'AS $$' का उपयोग नहीं कर सकते हैं। साथ ही, यदि आपके फ़ंक्शन में तर्क हैं तो आपको उस फ़ंक्शन को छोड़ते समय टाइप करना होगा। और आप बाहरी कार्यों के 'DECLARE' भाग में अपने कार्यों को कॉल नहीं कर सकते क्योंकि वे अभी तक नहीं बनाए गए हैं। नेस्टेड फ़ंक्शंस के निर्माण के बाद बस वैरिएबल बनाएं और इसे मान दें। –

+2

@ ग्रेगरी: एक और महत्वपूर्ण बात: यदि दो समवर्ती लेन-देन इस फ़ंक्शन को कॉल करने का प्रयास करते हैं, तो दूसरा व्यक्ति फ़ंक्शन नामों पर डेटाबेस की विशिष्टता बाधा के कारण आंतरिक 'CREATE' पर अवरुद्ध करेगा। आप अपने सत्र के अस्थायी स्कीमा में आंतरिक फ़ंक्शन डालकर इस पर काम कर सकते हैं, यानी 'CREATE FUNCTION pg_temp.inner() 'का उपयोग करके। अतिरिक्त लाभ यह है कि आंतरिक कार्य कभी भी बाहरी रूप से दिखाई नहीं देते हैं, और आपके सत्र के बाद स्वचालित रूप से साफ़ हो जाते हैं। –

+2

@ ग्रेगरी: वैसे, 'DECLARE ... BEGIN ... END' ब्लॉक को घोंसला जा सकता है, ताकि आंतरिक कार्य बनने के बाद आप अपनी घोषणाएं कर सकें –

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