Stai mescolando la sintassi per restituire SETOF
valori con sintassi per la restituzione di una singola riga o valore.
-- Una domanda correlata è:come posso restituire il singolo record 'r' da
Quando dichiari una funzione con RETURNS TABLE
, devi usare RETURN NEXT
nel corpo per restituire una riga (o un valore scalare). E se vuoi usare un record
variabile con quella deve corrispondere il tipo di ritorno. Fare riferimento agli esempi di codice più in basso.
Restituisce un singolo valore o riga
Se desideri restituire solo una singola riga, non è necessario per un record di tipo indefinito. @Kevin ha già dimostrato due modi. Aggiungerò una versione semplificata con OUT
parametri:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Non è nemmeno necessario aggiungere RETURN;
nel corpo della funzione, il valore del OUT
dichiarato i parametri verranno restituiti automaticamente alla fine della funzione - NULL
per qualsiasi parametro che non è stato assegnato.
E non è necessario dichiarare RETURNS RECORD
perché è già chiaro da OUT
parametri.
Restituisci un insieme di righe
Se desideri effettivamente restituire più righe (compresa la possibilità per 0 o 1 riga), puoi definire il tipo di ritorno come RETURNS
...
-
SETOF some_type
, dovesome_type
può essere qualsiasi tipo scalare o composito registrato. -
TABLE (col1 type1, col2 type2)
- una definizione del tipo di riga ad hoc. -
SETOF record
piùOUT
parametri per definire i nomi e i tipi di colonna.
equivalente al 100% aRETURNS TABLE
. -
SETOF record
senza ulteriore definizione. Ma poi le righe restituite sono non definite e devi includere un elenco di definizioni di colonna con ogni chiamata (vedi esempio).
Il manuale sul tipo di record:
Le variabili record sono simili alle variabili di tipo riga, ma non hanno una struttura predefinita. Assumono la struttura di riga effettiva della riga che vengono loro assegnate durante un comando SELECT o FOR.
C'è di più, leggi il manuale.
puoi utilizzare una variabile record senza assegnare un tipo definito, puoi anche restituire tali record indefiniti:
CREATE OR REPLACE FUNCTION my_func()
RETURNS SETOF record AS
$func$
DECLARE
r record;
BEGIN
r := (1::int, 'foo'::text); RETURN NEXT r; -- works with undefined record
r := (2::int, 'bar'::text); RETURN NEXT r;
END
$func$ LANGUAGE plpgsql;
Chiama:
SELECT * FROM my_func() AS x(a int, b text);
Ma questo è molto ingombrante poiché devi fornire l'elenco delle definizioni delle colonne con ogni chiamata. In genere può essere sostituito con qualcosa di più elegante:
- Se conosci il tipo al momento della creazione della funzione, dichiaralo subito (
RETURNS TABLE
o amici).
CREATE OR REPLACE FUNCTION my_func()
RETURNS SETOF tbl_or_type AS
$func$
DECLARE
r tbl_or_type;
BEGIN
SELECT INTO tbl_or_type * FROM tbl WHERE id = 10;
RETURN NEXT r; -- type matches
SELECT INTO tbl_or_type * FROM tbl WHERE id = 12;
RETURN NEXT r;
-- Or simpler:
RETURN QUERY
SELECT * FROM tbl WHERE id = 14;
END
$func$ LANGUAGE plpgsql;
- Se conosci il tipo al momento della chiamata di funzione , ci sono modi più eleganti per usare i tipi polimorfici:
Refactoring di una funzione PL/pgSQL per restituire l'output di varie query SELECT
La tua domanda non è chiara su ciò di cui hai bisogno esattamente.