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

Come faccio a passare un parametro di tabella a questa funzione?

Tutto testato in Postgres 9.4 .

Postgres ha alcuni punti deboli nella sintassi per la gestione dei tipi ROW. Non puoi trasmettere direttamente da una tabella (alias):

SELECT w::waypoint FROM waypoints w;

La soluzione è solo a un passo:scomponi la riga in una sottoquery, quindi il cast funziona. In questo modo, i valori delle colonne vengono scomposti e inseriti direttamente nel nuovo tipo, senza eseguire il cast su text e ritorno. Non è necessario elencare tutte le colonne singolarmente e non è nemmeno necessario creare un cast personalizzato:

SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;

O più breve:

SELECT w.*::waypoint FROM (TABLE waypoints) w;

O ancora più breve:

SELECT w::waypoint FROM (TABLE waypoints) w;

SQL Fiddle

È più breve e più veloce, in un rapido test con 30.000 righe e tipi semplici 10 volte più veloce piuttosto che trasmettere a text e ritorno. Se hai (grande) jsonb colonne o qualsiasi tipo complesso (conversione costosa da/verso text ), la differenza sarà ancora molto maggiore.

Ancora più importante, non è necessario un altro tipo di composito personalizzato (ROW). Ogni tabella ha già la sua riga definita come tipo automaticamente. Basta usare il tipo esistente waypoints invece di waypoints (se possibile). Allora tutto ciò di cui hai bisogno è:

SELECT w FROM waypoints w;

Oppure, per il tuo esempio:

SELECT everything(t) FROM temp t;  -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t;  -- using type waypoint

A parte:

  • Una tabella non ha "argomenti" ma colonne.
  • Tu sei non passando un table parameter to this function , ma piuttosto un valore di riga . Ecco come passare una tabella per nome:

    Non puoi "passare un'intera tabella" come parametro direttamente in Postgres, non ci sono variabili di tabella. Utilizzeresti un cursore o una tabella temporanea per questo.

Funzione

La tua funzione ha una dichiarazione di tipo non valida ed è inutilmente complessa. Dubito seriamente che tu voglia creare una vista:

CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
   RETURN QUERY
   SELECT ...
END
$func$ LANGUAGE plpgsql;

text array non è una sintassi valida, utilizzando text[] invece di dichiarare un array di text .

Piuttosto non usare la tabella / nome del tipo waypoints come nome del parametro di funzione, che ti apre a errori di confusione.

Oppure usa semplicemente una semplice funzione SQL se il tuo caso è semplice come mostrato:

CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
   SELECT ...
$func$ LANGUAGE sql;

Non citare il nome della lingua. È un identificatore.