PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Un modo semplice per fare in modo che il tipo di restituzione sia una tabella SETOF più campi aggiuntivi?

Potresti restituisce un'intera riga come tipo composito e aggiungine ancora:

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;

Ma poi, quando usi la semplice chiamata:

SELECT * FROM f_rowplus();

Ottieni la riga dalla tabella demo come tipo composito separato. Dovresti chiamare:

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

per ottenere tutti i individui colonne. Parentesi obbligatorie.

Postgres è un po' incoerente qui. Se crei una funzione con:

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

quindi il tipo composito demo viene convertito silenziosamente in singole colonne (scomposto). Nessun collegamento al tipo composito originale rimane. Non puoi fare riferimento alla colonna di output dichiarata rec affatto, dal momento che è stato sostituito con le colonne del tipo scomposto. Questa chiamata risulterebbe in un messaggio di errore:

SELECT rec FROM f_row2();

Lo stesso qui:

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

Tuttavia , non appena aggiungi qualsiasi altro OUT colonne, il tipo composto viene mantenuto come dichiarato (non scomposto) e puoi:

SELECT rec FROM f_rowplus();

con la prima funzione.

Ho creato un SQL Fiddle dimostrando le varianti.

A parte
Quando si utilizza una funzione che restituisce più colonne nel FROM list (come funzione di tabella) e scomposizione nel SELECT elenca in questo modo:

SELECT (rec).* FROM f_rowplus();

... la funzione viene ancora valutata una volta solo - durante una chiamata e decomposizione nel SELECT elenca direttamente in questo modo:

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

... valuterebbe una volta per ogni colonna nel tipo di reso. Dettagli: