简体   繁体   English

Oracle SQL:将 SELECT FOR UPDATE SKIP LOCKED 与排序和行数限制相结合的查询的可能性

[英]Oracle SQL: possibility of a query that combines SELECT FOR UPDATE SKIP LOCKED with ordering and rownum limit

From what I understand, the answer, broadly speaking is "no", but here's the problem:据我了解,从广义上讲,答案是“不”,但问题在于:

I need to run a query that needs to do the following things:我需要运行一个需要做以下事情的查询:

  1. Select rows in a table, sorted by a column选择表中的行,按列排序
  2. Of these rows, pick and lock the first one, skipping other locked rows.在这些行中,选择并锁定第一行,跳过其他锁定的行。

An example query would look something like this:示例查询如下所示:

SELECT
    E.*
FROM
   polled_table E
WHERE 
    E.ID IN 
    (SELECT ID FROM
        (SELECT 
            ID
         FROM
            polled_table
         WHERE 
            condition = 'value'
         ORDER BY priority DESC)
     WHERE rownum < 2)
FOR UPDATE SKIP LOCKED;

This of course doesn't work in the sense that the skip locked essentially doesn't work as that part of the query only ever sees one row.这当然不起作用,因为锁定的跳过基本上不起作用,因为查询的那部分只看到一行。

Bringing the "rownum < 2" outside doesn't seem to be possible (it triggers errors described for example here: ORA-00907 Missing right parenthesis issue - select with order by inside insert query )将“rownum < 2”带到外面似乎是不可能的(它会触发这里描述的错误: ORA-00907 Missing right parenthesis issue - select with order by inside insert query

I've tried several combinations, but they either don't do what I want or they straight up generate errors.我尝试了几种组合,但它们要么不符合我的要求,要么直接产生错误。 The only thing that might work would be removing the rownum condition, but that would lock a large number of rows.唯一可行的方法是删除 rownum 条件,但这会锁定大量行。

At this point, as I mentioned, I'm thinking it just be done, not as a single query at least.在这一点上,正如我所提到的,我认为它只是完成了,至少不是作为一个单一的查询。

If you push the query into a cursor, then just fetch the first row.如果将查询推送到游标中,则只需获取第一行。 That should accomplish this task with the skip locked intact.这应该在跳过锁定完整的情况下完成此任务。

Something like (I'm away from my DB so pardon any minor syntax errors):类似的东西(我远离我的数据库,所以请原谅任何小的语法错误):

Cursor C is SELECT
    E.*
FROM
   polled_table E
WHERE
    E.ID IN
    (SELECT ID FROM
        (SELECT
            ID
         FROM
            polled_table
         WHERE
            condition = 'value'
         ORDER BY priority DESC))  for update skip locked;

var c%rowtype;

Open C
Fetch C into var;
close C;

Then process that first row fetched in the VAR variable.然后处理在 VAR 变量中提取的第一行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM