Oracle APEX 5.1:页面项变更后PL/SQL如何获取新值?
解决Oracle APEX页面项变更后PL/SQL读取旧值的问题
我之前在Oracle APEX里也踩过这个坑!问题出在页面项变更后,新值还没同步到APEX的会话状态(Session State),导致PL/SQL代码读到的还是旧值。下面给你几个实用的解决办法,按需选就行:
方法一:用APEX动态动作的「提交页面项」功能(最省心)
如果你是用APEX内置的动态动作处理变更事件,别忽略这个关键设置:
- 打开你的动态动作,找到「执行PL/SQL代码」的动作步骤
- 在「设置」标签页里,找到「提交页面项」选项,把你要保存的页面项(比如
P1_MY_ITEM)添加进去 - 然后正常写你的PL/SQL保存逻辑,比如:
这样APEX会自动先把页面项的新值同步到会话状态,再执行PL/SQL,自然就能拿到新值了。UPDATE my_table SET target_column = :P1_MY_ITEM WHERE id = :P1_RECORD_ID; COMMIT;
方法二:通过JavaScript直接传递新值给PL/SQL(适合自定义JS场景)
如果是自己写JavaScript处理变更事件,不需要依赖会话状态,直接把新值作为参数传给后台PL/SQL就行:
- 给页面项绑定
change事件的JS代码:apex.item("P1_MY_ITEM").on("change", function() { const newValue = this.getValue(); // 调用APEX AJAX进程传递新值 apex.server.process( "SAVE_ITEM_NEW_VALUE", // 你要创建的AJAX进程名称 { x01: newValue }, // 把新值放到x01参数里 { success: () => console.log("保存成功"), error: () => console.log("保存失败") } ); }); - 在APEX里创建一个AJAX类型的进程(名称就是上面的
SAVE_ITEM_NEW_VALUE),PL/SQL代码如下:
这个方法绕开了会话状态的同步问题,直接传递最新值,适合灵活的自定义场景。DECLARE l_new_val VARCHAR2(200); -- 根据实际数据类型调整 BEGIN l_new_val := apex_application.g_x01; -- 接收JS传递的新值 -- 执行你的保存逻辑 INSERT INTO my_log_table (item_name, new_value) VALUES ('P1_MY_ITEM', l_new_val); COMMIT; END;
方法三:先同步新值到会话状态再执行PL/SQL(适合多步骤操作)
如果你的逻辑需要先把新值存入会话状态,再执行后续的PL/SQL操作,可以分两步走:
- 先创建一个AJAX进程
SYNC_ITEM_TO_SESSION,用来同步值::P1_MY_ITEM := apex_application.g_x01; - 在页面项的
change事件JS里,先调用同步进程,再调用保存进程:apex.item("P1_MY_ITEM").on("change", function() { const newValue = this.getValue(); // 第一步:同步新值到会话状态 apex.server.process( "SYNC_ITEM_TO_SESSION", { x01: newValue }, { success: () => { // 第二步:执行保存逻辑,此时会话里已经是新值了 apex.server.process("EXECUTE_SAVE_LOGIC"); } } ); }); - 最后创建
EXECUTE_SAVE_LOGIC进程,写你的保存代码即可,此时:P1_MY_ITEM就是新值。
内容的提问来源于stack exchange,提问作者zafar shakeel
相关产品推荐
相关产品推荐

