我试图做的Oracle 10gR2中以下更新:

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
)

但是,这并不工作,因为子查询仅选择一个行,然后将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
)

它的工作原理,但更复杂的比我预期这个任务。

其他提示

可以更新一些视图,但有限制,一个是该视图中不能包含解析函数。请参见 SQL语言参考上更新和搜索的第一次出现的“分析”。

这将工作,没有提供航程访问多于一个的端口在同一天(或日期包括时间分量,这使得它们是唯一的):

update voyage_port vp
set vp.port_seq =
( select count(*)
  from voyage_port vp2
  where vp2.voyage_id = vp.voyage_id
  and vp2.arrival_date <= vp.arrival_date
)

我认为这种处理的情况下航行的访问每天超过1个端口,并且没有时间分量(虽然端口的序列访问在同一天然后任意的):

update voyage_port vp
set vp.port_seq =
( select count(*)
  from voyage_port vp2
  where vp2.voyage_id = vp.voyage_id
  and (vp2.arrival_date <= vp.arrival_date)
  or (   vp2.arrival_date = vp.arrival_date 
     and vp2.voyage_port_id <= vp.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

更新后的第一个记号应该是表的名称进行更新,那么你列到更新。我不知道你正在努力实现与SELECT语句的地方是什么,但你可以”的更新的结果从选择设置459。结果 在SQL的一个版本,猜测你有什么想法,可能看起来像......

update voyage_port t
set t.port_seq = (<select statement that generates new value of port_seq>)

注意:,以使用select语句来设置这样的价值,你必须确保只有1行将从选择返回

编辑:上述修改声明以反映什么,我试图解释。该问题已回答非常漂亮通过Andomar上述

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top