त्रुटि: set_valued फ़ंक्शन को संदर्भ में कहा जाता है जो एक सेट को स्वीकार नहीं कर सकता है। यह किस बारे में है?


11

मैं Postgresql 9.1 का उपयोग करता हूं, ubuntu 12.04 के साथ।

मेरे सवाल का क्रेग की जवाब से प्रेरित होकर setof प्रकार या setof रिकॉर्ड के संयोजन मैंने सोचा कि मैं का उपयोग कर के साथ अच्छी तरह से जाना होगा return query, setof recordहै, और इस plpgsql समारोह में एक श्रृंखला जनरेटर:

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns setof record as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$    language plpgsql;

निष्पादन के दौरान मुझे त्रुटि मिलती है:

ERROR: set_valued function called in context that cannot accept a set

गलत क्या है ? क्रेग के विपरीत मैं फ़ंक्शन को वापस जाने के लिए कहता हूं setof record

मैं कुछ ऐसा हासिल कर सकता हूं जो क्रैग की तरह काम कर रहा है, यानी एक प्रकार को परिभाषित करके create type pair_id_value as (idx bigint, value integer)और मेरे plpgsql फ़ंक्शन के setof of pair_id_valueबजाय एक रिटर्न देता है setof record

लेकिन इस काम के समाधान के साथ, मुझे अभी भी समझ में नहीं आता है कि select id, generate_series(0,13)अकेले दो कॉलम में परिणाम क्यों लौटाएगा ... और इसके विपरीत फ़ंक्शन (रिटर्न सेटॉफ़ पेयर_ड_वल्यू) के साथ केवल एक कॉलमreturn query select id, generate_series(0,my_obj.value) from my_obj में परिणाम लौटाएगा जो फ़ील्ड की तरह दिखता है यह "(123123,0)" "(123123,1)" "(123123,2)" (3 पंक्तियाँ) जो स्पष्ट रूप से ट्यूपर हैं।

क्या यह ऐसा मामला है जहां एक अस्थायी तालिका बनाई जानी चाहिए / होनी चाहिए?


यह आपके द्वारा चलाए जा रहे फ़ंक्शन का सटीक पाठ नहीं हो सकता क्योंकि यह संकलन नहीं करता है; के बाद एक अतिरिक्त अर्धविराम है BEGINऔर एक के बाद एक लापता है RETURN QUERY। उन त्रुटियों को सुधारने के बाद, मैं लौटते समय त्रुटि की पुष्टि करता हूं record; उत्तर में बताएंगे।
क्रेग रिंगर

@ क्रैगरिंगर मैंने अर्धविराम को वापस जगह में डाल दिया।
स्टीफन रोलैंड

जवाबों:


7

त्रुटि संदेश बहुत उपयोगी नहीं है:

regress=> SELECT * FROM  compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM  compute_all_pair_by_craig(100);

लेकिन यदि आप क्वेरी को इसे एक उचित सेट-रिटर्निंग फ़ंक्शन के रूप में कॉल करते हैं, तो आपको वास्तविक समस्या दिखाई देगी:

regress=> SELECT * FROM compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM compute_all_pair_by_craig(100);

यदि आप SETOF RECORDएक OUTपैरामीटर सूची के बिना उपयोग कर रहे हैं तो आपको कॉलिंग स्टेटमेंट में परिणाम निर्दिष्ट करना होगा, जैसे:

regress=> SELECT * FROM compute_all_pair_by_craig(100) theresult(a integer, b integer);

हालांकि, यह उपयोग RETURNS TABLEया OUTमापदंडों के लिए बहुत बेहतर है । पूर्व वाक्य रचना के साथ आपका कार्य होगा:

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns table(a integer, b integer) as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$ language plpgsql;

यह सेलेक्ट-लिस्ट के संदर्भ में कॉल करने योग्य है और कॉल साइट पर परिणाम संरचना को स्पष्ट रूप से निर्दिष्ट किए बिना या इसका उपयोग किया जा सकता है।


प्रश्न के उत्तरार्ध के लिए, जो हो रहा है वह यह है कि 1 केस एक सेलेक्ट-लिस्ट में दो अलग-अलग कॉलमों को निर्दिष्ट करता है, दूसरा एक एकल कंपोजिट देता है। यह वास्तव में ऐसा नहीं है कि आप परिणाम कैसे लौटा रहे हैं, लेकिन आप फ़ंक्शन को कैसे लागू कर रहे हैं। यदि हम नमूना समारोह बनाते हैं:

CREATE OR REPLACE FUNCTION twocols() RETURNS TABLE(a integer, b integer) 
AS $$ SELECT x, x FROM generate_series(1,5) x; $$ LANGUAGE sql;

सेट-रिटर्निंग फ़ंक्शन को कॉल करने के लिए आपको दो तरीकों से अंतर दिखाई देगा - SELECTसूची में, क्वर्की व्यवहार के साथ एक पोस्टग्रैसक्यूएल विशिष्ट गैर-मानक एक्सटेंशन:

regress=> SELECT twocols();
 twocols 
---------
 (1,1)
 (2,2)
 (3,3)
 (4,4)
 (5,5)
(5 rows)

या अधिक मानक तरीके से तालिका के रूप में:

regress=> SELECT * FROM twocols();
 a | b 
---+---
 1 | 1
 2 | 2
 3 | 3
 4 | 4
 5 | 5
(5 rows)

बस परीक्षण किया, सही काम करता है। और मुझे यह वाक्य रचना पसंद है returns table
स्टीफन रोलैंड

@StephaneRolland प्रश्न के उत्तरार्द्ध के स्पष्टीकरण के साथ अपडेट किया गया।
क्रेग रिंगर

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