1. ホーム
  2. sql

[解決済み】Postgresのエラー。式として使用されるサブクエリによって返される複数の行

2022-02-02 01:38:02

質問

私は2つの別々のデータベースを持っています。一方のデータベースのカラムを、もう一方のデータベースのカラムの値に更新しようとしています。

UPDATE customer
SET customer_id=
   (SELECT t1 FROM dblink('port=5432, dbname=SERVER1 user=postgres password=309245',
   'SELECT store_key FROM store') AS (t1 integer));

これは、私が受け取っているエラーです。

ERROR:  more than one row returned by a subquery used as an expression

何かアイデアはありますか?

解決方法は?

技術的 を追加して、ステートメントを修正することができます。 LIMIT 1 をサブクエリに追加して、最大で 1 行が返されるようにします。そうすれば、エラーはなくなりますが、あなたのコードはまだ無意味なままです。

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

実質的に の場合、行をマッチングさせたい 何とか リモートテーブルから任意の行を選ぶのでなく store を使用して、ローカルテーブルのすべての行を更新します。 customer .
あなたの初歩的な質問では詳細が十分ではないので、私は 仮定 テキスト欄 match_name の両方のテーブルで(そして UNIQUEstore ) を、この例では

... '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を使用する場合、上記は1000倍重要になります。を呼び出したくはないでしょう。 dblink() を1行ごとに使うのは 非常に高い . 必要な行をすべて取得するために一度だけ呼び出す。

相関サブクエリでは、もし 行が見つからない を使用すると、カラムは NULL に更新され、ほとんどの場合、それは望んだものではありません。私の更新されたクエリでは、一致する行が見つかった場合のみ、行が更新されます。そうでなければ、行には手を付けません。

通常、実際には何も変化しないのに行を更新することはありません。それは、何もしない(しかし、死んだ行を生成する)ことになり、コストがかかります。の最後の式は WHERE 節はそのようなことを防ぐために 空の更新 :

     AND   c.customer_id IS DISTINCT FROM sub.store_key

関連する