sql >> Databáze >  >> RDS >> PostgreSQL

Jak předám parametr tabulky této funkci?

Vše testováno v Postgres 9.4 .

Postgres má některá slabá místa v syntaxi pro práci s typy ROW. Nemůžete odesílat přímo z tabulky (aliasu):

SELECT w::waypoint FROM waypoints w;

Řešení je jen jeden krok:rozložte řádek v dílčím dotazu, pak přetypování funguje. Tímto způsobem jsou hodnoty sloupců rozloženy a zabaleny do nového typu přímo, bez přetypování na text a zpět. Není třeba vypisovat všechny sloupce jednotlivě a není třeba vytvářet vlastní přetypování:

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

Nebo kratší:

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

Nebo ještě kratší:

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

SQL Fiddle

To je kratší a rychlejší, v rychlém testu s 30 000 řádky a jednoduchými typy 10x rychlejší než přenášet do text a zpět. Pokud máte (velký) jsonb sloupce nebo jakýkoli složitý typ (nákladný převod do/z text ), rozdíl bude ještě mnohem větší.

A co je důležitější, nepotřebujete jiný vlastní kompozitní (ROW) typ. Každá tabulka již má svůj řádek definovaný jako typ automaticky. Stačí použít stávající typ waypoints místo waypoint (pokud je to vůbec možné). Pak vše, co potřebujete, je:

SELECT w FROM waypoints w;

Nebo například:

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

Kromě:

  • Tabulka nemá "argumenty", ale sloupce.
  • nejste předání table parameter to this function , ale spíše hodnota řádku . Takto předáte tabulku podle názvu:

    Přímo v Postgresu nemůžete "předat celou tabulku" jako parametr, neexistují proměnné tabulky. K tomu byste použili kurzor nebo dočasnou tabulku.

Funkce

Vaše funkce má neplatnou deklaraci typu a je zbytečně složitá. Vážně pochybuji, že chcete vytvořit pohled:

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 není platná syntaxe, používá text[] místo toho deklarovat pole text .

Raději nepoužívejte název tabulky / typu waypoints jako název parametru funkce, který vás otevírá matoucím chybám.

Nebo použijte jednoduchou funkci SQL, pokud je váš případ tak jednoduchý, jak je ukázáno:

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

Neuvádějte název jazyka. Je to identifikátor.



  1. Docker postgres neplatný záznam primárního kontrolního bodu

  2. Pokud databáze existuje, ukončete skript MySQL

  3. Jak spustit nativní SQL dotazy ve stejné transakci Hibernate?

  4. Importujte soubor CSV do tabulky SQLite