Teknisk , for at reparere din erklæring kan du tilføje LIMIT 1
til underforespørgslen for at sikre, at der højst returneres 1 række. Det ville fjerne fejlen, din kode ville stadig være nonsens.
... 'SELECT store_key FROM store LIMIT 1' ...
Praktisk set , vil du matche rækker på en eller anden måde i stedet for at vælge en vilkårlig række fra fjerntabellen store
for at opdatere hver række i din lokale tabel customer
.
Dit rudimentære spørgsmål giver ikke nok detaljer, så jeg antager en tekstkolonne match_name
i begge tabeller (og UNIQUE
i store
) af hensyn til dette eksempel:
... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ...
Men det er en ekstremt dyr måde at gøre tingene på.
Ideelt set , du omskriver erklæringen fuldstændigt.
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;
Dette afhjælper en række problemer i din oprindelige erklæring.
Det er klart det grundlæggende problem fører til din fejl er rettet.
Det er typisk bedre at deltage i yderligere relationer i FROM
klausul af en UPDATE
sætning end at køre korrelerede underforespørgsler for hver enkelt række.
Når du bruger dblink, bliver ovenstående tusind gange vigtigere. Du ønsker ikke at kalde dblink()
for hver enkelt række er det ekstremt dyrt . Kald det én gang for at hente alle rækker, du har brug for.
Med korrelerede underforespørgsler, hvis ingen række er fundet i underforespørgslen bliver kolonnen opdateret til NULL, hvilket næsten altid ikke er, hvad du ønsker. I min opdaterede forespørgsel bliver rækken kun opdateret, hvis der findes en matchende række. Ellers røres rækken ikke.
Normalt ønsker du ikke at opdatere rækker, når intet rent faktisk ændrer sig. Det er dyrt at gøre ingenting (men producerer stadig døde rækker). Det sidste udtryk i WHERE
klausul forhindrer sådanne tomme opdateringer :
AND c.customer_id IS DISTINCT FROM sub.store_key
Relateret:
- Hvordan (eller kan jeg) VÆLGE DISTINCT på flere kolonner?