【问题标题】:Continually check for an Oracle record at page load在页面加载时持续检查 Oracle 记录
【发布时间】:2013-07-11 16:26:06
【问题描述】:

我基本上有一个页面,在加载时,它会读取 Oracle SQL 表中当前可能不存在的特定记录 id,因为可能需要一分钟才能将这条特定记录插入表中。

基于此,我需要一种在等待记录存在时显示“加载图像”的方法,因此必须等待。完成后,我想删除加载图像并向用户展示记录详细信息。为此,我正在使用 Oracle Application Express 4.2。

我的问题不是图像的加载/隐藏,而是如何在页面加载期间不断检查 Oracle 表中的记录。

我要么成功接收记录,然后隐藏图像,要么在 1 分钟后说,我取消对记录的检查并向用户显示一条消息,指示未找到记录。

【问题讨论】:

  • 如何创建这条记录?它是您启动的程序,还是正在运行的作业或某个过程?
  • 嗨,Tom,它实际上是一个包程序,它从另一个 Oracle APEX 应用程序中启动此作业,然后在后台运行,但是在从此应用程序创建此作业后,用户可以,从这个应用程序中,单击一个链接,然后调用我在上面的原始帖子中描述的过程,即调用另一个 Oracle APEX 应用程序。在页面加载期间,我希望在我的表格中显示加载图像,直到这项工作真正存在。希望这是有道理的。谢谢。

标签: javascript jquery sql ajax oracle-apex


【解决方案1】:

对不起我的英语。我会尽力帮助你的。

  1. 让您的“加载中的图片”始终在页面上可见。加载时无需显示,只需在适当的时候隐藏即可。
  2. 将应用程序进程添加到您的应用程序。例如,将其命名为“GET_MY_ROW”。进程必须检查您的事件,并返回一些标志,例如 1 或 0。

例子:

declare
  l_cnt number;
begin
  select count(*)
   into l_cnt
   from table1 t
   where id = 12345;
  if l_cnt > 0 then
    htp.p(1);
  else
    htp.p(0);
  end if;
end;

3.3 添加 javascript 代码作为页面加载事件(例如通过动态操作):

Javascript 代码:

var myInterval = setInteral(function {
    var get = new htmldb_Get(null,$v('pFlowId'),'APPLICATION_PROCESS=GET_MY_ROW',$v('pFlowStepId'));
    get.GetAsync(function(pRequest) {
        if (pRequest.readyState == 4) {
            if (pRequest.responseText == 1) {
                alert('Record loaded successfully');
                // add function call, hiding your "Loading image" here
                clearInterval(myInterval);
            }
        };
    });
    get = null;
}, 5000); //check every 5 seconds

setTimeout(function() {
    alert('Sorry, no record was found. Try again later.');
    clearInterval(myInterval);
}, 60000); // fail after 1 minute

【讨论】:

    【解决方案2】:

    既然 NoGotnu 已经回答了,我就把它放在这里:

    是否有任何理由通过作业调用该过程?这是创建所需记录的唯一方法吗?工作在其他地方被调用吗?为什么不在提交所需页面并在此处显示加载图标时直接调用该过程?当它完成时,用户知道它已经完成。这将涉及更少的摆弄,因为您可以让 apex 在页面提交时显示处理图形。然后,您可以在另一个页面上通知用户该进程尚未运行,他们必须先执行此操作。

    其次,虽然 NoGotnu 的答案会起作用,但我想指出,在 apex 4.2 中,您应该使用 apex.server namespace 而不是从未记录过的 htmldb_Get 构造。 apex.server.process 是 jQuery ajax 设置的干净实现。 NoGotnu 的代码翻译:

    apex.server.process( "GET_MY_ROW"
                        , null
                        , {  dataType: text
                           , success: function(pData){
                              if (pData == 1) {
                                 clearInterval(myInterval);
                                 alert('Record loaded successfully');
                              };
                             }
                          }
                       );
    

    虽然调用并不真正需要异步,但没关系。

    另一种选择是实现“长轮询”,而不是每 5 秒触发一次 ajax 事件。长轮询只会启动对服务器的调用并等待响应。只要服务器忙,客户端就会等待。要实现这一点,您可以使用 dbms_alert,如 Waiting for a submitted job to finish in Oracle PL/SQL?
    中所建议的那样 您将在作业的 plsql 代码中发出警报,并在按需流程代码中注册对警报的兴趣,并使用 waitone/any 和 60 秒超时。 Presto 长轮询。

    【讨论】:

    • 你好,汤姆!感谢您的回答。我知道 apex.server.process,但我试图举一个通用方法的例子,即使在 APEX 3.x 上也能工作。关于长民意调查-我认为在这个简单的任务中,长民意调查将过多(或多余?-我的英语不好)。但无论如何你是对的;)
    • @NoGotnu 如果人们在 4.2 上但坚持使用 htmldb_Get 他们应该诚实地受到惩罚 ;) 我知道它很有用,但仍然认为 jQuery 实现要好得多,即使它需要几行额外的代码。对我来说,它更加透明,我喜欢 apex 对其进行扩展并为我们提供更标准化的控制。至于长民意调查:是的,这可能有点矫枉过正。尽管如此,使用 dbms_alert 实现它应该不难,并且消除了必须在 javascript 中完成的一些乏味。但是,嘿,两种方式都有效并且有选择是一件好事!
    • @Tom 看看你的“长拉”建议,我真的很感激一个例子,因为我实际上已经在 SO 中提出了另一个线程。请看“stackoverflow.com/questions/42825441/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 2017-05-13
    • 2014-01-28
    • 2011-03-14
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多