循环退出条件中的“ORA-01001:无效游标”

Posted

技术标签:

【中文标题】循环退出条件中的“ORA-01001:无效游标”【英文标题】:"ORA-01001: Invalid cursor" in loop exit condition 【发布时间】: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

【问题讨论】:

【参考方案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。但大概这是对这些特定结构的练习。

【讨论】:

嗨,非常感谢。我不知道对不同的表使用不同的游标名称。我认为单个游标名称适用于多个表,因为它是一个引用游标。并特别感谢您的其他建议。

以上是关于循环退出条件中的“ORA-01001:无效游标”的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01001 无效游标错误

奇怪的 PL SQL 无效游标

while循

数据结构:单向循环链表

数据结构:单向循环链表

while语句