Ответ 1
Технически, чтобы восстановить ваше утверждение, вы можете добавить LIMIT 1
в подзапрос, чтобы гарантировать, что возвращается не более 1 строки. Это устранит ошибку, ваш код по-прежнему будет бессмыслицей.
... 'SELECT store_key FROM store LIMIT 1' ...
Практически вы хотите как-то сопоставить строки, а не выбирать произвольную строку из store
удаленных таблиц, чтобы обновлять каждую строку вашего локального customer
таблицы.
В вашем рудиментарном вопросе не содержится достаточно подробностей, поэтому я предполагаю, что для этого примера текстовый столбец match_name
в обеих таблицах (и UNIQUE
в store
):
... 'SELECT store_key FROM store
WHERE match_name = ' || quote_literal(customer.match_name) ...
Но это чрезвычайно дорогой способ делать вещи.
В идеале вы должны полностью переписать выражение.
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;
Это устраняет ряд проблем в вашем первоначальном заявлении.
-
Очевидно, что основная проблема, связанная с вашей ошибкой, исправлена.
-
Почти всегда лучше присоединяться к дополнительным отношениям в предложении
FROM
оператораUPDATE
чем для запуска коррелированных подзапросов для каждой отдельной строки. -
При использовании dblink вышеупомянутое становится в тысячу раз более важным. Вы не хотите вызывать
dblink()
для каждой отдельной строки, что очень дорого. Позвоните один раз, чтобы получить все нужные строки. -
При коррелированных подзапросах, если ни одна строка не найдена в подзапросе, столбец обновляется до NULL, что почти всегда не то, что вы хотите.
В моей обновленной форме строка обновляется только в том случае, если найдена соответствующая строка. Else, строка не трогается. -
Обычно вы не хотите обновлять строки, когда ничего не меняется. Это дорого ничего не делает (но все же создает мертвые строки). Последнее выражение в
WHERE
предотвращает такие пустые обновления:AND c.customer_id IS DISTINCT FROM sub.store_key