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

Deklarace struktury n-tice záznamu v PL/pgSQL

Mícháte syntaxi pro vrácení SETOF hodnoty se syntaxí pro vrácení jednoho řádku nebo hodnoty.

-- Související otázka zní - jak vrátím jediný záznam 'r' z

Když deklarujete funkci pomocí RETURNS TABLE , musíte použít RETURN NEXT v těle vrátit řádek (nebo skalární hodnotu). A pokud chcete použít record proměnná, se kterou se musí shodovat návratový typ. Viz příklady kódu níže.

Vrátí jednu hodnotu nebo řádek

Pokud chcete vrátit pouze jeden řádek, není potřeba pro záznam nedefinovaného typu. @Kevin již předvedl dva způsoby. Přidám zjednodušenou verzi s OUT parametry:

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

Nemusíte ani přidávat RETURN; v těle funkce hodnota deklarovaného OUT parametry budou vráceny automaticky na konci funkce - NULL pro jakýkoli parametr, který nebyl přiřazen.
A nemusíte deklarovat RETURNS RECORD protože to je již jasné z OUT parametry.

Vrátí sadu řádků

Pokud skutečně chcete vrátit více řádky (včetně možnosti pro 0 nebo 1 řádek), můžete definovat návratový typ jako RETURNS ...

  • SETOF some_type , kde some_type může být jakéhokoli registrovaného skalárního nebo složeného typu.

  • TABLE (col1 type1, col2 type2) - ad-hoc definice typu řádku.

  • SETOF record plus OUT parametry k definování názvů a typů sloupců.
    100% ekvivalentní RETURNS TABLE .

  • SETOF record bez další definice. Ale pak jsou vrácené řádky nedefinované a ke každému volání musíte zahrnout seznam definic sloupců (viz příklad).

Manuál o typu záznamu:

Proměnné záznamu jsou podobné proměnným typu řádek, ale nemají žádnou předem definovanou strukturu. Přebírají skutečnou řádkovou strukturu řádku, kterému jsou přiřazeny během příkazu SELECT nebo FOR.

Je toho víc, čtěte manuálu.

můžete použít proměnnou záznamu bez přiřazení definovaného typu, můžete dokonce vrátit takové nedefinované záznamy:

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;

Volejte:

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

Ale to je velmi nepraktické protože při každém volání musíte poskytnout seznam definic sloupců. Obecně ji lze nahradit něčím elegantnějším:

  • Pokud znáte typ v době vytváření funkce, ihned jej deklarujte (RETURNS TABLE nebo přátelé).

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;
  • Pokud znáte typ v době volání funkce , existují elegantnější způsoby použití polymorfních typů:
    Refaktorujte funkci PL/pgSQL, abyste vrátili výstup různých SELECT dotazů

Z vaší otázky není jasné, co přesně potřebujete.



  1. Jak zkopírovat tabulku v MySQL

  2. Tipy a triky pro navigaci v komunitě PostgreSQL

  3. Jak porovnat hodnoty Null v MySQL

  4. MariaDB CURRENT_TIMESTAMP() Vysvětleno