1

我正在尝试执行一个接收 REFCURSOR 并执行一些数据操作的函数。

为了测试我的功能,我有这个 SQL/PLUS 代码:

var some_cursor REFCURSOR;

exec :some_cursor := SCHEMA.test_getcursor;

print some_cursor;

variable res varchar2;

exec :res := SCHEMA.second_function(:some_cursor, 'Other_parameter');

print res;  

现在,第一个test_getcursor函数是一个简单的函数,它打开游标,执行选择查询并返回游标。它工作得很好,打印some_cursor也很好。

当我调用second_function并将 refcursor 传递给它时,就会出现问题。

函数有以下代码:

type cursor_row
IS RECORD
(field_1 some_field1%type,
 field_2 some_field2%type,
 field_3 some_field3%type);

 new_row cursor_row;

BEGIN
LOOP
fetch PASSED_IN_REFCURSOR INTO new_row --this is where the function fails
...data manipulation...
EXIT WHEN PASSED_IN_REFCURSOR%NOTFOUND;
END LOOP;
CLOSE PASSED_IN_REFCURSOR;
END;

我得到的错误是Invalid Cursor.

我确信我创建的类型与 ref 游标具有相同的行数和相同的数据类型。

在这种情况下我做错了什么?我正在使用 Oracle 10g、PL/SQL 10.2

4

1 回答 1

3

这是你的问题:

print some_cursor;

去掉它。通过打印游标,您获取了所有记录并将其关闭。所以第二个函数不能再读取它了。

例如;

SQL> create procedure two(p_rc sys_refcursor)
  2  is
  3    v_col varchar2(1);
  4  begin
  5    loop
  6      fetch p_rc into v_col;
  7      exit when p_rc%notfound;
  8      dbms_output.put_line(v_col);
  9    end loop;
 10  end;
 11  /

Procedure created.

SQL> set serverout on
SQL> var rc refcursor;
SQL> exec :rc := one;

PL/SQL procedure successfully completed.

SQL> exec two(:rc);
X

PL/SQL procedure successfully completed.

对比

SQL> var rc refcursor;
SQL> exec :rc := one;

PL/SQL procedure successfully completed.

SQL> print rc

D
-
X

SQL> exec two(:rc);
BEGIN two(:rc); END;

*
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at "TEST.TWO", line 6
ORA-06512: at line 1

由于光标未打开,因此在获取时会爆炸。如果你想返回一个更有用的错误,你应该%isopen首先检查并提出一个定义的错误。

于 2013-02-27T16:41:08.740 回答