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

Hvordan sender jeg en tabelparameter til denne funktion?

Alt testet i Postgres 9.4 .

Postgres har nogle svage punkter i syntaksen til håndtering af ROW-typer. Du kan ikke caste direkte fra en tabel (alias):

SELECT w::waypoint FROM waypoints w;

Løsningen er kun et skridt væk:nedbryd rækken i en underforespørgsel, så virker castet. På denne måde bliver kolonneværdier dekomponeret og pakket ind i den nye type direkte uden at caste til text og tilbage. Det er ikke nødvendigt at angive alle kolonner individuelt, og du behøver heller ikke oprette en brugerdefineret cast:

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

Eller kortere:

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

Eller endnu kortere:

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

SQL Fiddle

Det er kortere og hurtigere i en hurtig test med 30.000 rækker og simple typer 10 gange hurtigere end at caste til text og tilbage. Hvis du har (stor) jsonb kolonner eller en hvilken som helst kompleks type (dyr konvertering til/fra text). ), vil forskellen være meget større endnu.

Endnu vigtigere er det, at du ikke behøver en anden brugerdefineret sammensat (ROW) type. Hver tabel har allerede sin række defineret som type automatisk. Brug blot den eksisterende type waypoints i stedet for waypoint (hvis det overhovedet er muligt). Så behøver du bare:

SELECT w FROM waypoints w;

Eller for eksempel:

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

Bortset fra:

  • En tabel har ikke "argumenter", men kolonner.
  • Du er ikke sende en table parameter to this function , men snarere en rækkeværdi . Sådan sender du en tabel ved navn:

    Du kan ikke "passere en hel tabel" som parameter direkte i Postgres, der er ingen tabelvariable. Du ville bruge en markør eller en midlertidig tabel til det.

Funktion

Din funktion har en ugyldig typeerklæring og er unødvendigt kompleks. Jeg tvivler alvorligt på, at du vil oprette en visning:

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 er ikke gyldig syntaks ved hjælp af text[] i stedet for at erklære en matrix af text .

Brug hellere ikke tabellen/typenavnet waypoints som funktionsparameternavn, der åbner op for forvirrende fejl.

Eller brug bare en simpel SQL-funktion, hvis din sag er så enkel som vist:

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

Angiv ikke sprogets navn. Det er en identifikator.



  1. MySQL vs. SQL Server vs. Oracle

  2. Hvordan får man kolonnenavne og -typer fra en PostgreSQL-forespørgsel (uden at køre den)?

  3. Jeg vil kontrollere, om posten eksisterer, og hvis den ikke eksisterer, så vil jeg indsætte den post i databasen ved hjælp af golang

  4. Kunne ikke konvertere parameterværdi fra en streng til en Int32