Oracle APEX中基于风险影响状态实现关闭确认对话框的问题排查与功能完善
Oracle APEX中基于风险影响状态实现关闭确认对话框的问题排查与功能完善
我来帮你一步步排查问题并完善这个关闭风险的功能,咱们先从你遇到的两个核心问题入手,再把缺失的评论输入环节补上:
一、解决P2_ID undefined和JSON解析错误的问题
这两个问题本质是参数传递不匹配和JSON输出完整性导致的,咱们逐个修正:
1. 修正Ajax调用的参数传递(解决P2_ID undefined)
你当前JS代码用x01: $v('P2_ID')传递风险ID,但对应的PL/SQL过程却用:P2_ID获取值,这是不匹配的——x01对应的绑定变量是:X01,而非页面项:P2_ID。更稳妥的方式是让APEX自动处理页面项传递,修改JS代码如下:
console.log('P2_ID value:', apex.item('P2_ID').getValue()); // 用apex.item的getValue更稳定 apex.server.process( 'CLOSE_RISK', { pageItems: ['P2_ID'] // 让APEX自动传递P2_ID的会话状态到服务器 }, { dataType: 'json', success: function(data) { console.log('Server response:', data); // 后续逻辑后面再完善 }, error: function(jqXHR, textStatus, errorThrown) { console.error('AJAX错误详情:', jqXHR.responseText, textStatus, errorThrown); // 打印完整响应方便排查 apex.message.showErrors({ type: 'error', location: 'page', message: '请求处理出错: ' + textStatus + ' - ' + errorThrown }); } } );
这里用apex.item('P2_ID').getValue()替代$v('P2_ID'),是因为它在APEX的动态区域、模态框等特殊上下文里更可靠;同时用pageItems: ['P2_ID']让APEX自动管理页面项的会话状态传递,PL/SQL里就能直接用:P2_ID了。
2. 修正PL/SQL代码(确保JSON输出正确)
你的PL/SQL代码结构没问题,但可以优化输出逻辑并强制设置响应类型,避免解析错误:
DECLARE l_has_high_impact VARCHAR2(1); l_message VARCHAR2(4000); BEGIN -- 强制设置响应类型为JSON,避免APEX返回HTML导致解析失败 owa_util.mime_header('application/json', false); owa_util.http_header_close(); apex_json.open_object; BEGIN -- 用EXISTS子查询替代COUNT(*),性能更优(找到匹配项就停止查询) SELECT CASE WHEN EXISTS ( SELECT 1 FROM RMA_USER_EVALUATIONS WHERE ID_RISK = :P2_ID AND (IMPACT_ACTUAL = 'High' OR IMPACT_FORECAST = 'High') ) THEN 'Y' ELSE 'N' END INTO l_has_high_impact FROM DUAL; IF l_has_high_impact = 'Y' THEN l_message := 'Cannot close this risk because it has a High impact value. The countermeasures were not successful.'; apex_json.write('status', 'ERROR'); ELSE l_message := 'Risk can be closed.'; apex_json.write('status', 'SUCCESS'); END IF; apex_json.write('message', l_message); EXCEPTION WHEN OTHERS THEN apex_json.write('status', 'ERROR'); apex_json.write('message', 'An unexpected error occurred: ' || SQLERRM); END; apex_json.close_object; END;
另外要确保你的CLOSE_RISK应用进程设置为按需执行(On Demand),并且关闭调试模式(调试输出会添加额外HTML内容,破坏JSON结构)。
二、完善关闭风险的功能(添加评论输入+批量更新)
你提到用户确认关闭时需要输入评论,并批量更新RMA_USER_EVALUATIONS的COMMENT_WHEN_CLOSED列,咱们把这个功能补上:
1. 修改JS的Success回调逻辑
在用户确认关闭时,弹出输入框获取评论,再调用专门的应用进程执行关闭操作:
success: function(data) { console.log('Server response:', data); if (data.status === 'ERROR') { apex.message.showErrors({ type: 'error', location: 'page', message: data.message }); } else if (data.status === 'SUCCESS') { // 弹出关闭确认对话框 apex.message.confirm("Are you sure you want to close this risk?", function(okPressed) { if (okPressed) { // 弹出评论输入框 apex.prompt( "Please enter a closing comment:", function(pComment) { if (pComment) { // 确保用户输入了评论 // 调用执行关闭的应用进程 apex.server.process( 'FINALIZE_CLOSE_RISK', { pageItems: ['P2_ID'], x01: pComment // 传递评论内容 }, { dataType: 'json', success: function(closeData) { if (closeData.status === 'SUCCESS') { apex.message.showPageSuccess('Risk closed successfully!'); // 刷新风险详情区域更新显示 apex.region('RiskDetailsRegion').refresh(); // 替换为你的实际区域ID } else { apex.message.showErrors({ type: 'error', location: 'page', message: closeData.message }); } }, error: function(jqXHR) { apex.message.showErrors({ type: 'error', location: 'page', message: 'Failed to close risk: ' + jqXHR.responseText }); } } ); } else { apex.message.showErrors({ type: 'warning', location: 'page', message: 'Closing comment is required to proceed.' }); } }, { title: "Closing Comment", value: "" } ); } }); } else { apex.message.showErrors({ type: 'error', location: 'page', message: 'Unexpected response from server.' }); } }
2. 创建FINALIZE_CLOSE_RISK应用进程
这个进程负责执行关闭风险的跨表更新操作:
DECLARE l_risk_id NUMBER := :P2_ID; l_comment VARCHAR2(4000) := :X01; BEGIN owa_util.mime_header('application/json', false); owa_util.http_header_close(); apex_json.open_object; BEGIN -- 1. 更新风险状态为已关闭 UPDATE RMA_RISK_INCIDENTS SET IS_CLOSED = 'Y' WHERE ID = l_risk_id; -- 2. 批量更新所有相关评估的关闭评论 UPDATE RMA_USER_EVALUATIONS SET COMMENT_WHEN_CLOSED = l_comment WHERE ID_RISK = l_risk_id; COMMIT; -- 跨表更新手动提交更稳妥(若应用未开启自动提交) apex_json.write('status', 'SUCCESS'); apex_json.write('message', 'Risk closed successfully.'); EXCEPTION WHEN OTHERS THEN ROLLBACK; apex_json.write('status', 'ERROR'); apex_json.write('message', 'Failed to close risk: ' || SQLERRM); END; apex_json.close_object; END;
三、验证与测试
按以下步骤验证功能:
- 页面加载时用
console.log(apex.item('P2_ID').getValue())确认P2_ID值正确; - 测试高风险场景:点击按钮应直接弹出错误提示;
- 测试低风险场景:弹出确认框→输入评论→提交,检查数据库表的
IS_CLOSED和COMMENT_WHEN_CLOSED列是否更新正确; - 若仍遇JSON解析错误,打开浏览器开发者工具(F12)的Network标签,查看
CLOSE_RISK请求的Response内容,确认是否为纯JSON(若有HTML内容,说明PL/SQL有额外输出或进程设置错误)。
备注:内容来源于stack exchange,提问作者fesm
相关产品推荐
相关产品推荐

