PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana cara memperbarui baris yang dipilih dengan nilai dari file CSV di Postgres?

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 peran pg_read_server_files ,pg_write_server_files , atau pg_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?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Panggilan fungsi PostgreSQL

  2. Partisi Replikasi Logis Dengan PostgreSQL 13

  3. Bisakah saya menggunakan nilai pengembalian INSERT...RETURNING di INSERT lain?

  4. Tambahkan Tanda Plus/Minus ke Angka di PostgreSQL

  5. Cara Mengisi Tanggal yang Hilang di PostgreSQL menggunakan generate_series