PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

A união postgres garante a ordem de execução ao invocar funções com efeitos colaterais?


Na prática, eles serão executados na ordem dada, mas não há garantia.

Se for garantido, será abordado na documentação ou no padrão SQL. Não vejo nenhuma menção à ordem de execução de um UNION em ambos.

Se o otimizador tivesse um motivo para executar um antes do outro, estaria livre para fazê-lo.

Para garantir a ordem de execução, execute as instruções na ordem desejada:
SELECT * FROM func1();
SELECT * FROM func2();

Se você deseja reduzir as viagens de ida e volta, use as instalações de dosagem de seu cliente, se possível, ou use um DO quadra:
DO
$$
BEGIN
  PERFORM proc1();
  PERFORM proc2();
END;
$$;

Se você precisar retornar valores, use uma função e RETURN QUERY ou RETURN NEXT .

Ou você pode forçar o pedido com um CTE, porque no PostgreSQL (infelizmente) CTEs atuam como cercas de otimização que forçam a materialização dos resultados . No entanto, o AFAIK PostgreSQL ainda não precisa executar os termos CTE na ordem em que são escritos ou na ordem em que são referenciados; a única garantia que você tem é se você fizer isso:
WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;

então function1 deve ser executado e materializado primeiro. No entanto, esse é um recurso específico do PostgreSQL; não é verdade para outros mecanismos de banco de dados, não é garantido pelo padrão, e você não deve confiar nele.

Isso não se estende a
WITH f1 AS (SELECT * FROM function1())
     f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;

... como neste caso o PostgreSQL pode executar os termos CTE independentes em qualquer ordem.

Novamente, com junções, o mesmo princípio se aplica. Se os termos forem independentes, o sistema poderá optar por executá-los em qualquer ordem, embora geralmente não o faça. Então:
select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true

poderia avaliar e materializar bar() então junte seus resultados em foo() .

Se você deseja uma execução ordenada, não deve depender de operações de conjunto, como uniões e junções. Use consultas separadas ou código de procedimento.

Sim existe.
SELECT * FROM function1();
SELECT * FROM function2();