PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Postgres union гарантира ли ред на изпълнение при извикване на функции със странични ефекти?

На практика те ще бъдат изпълнени в дадения ред, но няма гаранция.

Ако е гарантирано, тогава ще бъде покрито в документацията или стандарта SQL. Не виждам никакво споменаване на реда на изпълнение на UNION в двете.

Ако оптимизаторът имаше причина да изпълни единия преди другия, щеше да е свободен да го направи.

За да осигурите ред на изпълнение, изпълнете изрази в желания ред:

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

Ако искате да намалите двупосочните пътувания, използвайте съоръженията за пакетиране на клиента, ако е възможно, или използвайте DO блокиране:

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

Ако трябва да върнете стойности, използвайте функция и RETURN QUERY или RETURN NEXT .

Или можете да наложите поръчка с CTE, защото в PostgreSQL (за съжаление) CTE действат като оптимизационни прегради, които принуждават материализирането на резултатите . Въпреки това, AFAIK PostgreSQL все още не трябва да изпълнява условията на CTE в реда, в който са написани или в реда, в който са посочени; единствената гаранция, която получавате, е ако направите това:

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

след това function1 първо трябва да се изпълни и материализира. Това обаче е специфична за PostgreSQL грешка; това не е вярно за други машини за бази данни, не е гарантирано от стандарта и не трябва да разчитате на него.

Това не се отнася до

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

... тъй като в този случай PostgreSQL може да изпълни независимите условия на CTE в двата реда.

Отново, с обединенията се прилага същият принцип. Ако термините са независими, тогава системата може да избере да ги изпълнява в произволен ред, въпреки че обикновено не го прави. И така:

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

може да оцени и материализира bar() след това обединете резултатите му на foo() .

Ако искате подредено изпълнение, не трябва да разчитате на наборни операции като обединения и присъединявания. Използвайте отделни заявки или процедурен код.

Да, има.

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Entity Framework Core postgresql Array Type Mapping не работи

  2. защо записите в една таблица предотвратяват вакуумите в друга?

  3. Защо null||null връща нулева стойност, но concat(null,null) връща празен низ в postgres?

  4. Как да защитите вашите PostgreSQL бази данни от кибератаки с SQL защитна стена

  5. Дублиращи се редове в таблица с първичен ключ.