2010-10-15 11 views
6

W Oracle, mogę wybrać górną 1 wiadomość w posortowanej tabeli zWybierz góry N z „dla aktualizacji Przejdź zablokowana” w Oracle

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

I jak odkryłem w previous question mogę wybrać wyłącznie wiersz z

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

jednak nie mogę połączyć te dwa pojęcia razem

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. 

Jak mogę wybrać th e top N z blokadą readpast?

+0

Myślę, że ten blog post ma kilka istotnych myśli: http://markjbobak.wordpress.com/2010/04/06/unintended-consequences/ –

Odpowiedz

2

Czy to zadziała?

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

Jeśli to zrobić w dwóch etapach, nie mam pomysł wprowadzenia są potencjalny stan wyścigu? Postępuję zgodnie z twoją logiką, ale trudno mi uwierzyć, że Oracle nie może zrobić tego, co SQL Server może. – Synesso

+0

To zapytanie zostało wykonane poprawnie. Sprawdzę, czy blokada działa zgodnie z przeznaczeniem, ale wydaje się, że dobrze. Dzięki! – Synesso

+0

Cóż, semantyka skip locked jest prawdopodobnie nieco trudna w tym przypadku, nawet na SQL Server. Spodziewam się, że powyższe zapytanie najpierw wykryje najlepsze wiadomości N, a następnie pominie je (tak, abyś mógł otrzymać mniej niż N rekordów). I nie sądzę, że ogólnie jest na to jakiś sposób (brak blokowania całego stołu). – Thilo

Powiązane problemy