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

Oracle APEX Ajax回调PL/SQL异常:误删全表数据排查

问题原因及解决方案

这不是Oracle APEX的Bug,核心问题是PL/SQL变量名与表列名重名导致的标识符解析错误。

原因分析

Oracle在解析PL/SQL块中的嵌入式SQL时,会优先将同名标识符解析为PL/SQL局部变量,而非表的列名。你的DELETE语句中:

DELETE FROM CHLI_IMAGES WHERE (INSPECTION_ID = inspection_id AND INNER_ID = inner_id);

这里的INSPECTION_ID和inner_id会被Oracle识别为你声明的PL/SQL变量,导致条件变成「变量=变量」(永远为真),最终等价于执行DELETE FROM CHLI_IMAGES;,所以删除了表中所有行。

而静态SQL能正常工作,是因为静态SQL中没有同名变量,Oracle直接将标识符解析为表列,条件逻辑正确。

解决方案

有两种简单的修复方式:

1. 修改PL/SQL变量名,避免与列名冲突

遵循PL/SQL编码规范,给局部变量添加前缀(比如l_表示local),区分表列:

DECLARE
    l_inspection_id number;
    l_inner_id number;
BEGIN
    l_inspection_id := apex_application.g_x01;
    l_inner_id := apex_application.g_x02;

    apex_debug.info('=====================================');
    apex_debug.info('DELETE ENTRY WITH INSPECTION_ID: '||l_inspection_id||' AND INNER_ID: '||l_inner_id);
    DELETE FROM CHLI_IMAGES WHERE (INSPECTION_ID = l_inspection_id AND INNER_ID = l_inner_id);
    apex_debug.info('ROWS DELETED '|| SQL%ROWCOUNT);

    apex_json.open_object;
    apex_json.write('success', true);
    apex_json.write('message', '删除完成');
    apex_json.write('INSPECTION_ID', l_inspection_id);
    apex_json.write('INNER_ID', l_inner_id);
    apex_json.write('result', true);
    apex_json.close_object;
EXCEPTION
    WHEN OTHERS THEN
        apex_json.open_object;
        apex_json.write('success', false);
        apex_json.write('message', sqlerrm);
        apex_json.close_object;
END;

2. 在SQL中使用表别名明确引用列

通过表别名指定列归属,避免标识符混淆:

DECLARE
    inspection_id number;
    inner_id number;
BEGIN
    inspection_id := apex_application.g_x01;
    inner_id := apex_application.g_x02;

    apex_debug.info('=====================================');
    apex_debug.info('DELETE ENTRY WITH INSPECTION_ID: '||inspection_id||' AND INNER_ID: '||inner_id);
    -- 添加表别名img,用img.INSPECTION_ID明确指定表列
    DELETE FROM CHLI_IMAGES img 
    WHERE (img.INSPECTION_ID = inspection_id AND img.INNER_ID = inner_id);
    apex_debug.info('ROWS DELETED '|| SQL%ROWCOUNT);

    apex_json.open_object;
    apex_json.write('success', true);
    apex_json.write('message', '删除完成');
    apex_json.write('INSPECTION_ID', inspection_id);
    apex_json.write('INNER_ID', inner_id);
    apex_json.write('result', true);
    apex_json.close_object;
EXCEPTION
    WHEN OTHERS THEN
        apex_json.open_object;
        apex_json.write('success', false);
        apex_json.write('message', sqlerrm);
        apex_json.close_object;
END;

内容的提问来源于stack exchange,提问作者Filip Degenhart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:50:25