In jedem Fall benötigen Sie dynamisches SQL.
Tabellenname als gegebener 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;
Aufruf:
SELECT * FROM foo(456887)
Im Allgemeinen würden Sie Tabellennamen im format ( %I )
bereinigen um SQL-Injection zu vermeiden. Mit nur einer integer
als dynamische Eingabe ist das nicht notwendig. Weitere Details und Links in dieser verwandten Antwort:
INSERT mit dynamischem Tabellennamen in Triggerfunktion
Datenmodell
Für das Datenmodell mag es gute Gründe geben. Wie Partitionierung / Sharding oder separate Privilegien ...
Wenn Sie keinen so guten Grund haben, ziehen Sie in Betracht, mehrere Tabellen mit identischem Schema zu einer zu konsolidieren und die number
hinzuzufügen als Säule. Dann brauchen Sie kein dynamisches SQL.
Betrachten Sie Vererbung
. Dann können Sie tableoid
eine Bedingung hinzufügen um nur Zeilen aus einer bestimmten untergeordneten Tabelle abzurufen:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Beachten Sie jedoch die Einschränkungen für die Vererbung. Verwandte Antworten:
- Ruft den Namen der Quelltabelle einer Zeile ab, wenn das übergeordnete Element abgefragt wird, von dem sie erbt
- Alle Datensätze aus mehreren Schemas mit Postgres auswählen (abrufen)
Name der 2. Tabelle abhängig vom Wert in der 1. Tabelle
Das Ableiten des Namens der Join-Tabelle aus Werten in der ersten Tabelle macht die Dinge dynamisch komplizierter.
Für nur ein paar Tische
LEFT JOIN
jeweils auf tableoid
. Es gibt nur eine Übereinstimmung pro Zeile, also verwenden Sie 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
Für viele Tabellen
Kombinieren Sie eine Schleife mit dynamischen Abfragen:
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;