COPY
file ke tabel pementasan sementara dan perbarui tabel aktual dari sana. Seperti:
CREATE TEMP TABLE tmp_x (id int, apple text, banana text); -- but see below
COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE tbl
SET banana = tmp_x.banana
FROM tmp_x
WHERE tbl.id = tmp_x.id;
DROP TABLE tmp_x; -- else it is dropped at end of session automatically
Jika tabel yang diimpor sama persis dengan tabel yang akan diperbarui, ini mungkin lebih mudah:
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
Membuat tabel sementara kosong yang cocok dengan struktur tabel yang ada, tanpa batasan.
Hak Istimewa
Hingga Postgres 10, SQL COPY
membutuhkan hak pengguna super untuk ini.
Di Postgres 11 atau yang lebih baru, ada juga beberapa peran yang telah ditentukan sebelumnya (sebelumnya "peran default") untuk mengizinkannya. Panduan:
COPY
penamaan file atau perintah hanya diperbolehkan untuk superusers atau pengguna database yang diberikan salah satu peranpg_read_server_files
,pg_write_server_files
, ataupg_execute_server_program
[...]
psql meta-command \copy
bekerja untuk peran db apa pun. Panduan:
Melakukan salinan frontend (klien). Ini adalah operasi yang menjalankan
COPY
anSQL perintah, tetapi alih-alih server membaca atau menulis file yang ditentukan, psql membaca atau menulis file dan merutekan data antara server dan sistem file lokal. Ini berarti bahwa aksesibilitas dan hak istimewa file adalah milik pengguna lokal, bukan server, dan tidak diperlukan hak pengguna super SQL.
Cakupan tabel sementara terbatas pada satu sesi dari satu peran, jadi yang di atas harus dieksekusi dalam sesi psql yang sama:
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
Jika Anda membuat skrip ini dalam perintah bash, pastikan untuk membungkus semuanya dalam tunggal panggilan psql. Seperti:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
Biasanya, Anda memerlukan meta-command \\
untuk beralih antara perintah meta psql dan perintah SQL di psql, tetapi \copy
merupakan pengecualian dari aturan ini. Manual lagi:
aturan penguraian khusus berlaku untuk
\copy
meta-perintah. Tidak seperti kebanyakan meta-perintah lainnya, seluruh sisa baris selalu dianggap sebagai argumen\copy
, dan baik interpolasi variabel maupun ekspansi backquote tidak dilakukan dalam argumen.
Meja besar
Jika tabel impor besar, mungkin perlu meningkatkan temp_buffers
sementara untuk sesi (hal pertama dalam sesi):
SET temp_buffers = '500MB'; -- example value
Tambahkan indeks ke tabel sementara:
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
Dan jalankan ANALYZE
secara manual, karena tabel sementara tidak tercakup oleh autovacuum / auto-analyze.
ANALYZE tmp_x;
Jawaban terkait:
- Cara terbaik untuk menghapus jutaan baris menurut ID
- Bagaimana cara memasukkan data umum ke dalam tabel sementara dari skema yang berbeda?
- Bagaimana cara menghapus entri duplikat?