PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgres Error:Więcej niż jeden wiersz zwrócony przez podzapytanie użyte jako wyrażenie

Technicznie , aby naprawić wyciąg, możesz dodać LIMIT 1 do podzapytania, aby upewnić się, że zostanie zwrócony co najwyżej 1 wiersz. To usunęłoby błąd, Twój kod nadal byłby nonsensem.

... 'SELECT store_key FROM store LIMIT 1' ...

Praktycznie , chcesz dopasować wiersze jakoś zamiast wybierać dowolny wiersz ze zdalnej tabeli store zaktualizować każdy wiersz lokalnej tabeli customer .
Twoje podstawowe pytanie nie zawiera wystarczających szczegółów, więc zakładam kolumna tekstowa match_name w obu tabelach (i UNIQUE w store ) ze względu na ten przykład:

... 'SELECT store_key FROM store
     WHERE match_name = ' || quote_literal(customer.match_name)  ...

Ale to niezwykle kosztowny sposób robienia rzeczy.

Idealnie , całkowicie przepisujesz oświadczenie.

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;

To rozwiązuje szereg problemów w Twoim pierwotnym oświadczeniu.

Oczywiście podstawowy problem prowadzący do twojego błędu został naprawiony.

Zazwyczaj lepiej jest dołączyć do dodatkowych relacji w FROM klauzula UPDATE oświadczenie niż uruchamiać skorelowane podzapytania dla każdego wiersza.

Podczas korzystania z dblink powyższe staje się tysiąc razy ważniejsze. Nie chcesz wywoływać dblink() dla każdego wiersza jest to bardzo drogie . Wywołaj go raz, aby pobrać wszystkie potrzebne wiersze.

Ze skorelowanymi podzapytaniami, jeśli nie znaleziono żadnego wiersza w podzapytaniu kolumna zostaje zaktualizowana do wartości NULL, co prawie zawsze nie jest tym, czego chcesz. W moim zaktualizowanym zapytaniu wiersz jest aktualizowany tylko wtedy, gdy zostanie znaleziony pasujący wiersz. W przeciwnym razie wiersz nie zostanie dotknięty.

Zwykle nie chcesz aktualizować wierszy, gdy nic się nie zmienia. To kosztowne nic nie robi (ale nadal powoduje powstawanie martwych rzędów). Ostatnie wyrażenie w WHERE klauzula zapobiega takim pustym aktualizacjom :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

Powiązane:

  • Jak (lub mogę) WYBRAĆ ODRÓŻNIENIE w wielu kolumnach?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ograniczenia tabel krzyżowych w PostgreSQL

  2. Postgres BŁĄD:nie można otworzyć pliku do odczytu:Odmowa uprawnień

  3. PostgreSQL JOIN z typem tablicy z kolejnością elementów tablicy, jak zaimplementować?

  4. Powolne LEFT JOIN na CTE z interwałami czasowymi

  5. Postgres — Konwertuj listę sąsiedztwa na zagnieżdżony obiekt JSON