Das könnte so funktionieren:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
-
Beachten Sie die Verwendung des Objektkennungstyps
regclass
um SQL-Injection automatisch zu vermeiden. -
Verwenden Sie nicht die veraltete Syntax
var ALIAS for $1
wenn du nicht musst. Deklarieren Sie stattdessen Parameternamen. -
Ich würde das Schlüsselwort
temp
nicht verwenden als Identifikator, auch wenn das erlaubt ist. Mittmp
stattdessen. -
Verwenden Sie
RETURN QUERY
um eine Reihe von Datensätzen zurückzugeben. Dies kann sogar ein statischer Aufruf ohneEXECUTE
sein . Sie geben jedoch anonyme Datensätze zurück und Postgres fordert eine Spaltendefinitionsliste bei jedem Aufruf:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Das ist ziemlich unhandlich.
Bessere Lösungen
Wenn Sie wissen Deklarieren Sie den Rückgabetyp (selbst wenn sich die Tabellennamen ändern, die Liste der Spalten kann dieselben Typen haben), deklarieren Sie ihn zum Zeitpunkt der Erstellung. Betrachten Sie diese verwandte Frage:
PostgreSQL:FEHLER:42601:Für Funktionen, die "record" zurückgeben, ist eine Spaltendefinitionsliste erforderlich
Wenn der Rückgabetyp variiert mit dem bereitgestellten Tabellennamen gibt es noch eine viel bessere Lösung. Da Sie eine Ansicht mit SELECT * FROM tbl
erstellen , können Sie den bekannten Typ der Tabelle selbst als polymorphe
Parameter:
CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
Vereinfachter Aufruf:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Verwenden Sie auch format()
für eine sichere und einfache Zeichenfolgenverkettung.
Weitere Details in dieser verwandten Antwort:
Refaktorisieren Sie eine PL/pgSQL-Funktion, um die Ausgabe verschiedener SELECT-Abfragen zurückzugeben