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

Erklæring af tupelstrukturen af ​​en post i PL/pgSQL

Du blander syntaksen for at returnere SETOF værdier med syntaks til at returnere en enkelt række eller værdi.

-- Et relateret spørgsmål er - hvordan returnerer jeg den enkelte post 'r' fra

Når du erklærer en funktion med RETURNS TABLE , skal du bruge RETURN NEXT i kroppen for at returnere en række (eller skalarværdi). Og hvis du vil bruge en record variabel med, at den skal matche returtypen. Se kodeeksemplerne længere nede.

Returner en enkelt værdi eller række

Hvis du blot ønsker at returnere en enkelt række, er der intet behov for en post af udefineret type. @Kevin har allerede demonstreret to måder. Jeg tilføjer en forenklet version med OUT parametre:

CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
   AS
$func$
BEGIN
   a := ...;
   b := ...;
END
$func$ LANGUAGE plpgsql;

Du behøver ikke engang at tilføje RETURN; i funktionsteksten, værdien af ​​den erklærede OUT parametre vil blive returneret automatisk i slutningen af ​​funktionen - NULL for enhver parameter, der ikke er blevet tildelt.
Og du behøver ikke at erklære RETURNS RECORD fordi det allerede er klart fra OUT parametre.

Returner et sæt rækker

Hvis du rent faktisk ønsker at returnere flere rækker (inklusive muligheden for 0 eller 1 række), kan du definere returtypen som RETURNS ...

  • SETOF some_type , hvor some_type kan være enhver registreret skalær eller sammensat type.

  • TABLE (col1 type1, col2 type2) - en ad-hoc rækketypedefinition.

  • SETOF record plus OUT parametre til at definere kolonnenavne og -typer.
    100 % svarende til RETURNS TABLE .

  • SETOF record uden nærmere definition. Men så er de returnerede rækker udefinerede og du skal inkludere en kolonnedefinitionsliste med hvert opkald (se eksempel).

Manualen om posttypen:

Postvariabler ligner rækkevariabler, men de har ingen foruddefineret struktur. De overtager den faktiske rækkestruktur af den række, de er tildelt under en SELECT- eller FOR-kommando.

Der er mere, læs manualen.

Du kan bruge en registreringsvariabel uden at tildele en defineret type, du kan endda returnere sådanne udefinerede poster:

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF record AS
$func$
DECLARE
    r record;
BEGIN
    r := (1::int, 'foo'::text); RETURN NEXT r; -- works with undefined record
    r := (2::int, 'bar'::text); RETURN NEXT r;
END
$func$ LANGUAGE plpgsql;

Ring til:

SELECT * FROM my_func() AS x(a int, b text);

Men dette er meget uhåndterligt da du skal angive kolonnedefinitionslisten ved hvert opkald. Det kan generelt erstattes med noget mere elegant:

  • Hvis du kender typen på tidspunktet for funktionsoprettelse, skal du deklarere den med det samme (RETURNS TABLE eller venner).

CREATE OR REPLACE FUNCTION my_func()
  RETURNS SETOF tbl_or_type AS
$func$
DECLARE
    r tbl_or_type;
BEGIN
    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 10;
    RETURN NEXT r;  -- type matches

    SELECT INTO tbl_or_type  * FROM tbl WHERE id = 12;
    RETURN NEXT r;

    -- Or simpler:
    RETURN QUERY
    SELECT * FROM tbl WHERE id = 14;
END
$func$ LANGUAGE plpgsql;
  • Hvis du kender typen på tidspunktet for funktionskaldet , der er mere elegante måder at bruge polymorfe typer:
    Refaktorer en PL/pgSQL-funktion for at returnere output fra forskellige SELECT-forespørgsler

Dit spørgsmål er uklart med hensyn til, hvad du præcist har brug for.



  1. Tilladelse nægtet til forholdet

  2. Tilføj WHERE-sætninger til SQL dynamisk / programmatisk

  3. Automatisk indeksstyring i Azure SQL-database

  4. Hvordan gør man en kolonne unik i SQL?