2010-10-15 4 views
6

En Oracle, puedo seleccionar el 1 mensaje de arriba en una tabla ordenada conSeleccionar subir N con "para la actualización de salto bloqueado" en Oracle

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

Y como descubrí en un previous question puedo seleccionar una fila exclusiva con

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

sin embargo no puedo combinar estos dos conceptos juntos

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. 

¿Cómo puedo seleccionar XX e la parte superior N con bloqueo de lectura?

+0

creo que esta entrada del blog tiene algunas ideas relevantes: http://markjbobak.wordpress.com/2010/04/06/unintended-consequences/ –

Respuesta

2

¿Funcionará?

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

Si se hace en dos pasos, no lo son la introducción de una condición de raza potencial? Sigo tu lógica, pero me cuesta creer que Oracle no pueda hacer lo que SQL Server puede hacer. – Synesso

+0

Esa consulta ejecutada bien. Continuaré para probar que el bloqueo funciona como estaba previsto, pero parece ir bien. ¡Gracias! – Synesso

+0

Bueno, la semántica de skip locked es probablemente un poco complicado en este caso, incluso en SQL Server. Esperaría que la consulta anterior encuentre primero los N mensajes superiores, y salte entre ellos (para que pueda terminar con menos de N registros). Y no creo que haya una forma de evitarlo en general (salvo cerrar toda la mesa). – Thilo

Cuestiones relacionadas