2013-07-10 20 views
1

我在Java中的下列准备好的声明:维持秩序与选择... In和锁定线

with main_select as 
    (select request_id,rownum iden 
    from 
    (select request_id 
    from queue_requests 
    where request_status = 0 and 
      date_requested <= sysdate and 
      mod(request_id,?) = ? 
    order by request_priority desc, oper_id, date_requested) 
    where rownum < ?) 

select * 
from queue_requests qr, main_select ms 
where qr.request_id in ms.request_id 
order by ms.iden for update skip locked; 

它不执行:

ORA-02014:不能选择从视图与DISTINCT,GROUP BY UPDATE等

我会尝试解释为什么我需要所有的SELECT语句:

  • 第一个(内部)选择获得我需要的数据
  • 第二个将行数限制为一个数字(我不能把它放在第一个选择中,因为oracle首先限制结果,并且只有在命令它们之后,这是不是我想要的)
  • 第三(与外部)选择保留顺序(我尝试使用3嵌套选择 - 所以,没有子句 - 但我找不到一种方法来保存在这种情况下的顺序)。另外,它应该锁定queue_requests表中的行,但是因为我从with子句中选择了数据,所以会出现上述错误。

所以,我想从queue_requests中选择数据,保留第一个x行,保留select的顺序并锁定行。

有没有办法做到这一点?

+0

我意识到,在我的具体情况下,我选择数据与MOD,所以每个线程将选择自己的表的一部分,所以我可以安全地删除“更新跳过锁定”。但是,对于一般情况下,其中的选择不使用MOD,它确实需要锁定线路,我会保持打开这个问题。 – Anakin001

回答

0

这个问题似乎是,你想对main_select的结果设置一个锁。我只是猜测,你可以做的选择select for update在与像子句:

with main_select as 
    (select request_id,rownum iden 
    from (subselect) 
    where rownum < ? 
    for update skip locked) 

但正如我所说幸运的猜测。

+0

不,它不起作用。现在它说:ORA-00907:缺少右括号。我经常遇到这个错误,这有点奇怪,因为(在我看来)它与该假设无关。如果我删除“更新跳过锁定”错误消失,所以我不知道有什么问题。 – Anakin001

+0

哎呀..然后删除分号:) – contradictioned

+0

事情是,不知何故数据库必须知道,它必须锁定哪些行。如果你像'SELECT * FROM foo WHERE x <= 5 FOR UPDATE SKIP LOCKED'那样做,那么结果是表'foo'中所有东西的一个子集,结果行仍然有rowId,它可以用来标识行被锁定。 但我认为这些信息在(a)with-clause或(b)与表queue_requests或(c)在排序过程中失去联系。 – contradictioned