आप जो मांगते हैं वह असंभव है . SQL एक कड़ाई से टाइप की जाने वाली भाषा है। PostgreSQL फ़ंक्शंस को रिटर्न प्रकार घोषित करने की आवश्यकता है (RETURNS ..
) निर्माण के समय . पर ।
इसके चारों ओर एक सीमित तरीका बहुरूपी कार्यों के साथ है। यदि आप कार्य के समय कॉल . पर वापसी प्रकार प्रदान कर सकते हैं . लेकिन यह आपके प्रश्न से स्पष्ट नहीं है।
- एक PL/pgSQL फ़ंक्शन को रिफ़ैक्टर करें ताकि विभिन्न SELECT क्वेरीज़ का आउटपुट लौटाया जा सके
आप कर सकते हैं अनाम रिकॉर्ड के साथ पूरी तरह से गतिशील परिणाम लौटाएं। लेकिन फिर आपको प्रत्येक कॉल के साथ कॉलम परिभाषा सूची प्रदान करने की आवश्यकता होती है। और आप लौटे कॉलम के बारे में कैसे जानते हैं? कैच 22.
आपको जिस चीज की जरूरत है या उसके साथ काम कर सकते हैं, उसके आधार पर विभिन्न वर्कअराउंड हैं। चूंकि आपके सभी डेटा कॉलम समान डेटा प्रकार साझा करते हैं, इसलिए मेरा सुझाव है कि एक सरणी . लौटाएं :text[]
. या आप hstore
. जैसे दस्तावेज़ प्रकार वापस कर सकते हैं या json
. संबंधित:
-
CASE और GROUP BY के साथ पिवट करने का डायनामिक विकल्प
-
अज्ञात कुंजियों के सेट के लिए hstore कुंजियों को स्तंभों में गतिशील रूप से रूपांतरित करें
लेकिन केवल दो कॉलों का उपयोग करना आसान हो सकता है:1:पोस्टग्रेज़ को क्वेरी बनाने दें। 2:लौटाई गई पंक्तियों को निष्पादित और पुनर्प्राप्त करें।
- एकल SQL कथन का उपयोग करके अनेक अधिकतम () मानों का चयन करना
जैसा कि आपके प्रश्न बिल्कुल . में प्रस्तुत किया गया है, मैं एरिक मिनिकेल के फ़ंक्शन का उपयोग नहीं करूंगा . यह दुर्भावनापूर्ण रूप से विकृत पहचानकर्ताओं के माध्यम से SQL इंजेक्शन के विरुद्ध सुरक्षित नहीं है। format()
का प्रयोग करें क्वेरी स्ट्रिंग बनाने के लिए जब तक कि आप पोस्टग्रेज़ 9.1 से पुराना पुराना संस्करण नहीं चला रहे हों।
एक छोटा और साफ-सुथरा कार्यान्वयन इस तरह दिख सकता है:
CREATE OR REPLACE FUNCTION xtab(_tbl regclass, _row text, _cat text
, _expr text -- still vulnerable to SQL injection!
, _type regtype)
RETURNS text AS
$func$
DECLARE
_cat_list text;
_col_list text;
BEGIN
-- generate categories for xtab param and col definition list
EXECUTE format(
$$SELECT string_agg(quote_literal(x.cat), '), (')
, string_agg(quote_ident (x.cat), %L)
FROM (SELECT DISTINCT %I AS cat FROM %s ORDER BY 1) x$$
, ' ' || _type || ', ', _cat, _tbl)
INTO _cat_list, _col_list;
-- generate query string
RETURN format(
'SELECT * FROM crosstab(
$q$SELECT %I, %I, %s
FROM %I
GROUP BY 1, 2 -- only works if the 3rd column is an aggregate expression
ORDER BY 1, 2$q$
, $c$VALUES (%5$s)$c$
) ct(%1$I text, %6$s %7$s)'
, _row, _cat, _expr -- expr must be an aggregate expression!
, _tbl, _cat_list, _col_list, _type
);
END
$func$ LANGUAGE plpgsql;
आपके मूल संस्करण के समान फ़ंक्शन कॉल। फ़ंक्शन crosstab()
अतिरिक्त मॉड्यूल tablefunc
. द्वारा प्रदान किया जाता है जिसे स्थापित किया जाना है। मूल बातें:
- PostgreSQL क्रॉसस्टैब क्वेरी
यह कॉलम और टेबल नामों को सुरक्षित रूप से संभालता है। वस्तु पहचानकर्ता प्रकारों के उपयोग पर ध्यान दें regclass
और regtype
. स्कीमा-योग्य नामों के लिए भी काम करता है।
- तालिका नाम PostgreSQL फ़ंक्शन पैरामीटर के रूप में
हालांकि, यह पूरी तरह से सुरक्षित नहीं है जब आप अभिव्यक्ति के रूप में निष्पादित करने के लिए एक स्ट्रिंग पास करते हैं (_expr
- cellc
आपकी मूल क्वेरी में)। इस तरह का इनपुट एसक्यूएल इंजेक्शन के खिलाफ स्वाभाविक रूप से असुरक्षित है और इसे आम जनता के सामने कभी नहीं दिखाया जाना चाहिए।
- पोस्टग्रेज फ़ंक्शन बनाम तैयार क्वेरी में SQL इंजेक्शन
तालिका को केवल एक बार स्कैन करता है दोनों श्रेणियों की सूचियों के लिए और थोड़ा तेज़ होना चाहिए।
अभी भी पूरी तरह से गतिशील पंक्ति प्रकारों को वापस नहीं कर सकता क्योंकि यह सख्ती से संभव नहीं है।