sql >> Database >  >> RDS >> PostgreSQL

Postgres-fout:meer dan één rij geretourneerd door een subquery die als expressie wordt gebruikt

Technisch , om uw afschrift te herstellen, kunt u LIMIT 1 . toevoegen naar de subquery om ervoor te zorgen dat er maximaal 1 rij wordt geretourneerd. Dat zou de fout verwijderen, je code zou nog steeds onzin zijn.

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

Praktisch , u wilt op de een of andere manier overeenkomen met rijen in plaats van een willekeurige rij te kiezen uit de tabel op afstand store om elke rij van uw lokale tabel customer bij te werken .
Uw rudimentaire vraag geeft niet genoeg details, dus aangenomen een tekstkolom match_name in beide tabellen (en UNIQUE in store ) omwille van dit voorbeeld:

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

Maar dat is een extreem dure manier om dingen te doen.

Idealiter , herschrijft u de verklaring volledig.

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;

Dit verhelpt een aantal problemen in uw oorspronkelijke verklaring.

Het is duidelijk dat het basisprobleem leidend tot uw fout is opgelost.

Het is doorgaans beter om deel te nemen aan aanvullende relaties in de FROM clausule van een UPDATE statement dan om gecorreleerde subquery's uit te voeren voor elke afzonderlijke rij.

Bij gebruik van dblink wordt het bovenstaande duizend keer belangrijker. U wilt dblink() . niet aanroepen voor elke rij is dat extreem duur . Roep het één keer aan om alle rijen op te halen die je nodig hebt.

Met gecorreleerde subquery's, als geen rij is gevonden in de subquery wordt de kolom bijgewerkt naar NULL, wat bijna altijd niet is wat je wilt. In mijn bijgewerkte zoekopdracht wordt de rij alleen bijgewerkt als er een overeenkomende rij wordt gevonden. Anders wordt de rij niet aangeraakt.

Normaal gesproken zou u rijen niet willen bijwerken als er niets verandert. Dat is duur niets doen (maar levert toch dode rijen op). De laatste uitdrukking in de WHERE clausule voorkomt dergelijke lege updates :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

Gerelateerd:

  • Hoe kan (of kan ik) DISTINCT SELECTEREN op meerdere kolommen?


  1. Volledige MariaDB-codering in rust en tijdens transport voor maximale gegevensbescherming - deel twee

  2. SQL INSERT INTO uit meerdere tabellen

  3. Tijdgedeelte van een DateTime-veld in SQL

  4. Nieuwe Azure SQL Database standaard tierformaten