Technisch , um Ihre Aussage zu reparieren, können Sie LIMIT 1
hinzufügen an die Unterabfrage, um sicherzustellen, dass höchstens 1 Zeile zurückgegeben wird. Das würde den Fehler beseitigen, dein Code wäre immer noch Unsinn.
... 'SELECT store_key FROM store LIMIT 1' ...
Praktisch , möchten Sie Zeilen irgendwie abgleichen anstatt eine beliebige Zeile aus der entfernten Tabelle store
auszuwählen um jede Zeile Ihrer lokalen Tabelle customer
zu aktualisieren .
Ihre rudimentäre Frage liefert nicht genügend Details, also gehe ich annehmen eine Textspalte match_name
in beiden Tabellen (und UNIQUE
im store
) für dieses Beispiel:
... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ...
Aber das ist eine extrem teure Methode.
Im Idealfall , schreiben Sie die Anweisung komplett neu.
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;
Dies behebt eine Reihe von Problemen in Ihrer ursprünglichen Anweisung.
Offensichtlich das grundlegende Problem was zu Ihrem Fehler führt, wird behoben.
Normalerweise ist es besser, zusätzliche Relationen in FROM
einzufügen -Klausel eines UPDATE
Anweisung statt korrelierte Unterabfragen auszuführen für jede einzelne Zeile.
Bei der Verwendung von dblink wird das Obige tausendmal wichtiger. Sie möchten dblink()
nicht aufrufen für jede einzelne Zeile ist das extrem teuer . Rufen Sie es einmal auf, um alle benötigten Zeilen abzurufen.
Bei korrelierten Unterabfragen, wenn keine Zeile gefunden wird in der Unterabfrage wird die Spalte auf NULL aktualisiert, was fast immer nicht das ist, was Sie wollen. In meiner aktualisierten Abfrage wird die Zeile nur aktualisiert, wenn eine übereinstimmende Zeile gefunden wird. Andernfalls wird die Zeile nicht berührt.
Normalerweise möchten Sie Zeilen nicht aktualisieren, wenn sich eigentlich nichts ändert. Das ist teuer, nichts zu tun (aber immer noch tote Zeilen zu produzieren). Der letzte Ausdruck im WHERE
-Klausel verhindert solche leeren Updates :
AND c.customer_id IS DISTINCT FROM sub.store_key
Verwandte:
- Wie kann ich (oder kann ich) DISTINCT für mehrere Spalten auswählen?