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

Dichiarazione della struttura della tupla di un record in PL/pgSQL

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 , dove some_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% a RETURNS 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.