为什么这个错误ora 01403在第27行找不到数据?

时间:2014-02-07 14:32:38

标签: oracle

SET SERVEROUTPUT ON SIZE 1000000

DECLARE
  MIN_ID employees.EMPLOYEE_ID%TYPE;
  MAX_ID employees.EMPLOYEE_ID%TYPE;
  J_NAME employees.JOB_ID%TYPE;
  USER_CAT employees.EMPLOYEE_ID%TYPE;

BEGIN

           SELECT MAX(EMPLOYEE_ID) , MIN(EMPLOYEE_ID)
           INTO     MAX_ID ,  MIN_ID
           FROM  employees;         


           FOR I IN MIN_ID..MAX_ID LOOP

           IF I = 1 THEN
             SELECT SUBSTR(JOB_ID , INSTR(JOB_ID , '_') , LENGTH(JOB_ID) )
             INTO J_NAME
             FROM EMPLOYEES
             WHERE EMPLOYEE_ID = I ; 

             INSERT INTO TASK_TABLE
              VALUES ( I , J_NAME);

           ELSE

             SELECT CASE USER_CATEGORY WHEN J_NAME THEN '1'
                                                           ELSE '0' 
                                                           END AS USER_CAT
              INTO    USER_CAT
              FROM TASK_TABLE ;
             /* WHERE USER_CATEGORY LIKE J_NAME ; */

             IF USER_CAT = '0'  THEN 
                 INSERT INTO TASK_TABLE
                 VALUES ( I , J_NAME);

             ELSE

                CONTINUE;   

             END IF;

         END IF;
             DBMS_OUTPUT.PUT_LINE(J_NAME);

    END LOOP;
END;

3 个答案:

答案 0 :(得分:3)

当您尝试使用no_data_found语法填充变量时会发生

select..into异常,但查询中没有返回任何行。

确保在使用select..into时查询只返回一行,并正确处理异常。如果您的查询返回多行,您还应该处理too_many_rows

declare
  ln_dummy number;
begin
  select 1 into ln_dummy
  from dual
  where
    1=2;
exception
  when no_data_found then
    --Handle
  when too_many_rows then
    --Handle
  when others then
    raise;
end;

答案 1 :(得分:2)

此错误是由SELECT / INTO子句返回没有行引起的。 为了防止这种情况,最佳做法是在此游标上使用游标和循环。通过这种方式,ORA-01403错误永远不会出现。

以下是使用您的表格的一个小例子:

DECLARE
  CURSOR cEMPLOYEES IS
    SELECT * FROM  employees;
  vEMPLOYEES cEMPLOYEES%rowtype;

BEGIN
  OPEN cEMPLOYEES;
  LOOP 
    FETCH cEMPLOYEES INTO vEMPLOYEES;
    EXIT WHEN cEMPLOYEES%notfound;
    IF cEMPLOYEES%found THEN
      -- Here you can make your stuff, accessing columns values like cEMPLOYEES.EMPLOYEE_ID or cEMPLOYEES.JOB_ID
      INSERT INTO TASK_TABLE
          VALUES ( cEMPLOYEES.EMPLOYEE_ID , SUBSTR(cEMPLOYEES.JOB_ID , INSTR(cEMPLOYEES.JOB_ID , '_') , LENGTH(cEMPLOYEES.JOB_ID) ));
    END IF;
  END LOOP;
  CLOSE cEMPLOYEES;
END;

答案 2 :(得分:0)

这几乎肯定是SELECT INTO...中的一个,例如您在EMPLOYEES表中没有EMPLOYEE_ID = 1的记录,或者在代码到达时TASK_TABLE中没有任何记录。

您应该使用when NO_DATA_FOUND exception handler来处理这种情况,并且可能同时处理when TOO_MANY_ROWS

但是,如果您认为SELECT INTO完全可以接受零行或多行,那么您可以使用第一个SELECT INTO中的聚合,即

SELECT MAX(EMPLOYEE_ID) , MIN(EMPLOYEE_ID)
       INTO     MAX_ID ,  MIN_ID
       FROM  employees;