Dalam praktiknya mereka akan dieksekusi sesuai urutan yang diberikan, tetapi tidak ada jaminan yang dibuat.
Jika dijamin, maka akan tercakup dalam dokumentasi atau standar SQL. Saya tidak melihat penyebutan urutan eksekusi UNION
di keduanya.
Jika pengoptimal memiliki alasan untuk mengeksekusi satu sebelum yang lain, itu akan bebas untuk melakukannya.
Untuk memastikan urutan eksekusi, jalankan pernyataan dalam urutan yang diinginkan:
SELECT * FROM func1();
SELECT * FROM func2();
Jika Anda ingin mengurangi perjalanan pulang pergi, gunakan fasilitas batching klien Anda jika memungkinkan, atau gunakan DO
blok:
DO
$$
BEGIN
PERFORM proc1();
PERFORM proc2();
END;
$$;
Jika Anda perlu mengembalikan nilai, gunakan fungsi dan RETURN QUERY
atau RETURN NEXT
.
Atau Anda dapat memaksa memesan dengan CTE, karena di PostgreSQL (sayangnya) CTE bertindak sebagai pagar pengoptimalan yang memaksa terwujudnya hasil . Namun, AFAIK PostgreSQL masih tidak harus menjalankan persyaratan CTE sesuai urutan penulisannya, atau urutan referensinya; satu-satunya jaminan yang Anda dapatkan adalah jika Anda melakukan ini:
WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;
lalu function1
harus dilaksanakan dan diwujudkan terlebih dahulu. Itu adalah kesalahan khusus PostgreSQL; itu tidak berlaku untuk mesin database lain, tidak dijamin oleh standar, dan Anda tidak boleh mengandalkannya.
Itu tidak mencakup
WITH f1 AS (SELECT * FROM function1())
f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;
... seperti dalam kasus ini PostgreSQL dapat mengeksekusi istilah CTE independen dalam urutan apa pun.
Sekali lagi, dengan bergabung, prinsip yang sama berlaku. Jika istilah independen maka sistem dapat memilih untuk menjalankannya dalam urutan apa pun, meskipun umumnya tidak. Jadi:
select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true
dapat mengevaluasi dan mewujudkan bar()
lalu gabungkan hasilnya di foo()
.
Jika Anda ingin eksekusi berurutan, Anda tidak boleh mengandalkan operasi yang ditetapkan seperti gabungan dan gabungan. Gunakan kueri terpisah, atau kode prosedural.
Ya, ada.
SELECT * FROM function1();
SELECT * FROM function2();