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

Oracle PL/SQL存储过程ORA-01403无数据找到问题求助

解决ORA-01403: no data found的思路

针对你遇到的存储过程中SELECT INTO报错但单独执行查询能返回数据的问题,结合task_number可能存在隐形字符的怀疑,给出以下具体解决步骤:

1. 排查隐形字符的具体类型

先通过DUMP函数查看数据库中TASK_NUMBER的实际字符编码,同时对比传入参数的编码,定位差异:

-- 查询数据库中目标记录的TASK_NUMBER编码
SELECT DUMP(TASK_NUMBER, 1016) AS TASK_HEX_DUMP, TASK_NUMBER
FROM PA_TASKS
WHERE PROJECT_ID = 你的测试项目ID
AND CHARGEABLE_FLAG = 'Y';

-- 在存储过程中添加日志,查看传入参数的编码
DBMS_OUTPUT.PUT_LINE('传入的TASK_NUMBER: ' || P_TASK_NUMBER_IN);
DBMS_OUTPUT.PUT_LINE('传入参数的编码: ' || DUMP(P_TASK_NUMBER_IN, 1016));

通过对比十六进制编码,能明确是换行、制表符、全角空格还是其他非打印字符导致匹配失败。

2. 修正WHERE条件的匹配逻辑

如果确认存在隐形字符,用正则表达式替换所有空白/非打印字符后再匹配,替换SELECT语句的WHERE子句:

-- 方案一:移除所有空白类字符(空格、换行、制表符等)
SELECT TASK_ID INTO L_TASK_ID_OUT
FROM PA_TASKS
WHERE PROJECT_ID = P_PROJ_ID_IN
  AND REGEXP_REPLACE(TASK_NUMBER, '[[:space:]]', '') = REGEXP_REPLACE(P_TASK_NUMBER_IN, '[[:space:]]', '')
  AND CHARGEABLE_FLAG = 'Y';

-- 方案二:移除所有非打印字符,只保留可见字符
SELECT TASK_ID INTO L_TASK_ID_OUT
FROM PA_TASKS
WHERE PROJECT_ID = P_PROJ_ID_IN
  AND REGEXP_REPLACE(TASK_NUMBER, '[^[:print:]]', '') = REGEXP_REPLACE(P_TASK_NUMBER_IN, '[^[:print:]]', '')
  AND CHARGEABLE_FLAG = 'Y';

3. 检查参数传递环节的问题

参数在传递过程中可能被意外添加隐形字符(比如前端复制粘贴、调用方的字符串处理),可以在存储过程开头将参数值写入日志表或打印出来,确认传入的内容是否符合预期:

-- 示例:写入日志表(需提前创建日志表)
INSERT INTO PROC_LOG(PROC_NAME, PARAM_NAME, PARAM_VALUE, CREATE_TIME)
VALUES('GET_TASK_ID', 'P_TASK_NUMBER_IN', P_TASK_NUMBER_IN, SYSDATE);

4. 添加异常处理辅助排查

在存储过程的SELECT块中添加异常捕获,报错时打印数据库中对应项目的所有task_number信息,快速定位匹配失败原因:

BEGIN
    SELECT TASK_ID INTO L_TASK_ID_OUT
    FROM PA_TASKS
    WHERE PROJECT_ID = P_PROJ_ID_IN
      AND TASK_NUMBER = P_TASK_NUMBER_IN
      AND CHARGEABLE_FLAG = 'Y';
    P_TASK_ID_OUT := L_TASK_ID_OUT;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('未找到匹配记录:PROJECT_ID=' || P_PROJ_ID_IN || ',传入的TASK_NUMBER=' || P_TASK_NUMBER_IN);
        DBMS_OUTPUT.PUT_LINE('数据库中该项目的有效任务编号:');
        FOR task_rec IN (SELECT TASK_NUMBER FROM PA_TASKS WHERE PROJECT_ID = P_PROJ_ID_IN AND CHARGEABLE_FLAG='Y') LOOP
            DBMS_OUTPUT.PUT_LINE(task_rec.TASK_NUMBER);
        END LOOP;
        RAISE; -- 根据业务需求选择是否抛出异常或返回默认值
END;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:28:22