2010-10-15 11 views
6

In Oracle, posso selezionare la parte superiore 1 messaggio in una tabella ordinata conSelezionare top N con "per l'aggiornamento Skip bloccato" in Oracle

select messageid from(
    select 
     messageid, 
     RANK() over (order by messageid asc) as msg_rank 
    from messages 
) where msg_rank=1; 

E come ho scoperto in un previous question posso selezionare una riga in esclusiva con

select * from messages where rownum < 2 for update skip locked; 

Tuttavia non posso unire questi due concetti insieme

select messageid from(
    select 
     messageid, 
     RANK() over (order by messageid asc) as msg_rank 
    from messages 
) where msg_rank=1 for update skip locked; 

-- results in error 
-- ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc. 

Come posso selezionare esimo e top N con blocco del readpast?

+0

penso che questo post del blog ha alcuni pensieri importanti: http://markjbobak.wordpress.com/2010/04/06/unintended-consequences/ –

risposta

2

Funzionerà?

select messageid from messages 
    where messageid in (
     select messageid from(
     select 
      messageid, 
      RANK() over (order by messageid asc) as msg_rank 
      from messages 
     ) where msg_rank=1 
    ) 
    for update skip locked; 
+0

Se è fatto in due fasi, io non sono l'introduzione di un potenziale condizione di gara? Seguo la tua logica, ma trovo difficile credere che Oracle non possa fare ciò che può fare SQL Server. – Synesso

+0

Questa query è stata eseguita correttamente. Continuerò a verificare che il blocco funzioni come previsto, ma sembra buono. Grazie! – Synesso

+0

Bene, la semantica di skip locked è probabilmente un po 'complicata in questo caso, anche su SQL Server. Mi aspetto che la query sopra trovi prima i primi N messaggi, quindi salta tra loro (in modo che tu possa finire con meno di N record). E non penso che ci sia un modo per aggirare questo in generale (a corto di bloccare l'intero tavolo). – Thilo

Problemi correlati