Oracle APEX交互式网格无法保存JS计算的PERF_ID数据问题
问题:Oracle APEX交互式网格通过JS设置的PERF_ID无法保存
我有一个基于以下SQL查询的Oracle APEX交互式网格:
select id_no , TESTID , UNITID , result , MEAN , SD , ROUND(((result - mean) / sd),2) AS SDI , LOW_LIMIT , HIGH_LIMIT , PERF_ID , VALIDATED FROM HAJJ_QC_RESULTS where sample_id = :P13_SAMPLE AND hospital_no = :P13_HOSPITAL AND approved_date = :P13_FROMDATE
我创建了一个带动态动作的按钮,点击按钮时通过以下JavaScript代码计算并设置PERF_ID列的值,点击按钮时网格能正常显示计算后的数据:
var widget = apex.region('validate').widget() , grid = widget.interactiveGrid('getViews','grid') , model = grid.model , v_amount = 0 ; model.forEach(function (r) { v_amount = 0; model.setValue(r,'VALIDATED',2) if ( model.getValue( r , "SDI") >= 0 && model.getValue( r , "SDI") <= 1 ) { v_amount += 1 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") <= 0 && model.getValue( r , "SDI") >= -1 ) { v_amount += 1 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") >= 1.01 && model.getValue( r , "SDI") <= 1.5 ) { v_amount += 2 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") <= -1.01 && model.getValue( r , "SDI") >= -1.5 ) { v_amount += 2 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") >= 1.6 && model.getValue( r , "SDI") <= 2 ) { v_amount += 3 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") <= -1.6 && model.getValue( r , "SDI") >= -2 ) { v_amount += 3 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") > 2 ) { v_amount += 4 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } else if ( model.getValue( r , "SDI") < -2 ) { v_amount += 4 model.setValue(r,'PERF_ID',v_amount) // $s("PERF_ID",v_amount) } v_amount = 0; })
问题:点击保存按钮时,PERF_ID列通过JS设置的数据无法被保存,但手动逐行输入PERF_ID数据后可以正常保存。已检查DML流程,仅存在一个可编辑区域,请问无法保存的原因是什么?
原因及解决方案
核心原因:Oracle APEX交互式网格的模型(
model)在通过setValue修改数据后,需要标记该行数据为已修改(脏数据),否则DML流程不会识别这些变更并提交到数据库。手动输入时APEX会自动触发行状态标记,但JS直接调用setValue不会自动完成这个操作。解决方案:在设置完字段值后,调用
model.markDirty(r)将该行标记为脏数据,确保APEX在保存时能捕获到这些变更。修改后的JS代码如下:
var widget = apex.region('validate').widget() , grid = widget.interactiveGrid('getViews','grid') , model = grid.model , v_amount = 0 ; model.forEach(function (r) { v_amount = 0; model.setValue(r,'VALIDATED',2) if ( model.getValue( r , "SDI") >= 0 && model.getValue( r , "SDI") <= 1 ) { v_amount += 1 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") <= 0 && model.getValue( r , "SDI") >= -1 ) { v_amount += 1 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") >= 1.01 && model.getValue( r , "SDI") <= 1.5 ) { v_amount += 2 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") <= -1.01 && model.getValue( r , "SDI") >= -1.5 ) { v_amount += 2 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") >= 1.6 && model.getValue( r , "SDI") <= 2 ) { v_amount += 3 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") <= -1.6 && model.getValue( r , "SDI") >= -2 ) { v_amount += 3 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") > 2 ) { v_amount += 4 model.setValue(r,'PERF_ID',v_amount) } else if ( model.getValue( r , "SDI") < -2 ) { v_amount += 4 model.setValue(r,'PERF_ID',v_amount) } // 标记当前行已修改,确保保存时能被DML流程识别 model.markDirty(r) v_amount = 0; })
额外排查点:
- 确认
PERF_ID列在交互式网格的列属性中设置为可编辑(手动输入能保存则此点大概率没问题)。 - 确保
id_no是表的主键,APEX需要主键来定位要更新的行(你的SQL已包含id_no,应已配置为主键列)。
内容的提问来源于stack exchange,提问作者Ziad Adnan
相关产品推荐
相关产品推荐

