如何等待查询返回行?

时间:2014-10-29 17:11:30

标签: oracle

在Oracle DB上,如何执行以下逻辑(即"等待至少返回一行并从其返回一个列值"),但没有轮询(循环,浪费CPU和可能I / O)但有一些等待/阻止机制? 因此,当调用 get_one()函数时,它不应该返回,直到它可以从匹配某些条件的表中获取一行。

function get_one()
return number
is
c1 sys_refcursor;
n number;
begin
    loop
        open c1 for select number_column from t1 where some_conditions;
        fetch c1 into n;
        if not c1%notfound then return n;
        close c1;
        dbms_lock.sleep(1); -- this wait reduces load, but is still polling, also it delays reaction time
    end loop;
end;

该解决方案应该适用于外部应用程序(例如使用J2EE,.NET等的应用程序服务器),因此使用触发器可能不适合。

3 个答案:

答案 0 :(得分:1)

有两个可以满足这些要求的oracle db功能:

答案 1 :(得分:0)

function get_one()
return number
is
n number;
begin
    loop
        select (select number_column from t1 where some_conditions) into n from dual;
        if n is null then
          dbms_lock.sleep(1); -- wait 1 second
        else 
          return n;
        end if;   
    end loop;
end;
  

DBMS_LOCK 包提供了Oracle Lock Management的界面   服务。您可以请求锁定特定模式,给它一个唯一的模式   在同一个或另一个的另一个程序中可识别的名称   例如,更改锁定模式,然后释放它。

您可能需要一些资助才能执行此Oracle软件包

答案 2 :(得分:0)

我不赞成实现在Oracle上直接等待或轮询的代码。这可能会扭曲Oracle统计数据,如数据库时间和等待时间。

为了实现需要对正在创建或修改的某组行进行操作的服务器代码,您可以诉诸:

  1. 以预定间隔唤醒并查询行的计划作业。如果存在行,则调用作用于新行的过程。

  2. 触发器 根据插入的内容,您可以创建一个在创建行时调用的触发器。如果您尝试修改具有触发器的原始行,请注意可能出现的突变对象错误。

  3. 如果是调用“get_one”的客户端应用程序,您可能还要让客户端应用程序每隔几秒钟根据一个计时器轮询它(在两次调用之间没有浪费客户端或DB CPU)。