Hoe dan ook, je hebt dynamische SQL nodig.
Tabelnaam als opgegeven parameter
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;
Bel:
SELECT * FROM foo(456887)
Over het algemeen zou u tabelnamen opschonen met format ( %I )
om SQL-injectie te voorkomen. Met slechts een integer
als dynamische input is dat niet nodig. Meer details en links in dit gerelateerde antwoord:
INSERT met dynamische tabelnaam in triggerfunctie
Gegevensmodel
Er kunnen goede redenen zijn voor het datamodel. Zoals partitionering / sharding of aparte privileges ...
Als je niet zo'n goede reden hebt, overweeg dan om meerdere tabellen met een identiek schema samen te voegen tot één en voeg het number
toe als kolom. Dan heb je geen dynamische SQL nodig.
Overweeg erfenis
. Dan kun je een voorwaarde toevoegen aan tableoid
om alleen rijen uit een bepaalde onderliggende tabel op te halen:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Houd echter rekening met beperkingen voor overerving. Gerelateerde antwoorden:
- Krijg de naam van de brontabel van een rij bij het opvragen van de ouder die het erft van
- Selecteer (haal) alle records van meerdere schema's op met Postgres
Naam van 2e tafel afhankelijk van waarde in 1e tabel
Het afleiden van de naam van de join-tabel van waarden in de eerste tabel maakt de zaken dynamisch ingewikkelder.
Voor slechts een paar tafels
LEFT JOIN
elk op tableoid
. Er is slechts één overeenkomst per rij, dus gebruik 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
Voor veel tafels
Combineer een lus met dynamische zoekopdrachten:
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;