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 COMMIT
tidak berfungsi dalam fungsi tersimpan bc seluruh fungsi diperlakukan sebagai satu transaksi.
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?
postgresql
transaction
plpgsql
postgresql-9.5
raphael
sumber
sumber
BEGIN
atauCOMMIT
di tubuh fungsi. Anda akan mendapatkan pengecualian, karena itu tidak diizinkan (tidak mungkin).Jawaban:
Tidak,
Anda tidak dapat mengontrol transaksi di dalam suatu
plpgsql
fungsi (atau blok anonim).Satu-satunya opsi yang Anda miliki adalah membuat transaksi di luar blok, misalnya:
BTW,
DO BLOCKS
memiliki efek yang sama dengan fungsi yang mengembalikanvoid
.Silakan, lihat lebih lanjut di dokumen:
sumber
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.
sumber
dblink
Anda akan membuka transaksi lain, jadiCOMMIT
panggilan Anda di sana tidak akan memengaruhi transaksi panggilan, jika saya tidak salah.