Apakah COMMIT berfungsi dalam fungsi plgpsql anonim di PostgreSQL 9.5?

8

Saya mengimpor sejumlah besar file besar ke sejumlah tabel untuk dipartisi menggunakan loop dalam blok kode plpgsql anonim $do$.

$do$
BEGIN
    FOR yyyy in 2012..2016 THEN 
        EXECUTE $$COPY table$$||yyyy||$$ FROM 'E:\data\file$$||yyyy||$$.csv DELIMITER ',' CSV;$$;
    END LOOP;
END;
$do$ LANGUAGE plpgsql

Seluruh proses ini akan memakan waktu sekitar 15 jam dan saya berharap bahwa semua impor tidak akan dibatalkan jika ada kesalahan impor di beberapa titik.

IIRC COMMITtidak berfungsi dalam fungsi tersimpan bc seluruh fungsi diperlakukan sebagai satu transaksi.

Dari dokumentasi untuk$do$

Blok kode diperlakukan seolah-olah itu adalah tubuh fungsi tanpa parameter, mengembalikan batal. Itu diurai dan dieksekusi satu kali.

Saya mengasumsikan ini berarti bahwa keseluruhan $do$adalah satu transaksi, dan jadi komitmen di dalam blok tidak akan berfungsi. Apakah saya benar?

raphael
sumber
1
Coba BEGINatau COMMITdi tubuh fungsi. Anda akan mendapatkan pengecualian, karena itu tidak diizinkan (tidak mungkin).
Erwin Brandstetter

Jawaban:

9

Tidak,

Anda tidak dapat mengontrol transaksi di dalam suatu plpgsqlfungsi (atau blok anonim).

Satu-satunya opsi yang Anda miliki adalah membuat transaksi di luar blok, misalnya:

BEGIN;

DO $$
  -- function stuff

  -- but if you use a exception, you will force a rollback
  RAISE EXCEPTION 'message';
$$ LANGUAGE 'plpgsql';

COMMIT; -- OR ROLLBACK

BTW, DO BLOCKSmemiliki efek yang sama dengan fungsi yang mengembalikan void.

Silakan, lihat lebih lanjut di dokumen:

Sebastian Webber
sumber
Apakah kita tahu apakah ini masih terjadi? Saya memiliki fungsi yang perlu diulang beberapa ratus kali. Loop pertama membutuhkan waktu 2 detik setelah tanggal 7 mendekati satu jam dan saya belum melihat apa pun setelah putaran ke-10.
Dennis Bauszus
1

Satu-satunya solusi untuk melakukan dalam "DO" blok (atau fungsi) (untuk versi Postgresql kurang dari 11) adalah dengan menggunakan koneksi dblink ke server yang sama dan jalankan permintaan Anda di sana. Hanya perlu diingat variabel dan visibilitas objek sementara.

informasi lebih lanjut tentang dblink Dimulai dengan kontrol transaksi Postgresql-11 dari dalam blok "DO" tersedia sementara "blok-DO" tidak berjalan dalam transaksi lain.

Dzhureedzh
sumber
postgresql.org/docs/11/sql-do.html menyatakan 'Pernyataan kontrol transaksi hanya diperbolehkan jika DO dieksekusi dalam transaksinya sendiri.' Ini tentu saja tidak benar dengan 9.5. OTOH dengan dblinkAnda akan membuka transaksi lain, jadi COMMITpanggilan Anda di sana tidak akan memengaruhi transaksi panggilan, jika saya tidak salah.
dezso
Salahku. Kontrol transaksi dalam "DO" diperkenalkan di Postgresql-11. Saya hanya memeriksa 10.4 masih tidak berfungsi.
Dzhureedzh
@dezso Terima kasih telah menunjukkan kepada saya tentang hal ini, saya menggunakan metode dblink bahkan pada server PG11.
Dzhureedzh