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?