Oracle APEX交互式网格:保存前如何通过异步服务调用实现行级验证?
Oracle APEX 22 可编辑交互式网格日期范围重叠验证实现方案
核心实现思路
利用APEX页面级PL/SQL验证,在DML执行前拦截提交数据,结合现有has_overlap函数同时检查数据库已有记录和本次提交的新增/修改行,验证失败时通过APEX错误API关联无效行并阻止保存。
1. 创建页面级PL/SQL验证
在页面的「验证」区域新建PL/SQL验证,类型选择「提交时 - 计算」,触发时机设为「提交 - 处理前」,确保在自动DML执行前完成验证。
2. 验证代码实现
以下代码需根据你的交互式网格列对应apex_application.g_fxx数组索引调整(可在网格「列」属性中查看各列的Fxx编号):
DECLARE TYPE t_submit_row IS RECORD ( item_id VARCHAR2(100), start_date DATE, end_date DATE, status VARCHAR2(20), row_num PLS_INTEGER ); TYPE t_submit_rows IS TABLE OF t_submit_row; l_submit_rows t_submit_rows := t_submit_rows(); l_row_num PLS_INTEGER; l_item_id VARCHAR2(100); l_start_date DATE; l_end_date DATE; l_status VARCHAR2(20); l_is_overlap BOOLEAN; BEGIN -- 收集本次提交的所有ACTIVE状态行 FOR i IN 1 .. apex_application.g_f01.count LOOP l_row_num := apex_application.g_f01(i); -- F01对应网格行号列 l_item_id := apex_application.g_f02(i); -- F02对应ITEM_ID列 l_start_date := apex_application.g_f03(i); -- F03对应START_DATE列 l_end_date := apex_application.g_f04(i); -- F04对应END_DATE列 l_status := apex_application.g_f05(i); -- F05对应STATUS列 IF l_status = 'ACTIVE' THEN l_submit_rows.EXTEND; l_submit_rows(l_submit_rows.LAST).item_id := l_item_id; l_submit_rows(l_submit_rows.LAST).start_date := l_start_date; l_submit_rows(l_submit_rows.LAST).end_date := l_end_date; l_submit_rows(l_submit_rows.LAST).row_num := l_row_num; END IF; END LOOP; -- 逐行验证重叠规则 FOR i IN 1 .. l_submit_rows.count LOOP -- 检查与数据库现有ACTIVE行的重叠(若为修改行,需传入主键排除自身,此处需调整has_overlap参数) l_is_overlap := has_overlap( p_item_id => l_submit_rows(i).item_id, p_start_date => l_submit_rows(i).start_date, p_end_date => l_submit_rows(i).end_date, p_exclude_row_id => NULL -- 修改行需替换为当前行主键/ROWID ); -- 检查与本次提交的其他ACTIVE行的重叠 IF NOT l_is_overlap THEN FOR j IN 1 .. l_submit_rows.count LOOP IF i != j AND l_submit_rows(i).item_id = l_submit_rows(j).item_id THEN -- 日期范围重叠判断逻辑:(A.start < B.end) AND (A.end > B.start) IF (l_submit_rows(i).start_date < l_submit_rows(j).end_date) AND (l_submit_rows(i).end_date > l_submit_rows(j).start_date) THEN l_is_overlap := TRUE; EXIT; END IF; END IF; END LOOP; END IF; -- 验证失败时添加错误,关联对应行和列以高亮 IF l_is_overlap THEN apex_error.add_error( p_message => 'ITEM_ID ' || l_submit_rows(i).item_id || ' 的ACTIVE记录日期范围重叠', p_display_location => apex_error.c_inline_in_notification, p_page_item_name => 'IG_YOUR_GRID_STATIC_ID_START_DATE', -- 替换为你的网格静态ID对应的START_DATE列项名 p_row_num => l_submit_rows(i).row_num ); END IF; END LOOP; -- 存在错误时抛出异常,阻止保存操作 IF apex_error.get_error_count > 0 THEN RAISE apex_error.e_stop_processing; END IF; END;
3. 关键注意事项
- 调整
apex_application.g_fxx索引:必须与网格列的实际Fxx编号对应,否则无法正确获取提交数据。 - 修改行排除逻辑:若为修改现有记录,需在
has_overlap函数中添加参数排除当前行(如传入主键),避免误判自身重叠。 - 网格静态ID:确保
p_page_item_name中的静态ID与你的交互式网格静态ID一致,这样APEX才能准确定位并高亮无效行。 - 测试覆盖场景:需验证新增多行重叠、修改行与数据库现有行重叠、修改行与本次提交其他行重叠等情况。
内容的提问来源于stack exchange,提问作者Krushna Rathod
相关产品推荐
相关产品推荐

