Oracle:对于更新选择前10行

我有一个ITEM在列的一个表CREATED_DATE 。 在群集环境,服务的多个副本会选择从这个表中的项目并进行处理。 每个服务应该选择从该项目表中最古老的10个项目。

我能够选择在存储过程中使用这种前10行:

select * from ( select item_id, row_number() over (order by CREATED_DATE) rownumber FROM item ) where rownumber < 11

由于许多服务应该利用这一点,我使用select ... for update更新行“处理”。 但下面的FOR UPDATE语句,失败,错误上面的select语句“ORA-02014:可以FOR UPDATE从视图中使用DISTINCT,GROUP BY等不能选择”

OPEN items_cursor FOR **select Statement** FOR UPDATE;

请帮我一个解决方案。

--------------解决方案-------------

DCookie的回答并不能解决多会话处理(这只是FOR UPDATE语法修复)。 如果你不会操作ROWNUMBER范围,如果要服务的每个实例来选择更新相同的行。 如果你在两会上执行that_for_update_select,第二个是要等到第一个完成交易。 并行处理将是一个错觉。

我会一起审议高效的批量处理for update skip locked的方法。 我的回答如下:

declare
con_limit constant number default 10;
cursor cItems is
select i.item_id, i.created_date
from item i
order by i.created_date
for update skip locked;
type t_cItems is table of cItems%rowtype;
tItems t_cItems;
begin
open cItems;
while true loop
fetch cItems bulk collect into tItems limit con_limit;
-- processing tItems
exit when tItems.count < con_limit;
end loop;
end;

可能长时间的交易可能是一个缺点。 请考虑使用Oracle流高级队列(DBMS_AQ)作为一个替代的解决方案。

这是否工作,为您的情况?

SELECT *
FROM item
WHERE (item_id,created_date) IN
(SELECT item_id,created_date
FROM (SELECT item_id, created_date
, ROW_NUMBER() OVER (ORDER BY created_date) rownumber
FROM item)
WHERE rownumber < 11)

您可以使用skip locked和计数器来实现这一点,只要你不一定需要每个会话获得连续行。 例如:

declare
l_cursor sys_refcursor;
l_name all_objects.object_name%type;
l_found pls_integer := 0;
begin
open l_cursor for
select object_name
from all_objects
order by created
for update skip locked;

loop
fetch l_cursor into l_name;
dbms_output.put_line(l_fetches || ':' || l_name);
if l_cursor%found then
l_found := l_found + 1;
-- dbms_lock.sleep(1);
end if;
exit when l_cursor%notfound or l_found = 10;
end loop;
end;
/

如果从两会上同时运行这一点,他们会得到不同的对象(虽然你可能需要启用呼叫dbms_lock.sleep里面found块,使之缓慢,足以可见)。

根据这个帖子,使用时skip locked所选行没有被锁定,直到他们牵强,并会打开将被忽略光标之后的任何行被另一个会话锁定。

分类:数据库 时间:2015-03-16 人气:8
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.861 (s). 10 q(s)