Dichiarare la variabile del tipo di tabella in PL / pgSQL


8

Mi chiedo se esiste un modo per dichiarare una variabile di tabella dei tipi in PL / pgSQL per contenere i risultati della query? Ad esempio, come posso esprimere qualcosa come:

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2

Ho esaminato il costrutto successivo di ritorno, ma sembra in grado di gestire solo i valori di ritorno.


2
PL / SQL => Oracle, PgPL / SQL => PostgreSQL. Con chi lavori?
Mat

@Mat: è PL / pgSQL , tra l'altro.
Erwin Brandstetter,

Risposte:


12

In PostgreSQL , ogni nome di tabella funge automaticamente da nome di tipo per il tipo di riga (aka tipo composito ) - non un tipo di tabella, non ci sono "tipi di tabella" o "variabili di tabella" in Postgres ( ma ci sono tabelle digitate ).
Quindi puoi semplicemente dichiarare una variabile di quel tipo PL/pgSQL.

CREATE FUNCTION foo()
 RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
  q1 foo;  -- "foo" ...
  q2 bar;  -- ... and "bar" are existing (visible) table names
BEGIN

FOR q1 IN 
   SELECT * from foo
LOOP
   FOR q2 IN 
      SELECT * from bar
   LOOP
       -- do something with q1 and q2
       -- since q1 and q2 are well known types, you can access columns
       -- with attribute notation. Like: q1.col1
   END LOOP;
END LOOP;

END
$func$

Un FORciclo funziona con un cursore incorporato. Ci sono anche cursori espliciti in plpgsql.

Potresti anche semplicemente dichiarare variabili di tipo generico record. Può richiedere automaticamente qualsiasi tipo di riga durante l'assegnazione. Ma si applicano regole speciali. Assicurati di seguire il link e leggere il capitolo del manuale!

Mentre è spesso utile avere la funzione return SETOF <table name>, tornare SETOF recordnon è altrettanto conveniente. Il sistema non sa cosa restituisce la funzione in questo modo e devi aggiungere un elenco di definizioni di colonne ad ogni chiamata. Questo è un dolore. Dettagli sulle funzioni della tabella nel manuale .

Spesso, tuttavia, esistono soluzioni più efficienti con SQL semplice. Il looping è una misura dell'ultima risorsa, quando è possibile eseguire operazioni in un'unica scansione in cui sono necessarie più scansioni in SQL puro.


2
Inoltre, se vuoi restituire il tipo di tabella, puoi semplicemente dire qualcosa del tipoCREATE FUNCTION footest() RETURNS SETOF foo LANGUAGE PLPGSQL AS $$...
Chris Travers,

Perché allora abbiamo la caratteristica di "tipi compositi" se invece possiamo creare tabelle, senza restrizioni applicate ai tipi compositi (senza vincoli, ecc.)? L'unico modo significativo di usare tipi compositi che vedo è restituire un paio (o più) parametri da una funzione invece di creare un'intera tabella per quello.
SaneDeveloper il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.