質問

私は、Oracle 10gリリース2で、次の更新を実行しようとしています:

update
  (select voyage_port_id, voyage_id, arrival_date, port_seq,
    row_number() over (partition by voyage_id order by arrival_date) as new_seq
   from voyage_port) t
set t.port_seq = t.new_seq

Voyage_port_idはvoyage_idが外部キーである、主キーです。私は、各航海内の日付に基づいてシーケンス番号を割り当てるしようとしています。

データ操作操作ではない法的このビューでの

しかし、上記の ORA-01732で失敗します

どのような問題があると私はそれを避けることができるか?

役に立ちましたか?

解決

あなたはrow_numberでサブクエリを更新することはできませんので、

は、更新のset部の行数を計算する必要があります。最初に私はこれを試してみました。

update voyage_port a
set a.port_seq = (
  select 
    row_number() over (partition by voyage_id order by arrival_date)
  from voyage_port b
  where b.voyage_port_id = a.voyage_port_id
)

しかし、サブクエリが1行のみ選択し、次いでrow_number()が常に別のサブクエリを使用して1である意味のある結果を可能にするので、それは、動作しない

update voyage_port a
set a.port_seq = (
  select c.rn
  from (
      select 
        voyage_port_id
      , row_number() over (partition by voyage_id 
            order by arrival_date) as rn
      from voyage_port b
   ) c
  where c.voyage_port_id = a.voyage_port_id
)

これは動作しますが、私はこの作業のために期待するよりも、より複雑ます。

他のヒント

あなたが派生テーブルを更新することができるとは思わない、私は書き直したい:

update voyage_port
set port_seq = t.new_seq
from
voyage_port p
inner join
  (select voyage_port_id, voyage_id, arrival_date, port_seq,
   row_number() over (partition by voyage_id order by arrival_date) as new_seq
   from voyage_port) t
on p.voyage_port_id = t.voyage_port_id

UPDATE後の最初のトークンは、あなたの列-に更新、更新するテーブルの名前でなければなりません。私はあなたはそれがあるselect文で達成しようとしているかわからないんだけど、あなたのことができ」の更新の法的選択の結果セット。
SQLのバージョンは、あなたが心の中に持っているものを推測し、

...のようになります。
update voyage_port t
set t.port_seq = (<select statement that generates new value of port_seq>)

注:!のあなただけの1行が選択から返されることを確認する必要があり、このように値を設定するために、SELECT文を使用する

編集:私は説明しようとしていたものを反映するために、上記の変更のステートメント。質問は、

上Andomarすることにより、非常にきれいに回答されています
scroll top