【问题标题】:"ORA-01001: Invalid cursor" in loop exit condition循环退出条件中的“ORA-01001:无效游标”
【发布时间】:2021-06-22 18:56:15
【问题描述】:

我需要打印部门游标从部门表中获取的那些部门中的雇员姓名(来自雇员表)。

我尝试执行以下代码。

declare
    type tn is ref cursor;
    deptemp_cur tn;
    v_dno DEPARTMENTS.DEPARTMENT_ID%type;
    v_dname departments.department_name%type;
    v_ename employees.first_name%type;
begin
    open deptemp_cur for select DEPARTMENT_ID,department_name from DEPARTMENTS where DEPARTMENT_ID<40;
    loop
        fetch deptemp_cur into v_dno, v_dname;
        open deptemp_cur for select first_name from employees where DEPARTMENT_ID=v_dno;
        loop
            fetch deptemp_cur into v_ename;
            dbms_output.put_line(v_dno||'  '||v_ename);
            exit when deptemp_cur%notfound;
        end loop;
        close deptemp_cur;
        exit when deptemp_cur%notfound; -- line 18
    end loop;
    close deptemp_cur;
end;

但我在第 18 行收到一条错误消息: 错误报告 - ORA-01001: 无效游标 ORA-06512: 在第 18 行 01001. 00000 - “无效光标” *原因:
*行动:

帮我纠正这个问题:P

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    你在做

    exit when deptemp_cur%notfound;
    

    立即之后

    close deptemp_cur;
    

    因此,当您检查 deptemp_cur%notfound 时,游标已关闭,不再有效。

    您正在重复使用相同的游标变量;没关系,除非你在两个层面上这样做,所以他们会互相绊倒。如果你想使用这个结构,那么你可以使用两个变量,比如:

    declare
        type tn is ref cursor;
        deptemp_cur tn;
        emptemp_cur tn;
        v_dno DEPARTMENTS.DEPARTMENT_ID%type;
        v_dname departments.department_name%type;
        v_ename employees.first_name%type;
    begin
        open deptemp_cur for
            select DEPARTMENT_ID,department_name
            from DEPARTMENTS
            where DEPARTMENT_ID<40;
        loop
            fetch deptemp_cur into v_dno, v_dname;
            -- test and exit straight after fetch, unless using bulk collect
            exit when deptemp_cur%notfound;
    
            -- use second cursor for inner loop
            open emptemp_cur for
                select first_name
                from employees
                where DEPARTMENT_ID=v_dno;
            loop
                fetch emptemp_cur into v_ename;
                -- test and exit straight after fetch
                exit when emptemp_cur%notfound;
    
                dbms_output.put_line(v_dno||'  '||v_ename);
            end loop;
            close emptemp_cur;
        end loop;
        close deptemp_cur;
    end;
    

    你可以使用sys_refcursor而不是声明你自己的游标类型:

    declare
        deptemp_cur sys_refcursor;
        emptemp_cur sys_refcursor;
        ...
    

    使用cursor FOR loops 会更简单,如果您加入表格,则可以作为单个游标完成;或者根本没有 PL/SQL。但大概这是对这些特定结构的练习。

    【讨论】:

    • 嗨,非常感谢。我不知道对不同的表使用不同的游标名称。我认为单个游标名称适用于多个表,因为它是一个引用游标。并特别感谢您的其他建议。
    猜你喜欢
    • 2013-06-09
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多