Tak czy inaczej, potrzebujesz dynamicznego SQL.
Nazwa tabeli jako podany parametr
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;
Zadzwoń:
SELECT * FROM foo(456887)
Ogólnie rzecz biorąc, możesz oczyścić nazwy tabel za pomocą format ( %I )
aby uniknąć wstrzyknięcia SQL. Wystarczy integer
jako dynamiczne wprowadzanie, które nie jest konieczne. Więcej szczegółów i linków w tej powiązanej odpowiedzi:
WSTAW z dynamiczną nazwą tabeli w funkcji wyzwalacza
Model danych
Model danych może mieć dobre powody. Podobnie jak partycjonowanie / sharding lub oddzielne uprawnienia ...
Jeśli nie masz tak dobrego powodu, rozważ konsolidację wielu tabel o identycznym schemacie w jedną i dodaj number
jako kolumna. Wtedy nie potrzebujesz dynamicznego SQL.
Rozważ dziedziczenie
. Następnie możesz dodać warunek na tableoid
aby pobrać tylko wiersze z danej tabeli podrzędnej:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Miej jednak świadomość ograniczeń dziedziczenia. Powiązane odpowiedzi:
- Pobierz nazwę tabeli źródłowej wiersza podczas zapytania rodzica, z którego dziedziczy
- Wybierz (pobierz) wszystkie rekordy z wielu schematów za pomocą Postgresa
Nazwa drugiej tabeli w zależności od wartości w pierwszej tabeli
Wyprowadzenie nazwy tabeli łączenia z wartości w pierwszej tabeli dynamicznie komplikuje sprawę.
Tylko kilka stołów
LEFT JOIN
każdy na tableoid
. W każdym wierszu jest tylko jedno dopasowanie, więc użyj 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
Dla wielu stołów
Połącz pętlę z zapytaniami dynamicznymi:
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;