किसी भी तरह से, आपको गतिशील SQL की आवश्यकता है।
दिए गए पैरामीटर के रूप में तालिका का नाम
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS -- adapt to actual data types!
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT t.cpa, substring(t.ku,'[0-9]+'), p.vym
FROM public."table_data_C" t
LEFT JOIN %s p USING (cpa)'
, 'pa' || _number
);
END
$func$ LANGUAGE plpgsql;
कॉल करें:
SELECT * FROM foo(456887)
आम तौर पर, आप टेबल नामों को format ( %I )
. के साथ सेनिटाइज करेंगे एसक्यूएल इंजेक्शन से बचने के लिए। केवल एक integer
. के साथ गतिशील इनपुट के रूप में जो आवश्यक नहीं है। इस संबंधित उत्तर में अधिक विवरण और लिंक:
ट्रिगर फंक्शन में डायनामिक टेबल नाम के साथ INSERT करें
डेटा मॉडल
डेटा मॉडल के अच्छे कारण हो सकते हैं। जैसे विभाजन / शार्डिंग या अलग विशेषाधिकार ...
यदि आपके पास इतना अच्छा कारण नहीं है, तो समान स्कीमा वाली एकाधिक तालिकाओं को एक में समेकित करने पर विचार करें और number
जोड़ें स्तंभ के रूप में। तब आपको गतिशील SQL की आवश्यकता नहीं है।
विरासत
पर विचार करें . फिर आप tableoid
. पर एक शर्त जोड़ सकते हैं केवल दी गई चाइल्ड टेबल से पंक्तियों को पुनः प्राप्त करने के लिए:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
हालांकि, इनहेरिटेंस की सीमाओं से अवगत रहें। संबंधित उत्तर:
- पंक्ति के स्रोत तालिका का नाम प्राप्त करें जब उस पैरेंट को क्वेरी करें जिससे वह इनहेरिट करता है
- Postgres का उपयोग करके एकाधिक स्कीमा से सभी रिकॉर्ड चुनें (पुनर्प्राप्त करें)
पहली तालिका में मान के आधार पर दूसरी तालिका का नाम
पहली तालिका में मानों से जुड़ने वाली तालिका का नाम गतिशील रूप से चीजों को जटिल बनाता है।
केवल कुछ तालिकाओं के लिए
LEFT JOIN
प्रत्येक tableoid
. पर . प्रति पंक्ति केवल एक मैच है, इसलिए COALESCE
. का उपयोग करें ।
SELECT t.*, t.tbl, COALESCE(p1.vym, p2.vym, p3.vym) AS vym
FROM (
SELECT cpa, ('pa' || substring(ku,'[0-9]+'))::regclass AS tbl
FROM public."table_data_C"
-- WHERE <some condition>
) t
LEFT JOIN pa456887 p1 ON p1.cpa = t.cpa AND p1.tableoid = t.tbl
LEFT JOIN pa456888 p2 ON p2.cpa = t.cpa AND p2.tableoid = t.tbl
LEFT JOIN pa456889 p3 ON p3.cpa = t.cpa AND p3.tableoid = t.tbl
कई तालिकाओं के लिए
गतिशील प्रश्नों के साथ एक लूप को संयोजित करें:
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS
$func$
DECLARE
_nr text;
BEGIN
FOR _nr IN
SELECT DISTINCT substring(ku,'[0-9]+')
FROM public."table_data_C"
LOOP
RETURN QUERY EXECUTE format(
'SELECT t.cpa, _nr, p.vym
FROM public."table_data_C" t
LEFT JOIN %I p USING (cpa)
WHERE t.ku LIKE (_nr || '%')'
, 'pa' || _nr
);
END LOOP;
END
$func$ LANGUAGE plpgsql;