Oracle 我想使用ref游标检索行。但是得到下面的错误

Oracle 我想使用ref游标检索行。但是得到下面的错误,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,PLS-00382:表达式类型错误 我知道有些东西与for循环有关,但我无法标记它 以下是我的疑问: set serveroutput on; cl scr(); DECLARE type type_cursor_emp is ref cursor return emp%ROWTYPE; v_emp_cur1 type_cursor_emp; v_emp emp%ROWTYPE; BEGIN open v_emp_cur1 for se

PLS-00382:表达式类型错误

我知道有些东西与for循环有关,但我无法标记它

以下是我的疑问:

set serveroutput on;
cl scr();

DECLARE
    type type_cursor_emp is 
      ref cursor return emp%ROWTYPE;
    v_emp_cur1 type_cursor_emp;
    v_emp emp%ROWTYPE;

BEGIN
    open v_emp_cur1 for 
    select emp_id,emp_name from emp;

    Loop
        fetch v_emp_cur1 into v_emp;
        exit when v_emp_cur1%notfound;
        dbms_output.put_line('Emp_id = '||v_emp.emp_id ||',emp_name = '||v_emp.emp_name);

    end loop;

    close v_emp_cur1;
end;

/

OPEN cursor FOR需要一个字符串,并且您的ref cursor是强类型的,因此您必须返回完整的
emp
记录,例如:

open v_emp_cur1 for
'select * from emp';

但是,在您的情况下,不清楚为什么需要使用动态SQL。您可以更简单地使用静态查询来完成此操作,无需使用ref游标:

BEGIN
  FOR v_emp IN (
    select emp_id,emp_name from emp
    ) LOOP
    dbms_output.put_line('Emp_id = '||v_emp.emp_id ||',emp_name = '||v_emp.emp_name);
  END LOOP;
END;

按照您的操作方式,它可以简化为一个简单的循环游标

SQL> BEGIN
  2    FOR i IN
  3    ( SELECT empno,ename FROM emp
  4    )
  5    LOOP
  6      dbms_output.put_line('Emp_id = '||i.empno ||',emp_name = '||i.ename);
  7    END LOOP;
  8  END;
  9  /
Emp_id = 7369,emp_name = SMITH
Emp_id = 7499,emp_name = ALLEN
Emp_id = 7521,emp_name = WARD
Emp_id = 7566,emp_name = JONES
Emp_id = 7654,emp_name = MARTIN
Emp_id = 7698,emp_name = BLAKE
Emp_id = 7782,emp_name = CLARK
Emp_id = 7788,emp_name = SCOTT
Emp_id = 7839,emp_name = KING
Emp_id = 7844,emp_name = TURNER
Emp_id = 7876,emp_name = ADAMS
Emp_id = 7900,emp_name = JAMES
Emp_id = 7902,emp_name = FORD
Emp_id = 7934,emp_name = MILLER

PL/SQL procedure successfully completed.

SQL>
SQL*Plus
中,您可以使用refcursor变量轻松完成此操作

SQL> var r refcursor
SQL>
SQL> BEGIN
  2    OPEN :r FOR SELECT empno,ename FROM emp;
  3  END;
  4  /

PL/SQL procedure successfully completed.

SQL> print r

     EMPNO ENAME
---------- ----------
      7369 SMITH
      7499 ALLEN
      7521 WARD
      7566 JONES
      7654 MARTIN
      7698 BLAKE
      7782 CLARK
      7788 SCOTT
      7839 KING
      7844 TURNER
      7876 ADAMS

     EMPNO ENAME
---------- ----------
      7900 JAMES
      7902 FORD
      7934 MILLER

14 rows selected.

SQL>

我想您应该使用
select*from emp
,尽管您已经使用了
ROWTYPE
嘿,David,我试过使用select*from emp,但效果不错。但即使在循环中写入dbms_output.put_行,也无法看到结果。输出结果就像匿名块完成一样。我想了解为什么它不使用列名称,如emp_id、emp_名称,并且只使用emp中的select*。请帮助我理解并感谢Jeffrey Kemp的回答。实际上,我正在尝试使用openfor语句和ref cursor编写代码,因为我现在正在学习编码。所以我只是想知道如何使用ref cursori如果您只是在学习编码,我不会从动态SQL开始。首先掌握简单的任务,然后你就有了解决更复杂问题的背景知识。谢谢Jeffrey。当然可以。谢谢你的回答杰弗里·拉利特。实际上,我正在尝试使用带有ref游标的OPEN FOR语句编写代码。第二个解决方案使用带有ref游标变量的OPEN FOR语句。是的。我已经完成了。现在根据下面的查询解决了它。设置serveroutput on;cl-scr();声明类型t_emp_cursor为ref cursor返回emp%ROWTYPE;v_emp_cur t_emp_光标;v_emp emp%行类型;开始打开v_emp_cur以从emp中选择*,其中emp_ID=2;循环获取v_emp_cur到v_emp;未找到v_emp_cur%时退出;dbms_output.put_line('Emp_id='|| v|Emp.Emp_id | |',Emp_name='| v|u Emp.Emp_name);端环;关闭v_emp_cur;结束/为什么使用return语句?