0

PostgreSQL を使用しており、自動採番列 ID を含むテーブルを更新したいと考えています。非常に単純なことかもしれませんが、私はこのようなことをしました。

CREATE SEQUENCE  SEQ_ID
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10

update trk2
set (id, track_id, track_point) =
           (select nextval('seq_id'), trk1.track_fid, trk1.wkb_geometry
              from track_points_1 as trk1
             where track_fid = 0)

問題は、次のエラーが表示されることです(コードが再フォーマットされました):

ERROR:  syntax error at or near "select"
LINE 3: set (id, track_id, track_point)=(select nextval('seq_id'), t...

誰でも助けてもらえますか?

4

3 に答える 3

2

あなたのクエリはいくつかの場所で壊れています。次のようになります。

UPDATE trk2
SET   (id, track_id, track_point) = 
      (next_id, x.track_fid, x.wkb_geometry)
FROM  (
   SELECT id
         ,nextval('seq_id') AS next_id
         ,track_fid
         ,wkb_geometry
   FROM   track_points_1
   WHERE  track_fid = 0
   ) x
WHERE  trk2.id = x.id;  -- adapt to your case

またはより単純な(好ましい構文):

UPDATE trk2
SET   (id, track_id, track_point) = 
      (nextval('seq_id'), x.track_fid, x.wkb_geometry)
FROM   track_points_1 x
WHERE  x.track_fid = 0
AND    trk2.id = x.id;   -- adapt to your case

主なポイント:

  • UPDATE句なしは、テーブル内のWHEREすべての行を本当に変更する必要がある場合にのみ意味があります。そうでなければ、それは間違っているか、少なくとも最適ではありません。

    別のテーブルから値を取得するときに、ターゲットとソースを接続CROSS JOINする句を追加しないと、ターゲットとソースの間に が取得されますWHERE。つまり、ターゲット テーブルのすべての行がソース テーブルのすべての行で更新されます。これには非常に長い時間がかかり、任意の結果が生じる可能性があります。最後のUPDATE勝利。要するに、これはほとんどの場合完全にナンセンスであり、非常にコストがかかります。

    私の例では、ターゲットとソースをid列でリンクしています。それをあなたのケースに合うものに置き換える必要があります。

  • の 1 つの句で複数の値を割り当てることができますが、相関副選択式からは 1 つの値しか返すことができません。したがって、複数の値を持つ句にサブセレクトを含めることは厳密に不可能です。SETUPDATESET

  • 最初の構文エラーは、副選択を囲む括弧のペアが欠落していることが原因です。しかし、それを追加しても、上記のエラーのみが明らかになります。

  • 目的に応じてnextval('seq_id')、サブクエリまたはSET句に直接含めます。これにより、特にサブクエリにUPDATE.

    私はそれをSET節に入れました。それがあなたが望んでいることだと思うからです。行の順序は依然として任意です。どの番号が割り当てられるかをより詳細に制御したい場合は、必要なものを定義してから、別のルートを取る必要があります。

于 2012-10-31T20:01:08.770 に答える
1

Tyler Eaves は正しいです。このアクションはお勧めできません

ただし、主張する場合は、これが役立つ場合があります。

nextval()列にシーケンスがあれば、SETステートメントで呼び出す必要はありません。そのままにしておくと、列は自動インクリメントされます。

UPDATE
    trk2
SET 
    (
        track_id = [track_id Value],
        track_point = [track_point Value]
    )

または、それを含めてまたはに設定しdefaultますnull

UPDATE
    trk2
SET 
    (
        id = default,
        track_id = [track_id Value],
        track_point = [track_point Value]
    )

あなたの例を使用して:

UPDATE
    trk2
SET 
    (
        track_id, 
        track_point
    ) = (
        SELECT 
            trk1.track_fid,
            trk1.wkb_geometry
        FROM 
            track_points_1 AS trk1
        WHERE
            track_fid = 0
    )
于 2012-10-31T17:51:54.940 に答える
0

SET 句の RHS に 2 番目の括弧が必要だと思います。

UPDATE trk2
SET (id, track_id, track_point) =
          ((SELECT nextval('seq_id'), trk1.track_fid, trk1.wkb_geometry
              FROM track_points_1 as trk1
             WHERE track_fid = 0));

括弧の最初のセットは、SET 句の LHS の括弧と一致します。2 番目のセットは、再利用のためにサブクエリをラップします。

于 2012-10-31T17:58:33.917 に答える