sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgres-fejl:Mere end én række returneret af en underforespørgsel, der bruges som et udtryk

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?


  1. Ikke mere SPU

  2. MAX vs Top 1 - hvad er bedre?

  3. Skift PostgreSql-databasekodning

  4. Sådan gemmer du sqlite-database direkte på sdcard