Techniquement , pour réparer votre relevé, vous pouvez ajouter LIMIT 1
à la sous-requête pour s'assurer qu'au plus 1 ligne est renvoyée. Cela supprimerait l'erreur, votre code serait toujours un non-sens.
... 'SELECT store_key FROM store LIMIT 1' ...
Pratiquement , vous voulez faire correspondre les lignes d'une manière ou d'une autre au lieu de choisir une ligne arbitraire dans la table distante store
pour mettre à jour chaque ligne de votre table locale customer
.
Votre question rudimentaire ne fournit pas suffisamment de détails, donc je suppose une colonne de texte match_name
dans les deux tables (et UNIQUE
en store
) pour les besoins de cet exemple :
... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ...
Mais c'est une façon extrêmement coûteuse de faire les choses.
Idéalement , vous réécrivez complètement l'instruction.
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;
Cela résout un certain nombre de problèmes dans votre déclaration d'origine.
Évidemment, le problème de base menant à votre erreur est corrigé.
Il est généralement préférable de joindre des relations supplémentaires dans le FROM
clause d'un UPDATE
plutôt que d'exécuter des sous-requêtes corrélées pour chaque ligne individuelle.
Lorsque vous utilisez dblink, ce qui précède devient mille fois plus important. Vous ne voulez pas appeler dblink()
pour chaque ligne, c'est extrêmement cher . Appelez-le une fois pour récupérer toutes les lignes dont vous avez besoin.
Avec des sous-requêtes corrélées, si aucune ligne n'est trouvée dans la sous-requête, la colonne est mise à jour sur NULL, ce qui n'est presque toujours pas ce que vous voulez. Dans ma requête mise à jour, la ligne n'est mise à jour que si une ligne correspondante est trouvée. Sinon, la ligne n'est pas touchée.
Normalement, vous ne voudriez pas mettre à jour les lignes, alors que rien ne change réellement. Cela coûte cher de ne rien faire (mais produit toujours des lignes mortes). La dernière expression dans WHERE
la clause empêche de telles mises à jour vides :
AND c.customer_id IS DISTINCT FROM sub.store_key
Connexe :
- Comment puis-je (ou puis-je) SELECT DISTINCT sur plusieurs colonnes ?