Lösung für den einfachen Fall
Wie in den referenzierten Antworten unten erläutert, können Sie registrierte (Zeilen-)Typen verwenden und somit implizit den Rückgabetyp einer polymorphen Funktion deklarieren:
CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;
Aufruf:
SELECT * FROM public.get_table(NULL::public.users); -- note the syntax!
Gibt die vollständige Tabelle (mit allen Benutzerspalten) zurück.
Warte! Wie?
Ausführliche Erklärung in dieser zugehörigen Antwort, Kapitel "Verschiedene vollständige Tabellentypen" :
- Refaktorisieren Sie eine PL/pgSQL-Funktion, um die Ausgabe verschiedener SELECT-Abfragen zurückzugeben
TABLE foo
ist nur kurz für SELECT * FROM foo
:
- Gibt es eine Abkürzung für SELECT * FROM?
2 Schritte für vollständig dynamischen Rückgabetyp
Aber was Sie zu tun versuchen, ist streng unmöglich in einem einzelnen SQL-Befehl.
Ich möchte schema_name
übergeben und table_name
als Parameter zum Funktionieren und Abrufen der Datensatzliste gemäß column_visible
Feld inpublic.fields
Tabelle.
Es gibt keine direkte Möglichkeit, eine willkürliche Auswahl von Spalten (Rückgabetyp zum Zeitpunkt des Aufrufs nicht bekannt) von einer Funktion zurückzugeben - oder beliebig SQL-Befehl. SQL fordert zum Zeitpunkt des Aufrufs die Kenntnis von Nummer, Namen und Typen der resultierenden Spalten. Mehr im 2. Kapitel dieser verwandten Antwort:
- Wie erzeuge ich einen pivotierten CROSS JOIN, bei dem die resultierende Tabellendefinition unbekannt ist?
Es gibt verschiedene Workarounds . Sie könnten das Ergebnis in einen der Standarddokumenttypen (json
, jsonb
, hstore
, xml
).
Oder Sie generieren die Abfrage mit einem Funktionsaufruf und führen das Ergebnis mit dem nächsten aus:
CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
RETURNS text AS
$func$
SELECT format('SELECT %s FROM %I.%I'
, string_agg(quote_ident(column_name), ', ')
, schema_name
, table_name)
FROM fields
WHERE column_visible
AND schema_name = _schema_name
AND table_name = _table_name
GROUP BY schema_name, table_name
ORDER BY schema_name, table_name;
$func$ LANGUAGE sql;
Aufruf:
SELECT public.generate_get_table('public', 'users');
Dies erstellt eine Abfrage der Form:
SELECT usr_id, usr FROM public.users;
Führen Sie es im 2. Schritt aus. (Möglicherweise möchten Sie Spaltennummern hinzufügen und Spalten anordnen.)
Oder \gexec
anhängen in psql, um den Rückgabewert sofort auszuführen. Siehe:
So erzwingen Sie die Auswertung einer Unterabfrage, bevor Sie sich einem fremden Server anschließen/herunterdrücken
Schützen Sie sich unbedingt vor SQL-Injection:
- INSERT mit dynamischem Tabellennamen in Triggerfunktion
- Tabellen- und Spaltennamen als Argumente in einer plpgsql-Funktion definieren?
varchar(100)
macht für Bezeichner, die in Standard-Postgres auf 63 Zeichen begrenzt sind, nicht viel Sinn:
- Maximale Zeichenanzahl in Beschriftungen (Tabellennamen, Spalten usw.)
Wenn Sie verstehen, wie der Objektidentifizierer regclass
eingibt funktioniert, können Sie den Schema- und Tabellennamen durch eine einzelne regclass
ersetzen Spalte.