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

Garantuje postgres union pořadí provedení při vyvolání funkcí s vedlejšími účinky?

V praxi budou provedeny v daném pořadí, ale neexistuje žádná záruka.

Pokud je to zaručeno, bude to zahrnuto v dokumentaci nebo ve standardu SQL. Nevidím žádnou zmínku o pořadí provádění UNION v obou.

Pokud by měl optimalizátor důvod provést jednu před druhou, mohl by tak učinit.

Chcete-li zajistit pořadí provádění, spouštějte příkazy v požadovaném pořadí:

SELECT * FROM func1();
SELECT * FROM func2();

Chcete-li snížit počet zpátečních cest, použijte dávkovací zařízení vašeho klienta, pokud je to možné, nebo použijte DO blokovat:

DO
$$
BEGIN
  PERFORM proc1();
  PERFORM proc2();
END;
$$;

Pokud potřebujete vrátit hodnoty, použijte funkci a RETURN QUERY nebo RETURN NEXT .

Nebo můžete vynutit objednávku pomocí CTE, protože v PostgreSQL (bohužel) CTE fungují jako optimalizační ploty, které si vynucují zhmotnění výsledků . AFAIK PostgreSQL však stále nemusí provádět podmínky CTE v pořadí, v jakém jsou napsány, nebo v pořadí, v jakém se na ně odkazuje; jediná záruka, kterou získáte, je, když uděláte toto:

WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;

pak function1 musí být nejprve provedeny a zhmotněny. To je však chyba specifická pro PostgreSQL; neplatí to pro jiné databázové stroje, které standard nezaručuje, a neměli byste na to spoléhat.

To se nevztahuje na

WITH f1 AS (SELECT * FROM function1())
     f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;

... jako v tomto případě může PostgreSQL provádět nezávislé podmínky CTE v libovolném pořadí.

Opět platí, že u spojení platí stejný princip. Pokud jsou podmínky nezávislé, pak se systém může rozhodnout je spouštět v libovolném pořadí, i když to obecně nebude. Takže:

select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true

mohl vyhodnotit a zhmotnit bar() pak připojte jeho výsledky na foo() .

Pokud chcete provedení příkazu, neměli byste se spoléhat na nastavené operace, jako jsou sjednocení a spojení. Použijte samostatné dotazy nebo procedurální kód.

Ano, existuje.

SELECT * FROM function1();
SELECT * FROM function2();



  1. Vrácení hodnoty 0 z řádku databáze v PHP/MySQL po dotazu

  2. sloupec není null odložitelný

  3. java - DataSource pro samostatnou aplikaci - žádný aplikační server

  4. přidání měsíců k datu SQL