ORACLE APEX PL/SQL 在 onbeforepageunload 期间使用 AJAX 调用时进程没有响应

ORACLE APEX PL/SQL Process not responding when called with AJAX during onbeforepageunload

我正在使用 Oracle APEX 4.2。我构建了一个设置为执行 "On Demand - When this process is called by AJAX" 的 PLSQL 进程。此过程旨在更新我在加载页面时创建的集合中的两个成员属性。其代码如下:

DECLARE
v_seq_id NUMBER;
BEGIN

--get sequence id
SELECT seq_id into v_seq_id FROM apex_collections 
WHERE collection_name = 'THE_COLLECTION' and c001 = :APP_SESSION;

--I've tried uncommenting this script to see if this works, too
--htp.script('alert(''PLSQL Process works'');');

--update first member attribute    
apex_collection.update_member_attribute(
p_collection_name =>'THE_COLLECTION',
p_seq => v_seq_id,
p_attr_number => 2, 
p_attr_value => 0);


--update second member attribute
apex_collection.update_member_attribute(
p_collection_name =>'THE_COLLECTION',
p_seq => v_seq_id,
p_attr_number => 3, 
p_attr_value => sysdate);

END;

当我尝试在页面卸载前使用 AJAX/javascript 调用此进程时,没有任何反应。我将此代码放在页面的 "Execute on Page Load" 部分:

window.onbeforeunload = function(){
//this alert box works, so I know the function is called
alert('Unloading...');
//call the PLSQL process 
 var get = new htmldb_Get(null,$v('pFlowId'), 'APPLICATION_PROCESS=THE_PROCESS',1234);         
get.get();
//this also works, so I know the function completes
 alert('end');
};

我用两种方式测试。首先,我在我的页面中内置了一些逻辑,这些逻辑取决于这些成员属性是否已更新。当我重新加载页面时,它的行为就好像 PLSQL 进程从不 运行。其次,我尝试取消注释上面 PLSQL 代码中的 htp.script 行,但它也不会执行。

当我在浏览器的 F12 工具中尝试 运行 执行以下操作时,控制台打印 "alert('test');" 而实际上没有显示错误消息:

var get = new htmldb_Get(null,$v('pFlowId'), 'APPLICATION_PROCESS=THE_PROCESS',1234);         
get.get();

我也试过 运行 将其与 window.onload 结合使用,但这似乎也不起作用。

当我 运行 PLSQL 进程作为 "After Header" 进程时,htp.script 代码成功启动了一个警告框,并且该进程似乎正常工作。

有谁知道如何让它与 AJAX 一起工作?我是否遗漏了一些明显的东西?

看起来问题毕竟出在 PLSQL 进程中。根据 Tom 评论的建议,我在浏览器开发工具的网络选项卡中查看了 wwv_flow.show。当我查看 "detailed view" 下的 "Response body" 选项卡时,我发现进程正在返回 htp.script 命令的结果;它只是没有生成警告框本身。

经过一些故障排除后,我发现我的 PLSQL 进程中的以下代码不起作用:

--update first member attribute    
apex_collection.update_member_attribute(
p_collection_name =>'THE_COLLECTION',
p_seq => v_seq_id,
p_attr_number => 2, 
p_attr_value => 0);

我改成:

UPDATE apex_collections SET n001 = 0 WHERE c001 = :APP_SESSION and collection_name = 'THE_COLLECTION';

为了完成这项工作,我必须执行一个命令来向我的数据库用户授予更新权限:

GRANT UPDATE ON apex_collections TO USER