Secara teknis , untuk memperbaiki pernyataan Anda, Anda dapat menambahkan LIMIT 1 ke subquery untuk memastikan bahwa paling banyak 1 baris dikembalikan. Itu akan menghapus kesalahan, kode Anda akan tetap tidak masuk akal.
... 'SELECT store_key FROM store LIMIT 1' ...
Secara praktis , Anda ingin mencocokkan baris entah bagaimana alih-alih memilih baris arbitrer dari tabel jarak jauh store untuk memperbarui setiap baris tabel customer lokal Anda .
Pertanyaan dasar Anda tidak memberikan detail yang cukup, jadi saya berasumsi kolom teks match_name di kedua tabel (dan UNIQUE di store ) untuk contoh ini:
... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ... Tapi itu cara yang sangat mahal untuk melakukan sesuatu.
Idealnya , Anda benar-benar menulis ulang pernyataan tersebut.
UPDATE customer c
SET customer_id = s.store_key
FROM dblink('port=5432, dbname=SERVER1 user=postgres password=309245'
, 'SELECT match_name, store_key FROM store')
AS s(match_name text, store_key integer)
WHERE c.match_name = s.match_name
AND c.customer_id IS DISTINCT FROM s.store_key;
Ini memperbaiki sejumlah masalah dalam pernyataan awal Anda.
Jelas, masalah dasar yang menyebabkan kesalahan Anda telah diperbaiki.
Biasanya lebih baik untuk bergabung dalam relasi tambahan di FROM klausa dari UPDATE pernyataan daripada menjalankan subkueri berkorelasi untuk setiap baris individu.
Saat menggunakan dblink, hal di atas menjadi seribu kali lebih penting. Anda tidak ingin memanggil dblink() untuk setiap baris, itu sangat mahal . Panggil sekali untuk mengambil semua baris yang Anda butuhkan.
Dengan subkueri yang berkorelasi, jika tidak ada baris yang ditemukan di subquery, kolom diperbarui ke NULL, yang hampir selalu bukan yang Anda inginkan. Dalam kueri saya yang diperbarui, baris hanya diperbarui jika baris yang cocok ditemukan. Jika tidak, baris tidak akan disentuh.
Biasanya, Anda tidak ingin memperbarui baris, ketika tidak ada yang benar-benar berubah. Itu mahal tidak melakukan apa-apa (tetapi masih menghasilkan baris mati). Ekspresi terakhir dalam WHERE klausa mencegah pembaruan kosong such tersebut :
AND c.customer_id IS DISTINCT FROM sub.store_key
Terkait:
- Bagaimana cara (atau dapatkah saya) PILIH BERBEDA pada beberapa kolom?