PL / SQL块问题:找不到数据错误

时间:2009-08-10 17:21:32

标签: sql oracle plsql oracle10g ora-01403

SET SERVEROUTPUT ON
DECLARE
    v_student_id NUMBER := &sv_student_id;
    v_section_id NUMBER := 89;
    v_final_grade NUMBER;
    v_letter_grade CHAR(1);
BEGIN
    SELECT final_grade
    INTO v_final_grade
    FROM enrollment
    WHERE student_id = v_student_id
    AND section_id = v_section_id;

    CASE -- outer CASE
        WHEN v_final_grade IS NULL THEN
            DBMS_OUTPUT.PUT_LINE ('There is no final grade.');
        ELSE
            CASE -- inner CASE
                WHEN v_final_grade >= 90 THEN v_letter_grade := 'A';
                WHEN v_final_grade >= 80 THEN v_letter_grade := 'B';
                WHEN v_final_grade >= 70 THEN v_letter_grade := 'C';
                WHEN v_final_grade >= 60 THEN v_letter_grade := 'D';
                ELSE v_letter_grade := 'F';
            END CASE;

            -- control resumes here after inner CASE terminates
            DBMS_OUTPUT.PUT_LINE ('Letter grade is: '||v_letter_grade);
    END CASE;
    -- control resumes here after outer CASE terminates
END;

我从上面的代码“Oracle PL / SQL by Example,4th Edition 2009”我的问题是当我输入一个student_id表中没有它返回时我有以下错误

Error report: ORA-01403: no data found
ORA-06512: at line 7
01403. 00000 -  "no data found"
*Cause:    
*Action:

但根据该书,它应该返回一个空值,然后按照案例流程。

5 个答案:

答案 0 :(得分:86)

当您选择INTO变量并且没有返回任何记录时,您应该得到NO DATA FOUND错误。我相信编写上面代码的正确方法是用它自己的BEGIN / EXCEPTION / END块包装SELECT语句。例如:

...
v_final_grade NUMBER;
v_letter_grade CHAR(1);
BEGIN

    BEGIN
    SELECT final_grade
      INTO v_final_grade
      FROM enrollment
     WHERE student_id = v_student_id
       AND section_id = v_section_id;

    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        v_final_grade := NULL;
    END;

    CASE -- outer CASE
      WHEN v_final_grade IS NULL THEN
      ...

答案 1 :(得分:2)

可能值得在线查看你的书的勘误部分。

这里有一个处理此例外的例子http://www.dba-oracle.com/sf_ora_01403_no_data_found.htm

答案 2 :(得分:2)

您的SELECT声明未找到您要查找的数据。也就是说,ENROLLMENT表中没有包含STUDENT_IDSECTION_ID的记录。在运行查询之前,您可能需要尝试添加一些DBMS_OUTPUT.PUT_LINE语句,并打印v_student_idv_section_id的值。它们可能不包含您希望它们包含的内容。

答案 3 :(得分:1)

当我无法依赖程序底部的EXCEPTION块时,我会使用另一种方法。我在开头声明了变量:

my_value VARCHAR := 'default';
number_rows NUMBER := 0;
.
.
.
SELECT count(*) FROM TABLE INTO number_rows (etc.)

IF number_rows > 0 -- Then obtain my_value with a query or constant, etc.
END IF;

答案 4 :(得分:0)

由于我们正在使用某种数据类型,因此找不到此数据。

喜欢选择empid到v_test

上面的empid和v_test必须是数字类型,然后才会存储数据。

因此,在收到此错误时,请跟踪数据类型,这可能会有所帮助