Tecnicamente , para reparar seu extrato, você pode adicionar
LIMIT 1
para a subconsulta para garantir que no máximo 1 linha seja retornada. Isso removeria o erro, seu código ainda seria um absurdo. ... 'SELECT store_key FROM store LIMIT 1' ...
Praticamente , você deseja corresponder as linhas de alguma forma em vez de escolher uma linha arbitrária da tabela remota
store
para atualizar cada linha de sua tabela local customer
.Sua pergunta rudimentar não fornece detalhes suficientes, então estou supondo uma coluna de texto
match_name
em ambas as tabelas (e UNIQUE
em store
) por causa deste exemplo:... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ...
Mas essa é uma maneira extremamente cara de fazer as coisas.
Idealmente , você reescreve completamente a instrução.
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;
Isso corrige uma série de problemas em sua declaração original.
Obviamente, o problema básico levando ao seu erro é corrigido.
Normalmente é melhor juntar relações adicionais no
FROM
cláusula de um UPDATE
instrução do que executar subconsultas correlacionadas para cada linha individual. Ao usar dblink, o acima se torna mil vezes mais importante. Você não quer chamar
dblink()
para cada linha, isso é extremamente caro . Chame-o uma vez para recuperar todas as linhas que você precisa. Com subconsultas correlacionadas, se nenhuma linha for encontrada na subconsulta, a coluna é atualizada para NULL, o que quase sempre não é o que você deseja. Na minha consulta atualizada, a linha só é atualizada se uma linha correspondente for encontrada. Caso contrário, a linha não é tocada.
Normalmente, você não gostaria de atualizar as linhas, quando nada realmente muda. Isso é caro não fazer nada (mas ainda produz linhas mortas). A última expressão no
WHERE
cláusula impede tais atualizações vazias : AND c.customer_id IS DISTINCT FROM sub.store_key
Relacionado:
- Como posso (ou posso) SELECT DISTINCT em várias colunas?