sql >> Database >  >> RDS >> PostgreSQL

Hoe geef ik een tabelparameter door aan deze functie?

Alles getest in Postgres 9.4 .

Postgres heeft enkele zwakke plekken in de syntaxis voor het omgaan met ROW-typen. U kunt niet rechtstreeks vanaf een tafel (alias) casten:

SELECT w::waypoint FROM waypoints w;

De oplossing is slechts één stap verwijderd:ontbind de rij in een subquery, dan werkt de cast. Op deze manier worden kolomwaarden ontleed en direct in het nieuwe type verpakt, zonder casten naar text en terug. U hoeft niet alle kolommen afzonderlijk weer te geven en u hoeft ook geen aangepaste cast te maken:

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

Of korter:

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

Of korter, maar toch:

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

SQL Fiddle

Dat is korter en sneller, in een snelle test met 30k rijen en eenvoudige typen 10x sneller dan casten naar text en terug. Als je (grote) jsonb . hebt kolommen of elk complex type (dure conversie van/naar text ), zal het verschil nog veel groter zijn.

Wat nog belangrijker is, u niet nodig een ander aangepast composiettype (ROW). Elke tabel heeft zijn rij al automatisch als type gedefinieerd. Gebruik gewoon het bestaande type waypoints in plaats van waypoint (indien mogelijk). Dan is alles wat je nodig hebt:

SELECT w FROM waypoints w;

Of, voor jouw voorbeeld:

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

Terzijde:

  • Een tabel heeft geen "argumenten" maar kolommen.
  • Je bent niet een table parameter to this function , maar eerder een rijwaarde . Zo geef je een tafel op naam door:

    Je kunt niet "een hele tabel doorgeven" als parameter rechtstreeks in Postgres, er zijn geen tabelvariabelen. Je zou daarvoor een cursor of een tijdelijke tabel gebruiken.

Functie

Uw functie heeft een ongeldige typedeclaratie en is onnodig complex. Ik betwijfel ten zeerste of je een weergave wilt maken:

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 is geen geldige syntaxis, met behulp van text[] in plaats daarvan om een ​​array van text . te declareren .

Gebruik liever niet de tabel / typenaam waypoints als functieparameternaam, die je blootstelt aan verwarrende fouten.

Of gebruik gewoon een eenvoudige SQL-functie als uw zaak zo eenvoudig is als aangetoond:

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

Citeer de taalnaam niet. Het is een identificatie.



  1. Laatste invoer selecteren voor afzonderlijke invoer

  2. Waarde ophalen van een xml-element in Oracle PL SQL

  3. Postgres db-ontwerp Normaliseer tabellen of gebruik matrixkolommen

  4. Krijg alle tabelnamen van een bepaalde database door SQL-query?