database - oracle:更新选择前 10 行

标签 database oracle stored-procedures oracle10g

我有一个 ITEM 表,其中一列为 CREATED_DATE。在集群环境中,许多服务副本将从该表中挑选项目并进行处理。每个服务应该从 ITEM 表中选择最旧的 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:无法从具有 DISTINCT、GROUP BY 等的 View 中选择 FOR UPDATE。”

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

请帮我解决。

最佳答案

DCookie 的回答没有解决多 session 处理(它只是为了更新语法修复)。如果您不操作行号范围,则每个服务实例都会选择更新相同的行。如果您在两个 session 中执行 that_for_update_select,第二个 session 将等到第一个完成事务。并行处理将是一种错觉。

我会考虑将高效的批量处理与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 Streams Advanced Queuing (DBMS_AQ) 作为此解决方案的替代方案。

关于database - oracle:更新选择前 10 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337126/

相关文章:

mysql - 有关 MySQL 合并和存储过程的帮助

asp.net-mvc - 如何在具有不同 PK 和 FK 的 Fluent API 中配置一对零和一对一关系

database - 从旧硬盘传输 postgres 数据库

sql - Oracle - 如何在分层查询中使用连接并避免笛卡尔积

mysql - SQL Server 到 MySQL - 但如何使用存储过程呢?

MySQL - 你的 SQL 语法有错误;检查与您的 MariaDB 服务器版本对应的手册以了解正确的语法 - phpMyAdmin

android - 我如何为 Android 应用程序硬编码 SQLite 数据库

c# - 在 SQL Server 中批量插入特定列

c# - 为什么 DataRow 在方法的一部分中被识别而不是在另一部分中(我如何动态添加 DataRows)?

java - 如何在 Java 中检索预期时区中的 oracle Timestamp 列?