PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

plpgsql-Funktion:Gibt Zeilen aus einer Ansicht zurück, die aus einer Zufallstabelle erstellt wurde

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. Mit tmp stattdessen.

  • Verwenden Sie RETURN QUERY um eine Reihe von Datensätzen zurückzugeben. Dies kann sogar ein statischer Aufruf ohne EXECUTE 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