Oracle查询失败:缺少右括号

时间:2015-10-21 16:02:54

标签: oracle

我在 ORACLE SGBD

上执行此查询
service

执行此查询我收到此错误:

update product p set p.PROVIDER_ID = 
( select PROVIDER_ID from provider pr where pr.VALID_FROM is not null 
 and ((pr.VALID_TO is not null and pr.VALID_TO < p.VALID_TO ) 
 or (pr.VALID_TO is  null and pr.VALID_FROM < p.VALID_TO) )
 and rownum < 2 order by valid_to desc 
)
 where p.VALID_FROM is not null and p.VALID_TO is not null;

此时我被阻止了。

1 个答案:

答案 0 :(得分:1)

这几乎是this的重复,因为直接的问题是你在子查询中有一个order by子句 - 这是不允许的并且导致了这个错误。 Oracle希望在rownum < 2之后看到子查询的右括号。

但在这种情况下,它会稍微复杂一点,因为您需要按顺序获取所需的行以进行匹配,并且您在错误的位置进行了rownum检查;即使是一个独立的查询,它也不会给你你期望的结果,因为它会找到一个不确定的行然后命令那一行,这是没有意义的。

您需要另一个图层,因此您的子查询具有可以排序的内联视图,然后您从该第一行获取:

update product p set p.PROVIDER_ID = 
(
  select PROVIDER_ID from (
    select pr.PROVIDER_ID from provider pr
    where pr.VALID_FROM is not null 
    and ((pr.VALID_TO is not null and pr.VALID_TO < p.VALID_TO) 
      or (pr.VALID_TO is null and pr.VALID_FROM < p.VALID_TO))
    order by pr.VALID_TO desc
  )
  where rownum < 2
)
where p.VALID_FROM is not null and p.VALID_TO is not null;

但现在您将获得ORA-00904: "P"."VALID_TO": invalid identifier因为您尝试通过引用p别名中的两个级别的列来关联更新,Oracle不允许这样做

另一种方法是使用分析,例如keep dense_rank

update product p set p.PROVIDER_ID = 
(
  select max(pr.PROVIDER_ID) keep (dense_rank first order by pr.VALID_TO desc)
  from provider pr
  where pr.VALID_FROM is not null 
  and ((pr.VALID_TO is not null and pr.VALID_TO < p.VALID_TO) 
    or (pr.VALID_TO is null and pr.VALID_FROM < p.VALID_TO))
)
where p.VALID_FROM is not null and p.VALID_TO is not null;

...确实成功运行。 (我不完全确定你的日期比较逻辑,但这是一个单独的问题,实际上可能就是你想要的。)

相关问题