You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 17:12:37