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

Oracle APEX 5.1.3中Interactive Grid的Apex_application.G_FNN.COUNT返回0问题

解决方案:老版本APEX中验证可编辑Interactive Grid(含新增行)的列值

针对你遇到的老版本APEX无法通过APEX_APPLICATION.G_FNN获取IG提交数据、无提交前流程的问题,提供以下3种可行的当前版本解决方案:

方案1:利用IG内置验证(最简方案)

前端基础验证

直接在IG的列属性中配置前端验证规则:

  • 进入IG列的编辑界面,找到「验证」分组,设置必填、格式正则、数值范围等规则。
  • 该验证会在用户输入、行保存时自动触发,覆盖现有行和新增行,无需额外代码。

后端复杂验证(通过行处理)

如果需要关联数据库的复杂校验,放弃G_FNN,直接在IG的行处理中编写逻辑:

  1. 进入IG的「处理」属性,找到对应保存操作的行处理(如“保存交互式网格数据”)。
  2. 在「处理代码」中使用:NEW.aaa、:NEW.bbb这类绑定变量直接访问当前行的列值(新增/现有行均适用),验证不通过时抛出APEX_ERROR异常:
IF :NEW.aaa IS NULL OR :NEW.bbb <= 0 THEN
    APEX_ERROR.RAISE_ERROR(
        p_message => 'aaa不能为空,且bbb必须大于0',
        p_display_location => APEX_ERROR.C_INLINE_IN_NOTIFICATION
    );
END IF;

错误会直接显示在IG的行内通知中,符合APEX原生交互逻辑。

方案2:自定义AJAX提交+前端数据收集(复杂批量校验)

放弃IG自带保存按钮,手动收集数据并做前置验证:

  1. 隐藏自带保存按钮:在IG工具栏属性中取消勾选「保存」按钮的显示。
  2. 添加自定义按钮与动态动作:
    • 创建页面按钮,点击触发动态动作,执行JS代码收集所有行数据(含新增行):
var ig = apex.region("YOUR_IG_STATIC_ID").widget().interactiveGrid("getViews", "grid");
var allRows = ig.model.getRecords();
var dataToSubmit = [];

allRows.forEach(function(row){
    var rowData = ig.model.getRecordValues(row);
    dataToSubmit.push({
        aaa: rowData.aaa,
        bbb: rowData.bbb,
        ccc: rowData.ccc,
        ddd: rowData.ddd,
        eee: rowData.eee,
        fff: rowData.fff,
        ggg: rowData.ggg,
        row_status: rowData[ig.model.STATUS_COLUMN] // 获取行状态:新增/修改/删除
    });
});

// 提交到AJAX回调
apex.server.process("VALIDATE_IG_DATA", {
    x01: JSON.stringify(dataToSubmit)
}, {
    success: function(res){
        if(res.is_valid){
            ig.save(); // 验证通过后触发IG原生保存
        } else {
            apex.message.showErrors(res.errors); // 显示错误
        }
    }
});
  1. 创建AJAX回调流程:在页面「AJAX回调」中新增名为VALIDATE_IG_DATA的流程,编写PL/SQL验证逻辑:
DECLARE
    l_data JSON;
    l_row JSON;
    l_errors apex_t_error;
BEGIN
    l_data := JSON.parse(apex_application.g_x01);
    FOR i IN 1..l_data.get_size LOOP
        l_row := l_data.get(i);
        -- 自定义验证逻辑
        IF l_row.get_string('aaa') IS NULL THEN
            apex_error.add_error(
                p_message => '第'||i||'行:aaa不能为空',
                p_error_type => apex_error.c_error_type_error,
                p_display_location => apex_error.c_inline_in_notification
            );
        END IF;
        -- 其他列验证规则...
    END LOOP;

    -- 返回验证结果
    apex_json.open_object;
    apex_json.write('is_valid', apex_error.get_first_error IS NULL);
    apex_json.write('errors', apex_error.get_errors);
    apex_json.close_object;
EXCEPTION
    WHEN OTHERS THEN
        apex_json.open_object;
        apex_json.write('is_valid', FALSE);
        apex_json.write('errors', apex_t_error(apex_error.create_error(p_message => SQLERRM)));
        apex_json.close_object;
END;

方案3:隐藏页面项传递IG数据(页面提交场景)

如果需要通过页面提交而非AJAX处理,可通过隐藏项中转数据:

  1. 添加隐藏页面项:创建类型为「隐藏」的页面项(如PXX_IG_DATA)。
  2. 动态动作收集数据:在自定义提交按钮的点击事件中,先执行JS将IG数据转成JSON赋值给隐藏项:
var ig = apex.region("YOUR_IG_STATIC_ID").widget().interactiveGrid("getViews", "grid");
var allRows = ig.model.getRecords();
var dataToSubmit = [];

allRows.forEach(function(row){
    dataToSubmit.push(ig.model.getRecordValues(row));
});

apex.item("PXX_IG_DATA").setValue(JSON.stringify(dataToSubmit));
  1. 提交后处理验证:在页面「提交后流程」中解析隐藏项的JSON数据,执行验证:
DECLARE
    l_data JSON;
    l_row JSON;
BEGIN
    l_data := JSON.parse(:PXX_IG_DATA);
    FOR i IN 1..l_data.get_size LOOP
        l_row := l_data.get(i);
        IF l_row.get_string('aaa') IS NULL THEN
            RAISE_APPLICATION_ERROR(-20001, '第'||i||'行:aaa不能为空');
        END IF;
        -- 其他验证规则...
    END LOOP;
    -- 验证通过后可手动处理数据,或触发IG保存逻辑
END;

关键说明

老版本APEX中,IG的AJAX提交不会将数据放入APEX_APPLICATION.G_FNN数组,因此直接访问该变量必然为空,以上方案均绕开了这个限制,适配现有版本的IG交互逻辑。

内容的提问来源于stack exchange,提问作者No Body

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:18:14