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

Einfache Möglichkeit, den Rückgabetyp als SETOF-Tabelle plus zusätzliche Felder zu haben?

Sie könnten geben Sie eine ganze Zeile als zusammengesetzten Typ zurück und fügen Sie weitere hinzu:

CREATE OR REPLACE FUNCTION f_rowplus()
  RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$  LANGUAGE sql;

Aber dann, wenn Sie den einfachen Aufruf verwenden:

SELECT * FROM f_rowplus();

Sie erhalten die Zeile aus der Tabelle demo als separate zusammengesetzte Art. Sie müssten anrufen:

SELECT (rec).*,  add_int, add_txt FROM f_rowplus();

um alle individuell zu bekommen Säulen. Klammern erforderlich.

Postgres ist hier etwas inkonsistent. Wenn Sie eine Funktion erstellen mit:

CREATE OR REPLACE FUNCTION f_row2()
  RETURNS TABLE (rec demo) AS
...

dann den zusammengesetzten Typ demo wird stillschweigend in einzelne Spalten umgewandelt (zerlegt). Es bleibt keine Verbindung zum ursprünglichen zusammengesetzten Typ. Sie können nicht auf die deklarierte Ausgabespalte rec verweisen überhaupt, da dieser durch die Spalten des zerlegten Typs ersetzt wurde. Dieser Aufruf würde zu einer Fehlermeldung führen:

SELECT rec FROM f_row2();

Auch hier:

CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
  RETURNS SETOF demo AS
...

Allerdings , sobald Sie beliebige hinzufügen mehr OUT Spalten, wird der zusammengesetzte Typ wie deklariert (nicht zerlegt) beibehalten und Sie können:

SELECT rec FROM f_rowplus();

mit der ersten Funktion.

Ich habe eine SQL Fiddle erstellt Demonstrieren der Varianten.

Beiseite
Bei Verwendung einer Funktion, die mehrere Spalten im FROM zurückgibt list (als Tabellenfunktion) und Zerlegung in die SELECT Liste wie folgt:

SELECT (rec).* FROM f_rowplus();

... die Funktion trotzdem einmal ausgewertet wird nur - während eines Anrufs und Zerlegung im SELECT direkt so auflisten:

SELECT (f_rowplus()).*;  -- also: different result

... würde einmal für jede Spalte auswerten im Rückgabetyp. Einzelheiten: