sql >> Base de Datos >  >> RDS >> PostgreSQL

Error de Postgres:más de una fila devuelta por una subconsulta utilizada como expresión

Técnicamente , para reparar su estado de cuenta, puede agregar LIMIT 1 a la subconsulta para garantizar que se devuelva como máximo 1 fila. Eso eliminaría el error, tu código seguiría siendo una tontería.

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

Prácticamente , desea hacer coincidir las filas de alguna manera en lugar de elegir una fila arbitraria de la tabla remota store para actualizar cada fila de su tabla local customer .
Su pregunta rudimentaria no proporciona suficientes detalles, así que supongo una columna de texto match_name en ambas tablas (y UNIQUE en store ) por el bien de este ejemplo:

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

Pero esa es una forma extremadamente costosa de hacer las cosas.

Idealmente , reescribe completamente la declaración.

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;

Esto soluciona una serie de problemas en su estado de cuenta original.

Obviamente, el problema básico que conduce a su error está arreglado.

Por lo general, es mejor unirse a relaciones adicionales en el FROM cláusula de un UPDATE declaración que ejecutar subconsultas correlacionadas para cada fila individual.

Al usar dblink, lo anterior se vuelve mil veces más importante. No desea llamar a dblink() por cada fila, eso es extremadamente caro . Llámelo una vez para recuperar todas las filas que necesita.

Con subconsultas correlacionadas, si no se encuentra ninguna fila en la subconsulta, la columna se actualiza a NULL, que casi siempre no es lo que desea. En mi consulta actualizada, la fila solo se actualiza si se encuentra una fila coincidente. De lo contrario, la fila no se toca.

Normalmente, no querría actualizar las filas, cuando en realidad nada cambia. Eso es costoso no hacer nada (pero aún produce filas muertas). La última expresión en WHERE cláusula evita tales actualizaciones vacías :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

Relacionado:

  • ¿Cómo puedo (o puedo) SELECCIONAR DISTINTO en varias columnas?