sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur skickar jag in en tabellparameter till den här funktionen?

Allt testat i Postgres 9.4 .

Postgres har några svaga punkter i syntaxen för hantering av ROW-typer. Du kan inte casta från en tabell (alias) direkt:

SELECT w::waypoint FROM waypoints w;

Lösningen är bara ett steg bort:dekomponera raden i en underfråga, sedan fungerar casten. På så sätt bryts kolumnvärden upp och lindas in i den nya typen direkt, utan att casta till text och tillbaka. Du behöver inte lista alla kolumner individuellt och du behöver inte skapa en anpassad roll heller:

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

Eller kortare:

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

Eller ännu kortare:

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

SQL Fiddle

Det är kortare och snabbare, i ett snabbtest med 30 000 rader och enkla typer 10 gånger snabbare än att casta till text och tillbaka. Om du har (stor) jsonb kolumner eller någon komplex typ (dyr konvertering till/från text ), kommer skillnaden att vara mycket större, ännu.

Ännu viktigare är att du inte behöver en annan anpassad komposittyp (ROW). Varje tabell har redan sin rad definierad som typ automatiskt. Använd bara den befintliga typen waypoints istället för waypoint (om ens möjligt). Då behöver du bara:

SELECT w FROM waypoints w;

Eller, till exempel:

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

Bortsett från:

  • En tabell har inte "argument" utan kolumner.
  • Du är inte skicka en table parameter to this function utan snarare ett radvärde . Det är så du skickar en tabell med namn:

    Du kan inte "passera en hel tabell" som parameter direkt i Postgres, det finns inga tabellvariabler. Du skulle använda en markör eller en temporär tabell för det.

Funktion

Din funktion har en ogiltig typdeklaration och är onödigt komplex. Jag tvivlar allvarligt på att du vill skapa en vy:

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 är inte giltig syntax, med text[] istället för att deklarera en array med text .

Använd hellre inte tabell-/typnamnet waypoints som funktionsparameternamn, som öppnar upp för förvirrande fel.

Eller använd bara en enkel SQL-funktion om ditt fall är så enkelt som visas:

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

Citera inte språknamnet. Det är en identifierare.



  1. Loop in trigger med kommaseparerade värden mysql

  2. PostGres-fel vid användning av Distinct:postgres-FEL:kunde inte identifiera en beställande operatör för typpost

  3. Beräkna exakt månadsskillnad mellan två datum

  4. EEE MMM dd HH:mm:ss ZZZ åååå datumformat till java.sql.Date