从自定义游标类型获取参考游标

Getting a Ref Cursor from Custom Cursor Type

我们有一个名为 "Get()" 的现有 PL SQL 过程,当提供一个 order_no_ 和一个 sequence_no_ 时,return 是一个命名的 REF CURSOR类型名为 "CURSOR_TYPE"。我需要为这个方法创建一个 "overload",程序员只需传入 order_no_(没有 sequence_no_),它会重复调用该方法并收集所有 [=] 的所有记录27=] 值转换为单个 return "CURSOR_TYPE" REF CURSOR。这是我为实现这一目标而写的,试图遵循示例 shown here

    PROCEDURE Get(order_no_ IN VARCHAR2, results_cursor OUT CURSOR_TYPE)
    AS
    --Declare a "nested table type" table
    TYPE CoC_RowType IS TABLE OF customer_order_charge_cfv%ROWTYPE; 
    CoC_RowTable CoC_RowType := CoC_RowType();
    CURSOR c1 IS
      SELECT coc.SEQUENCE_NO
      FROM customer_order_charge_cfv coc
      WHERE coc.ORDER_NO = order_no_;
    BEGIN
    FOR i in c1 LOOP
        CoC_RowTable.extend();
        Get(order_no_, i.sequence_no, results_cursor);
        FETCH results_cursor INTO CoC_RowTable(CoC_RowTable.count);
    END LOOP;

    OPEN results_cursor FOR SELECT * FROM TABLE(CoC_RowTable);

    END Get;

然而,当我尝试将此代码编译到我的程序包中时,出现以下错误:

    Compilation errors for PACKAGE BODY GLOB1APP.GFS_CUSTOMER_ORDER_CHARGE_CFP

    Error: PLS-00382: expression is of wrong type
    Line: 81
    Text: OPEN results_cursor FOR SELECT * FROM TABLE(CoC_RowTable);

    Error: PL/SQL: ORA-22905: cannot access rows from a non-nested table item
    Line: 81
    Text: OPEN results_cursor FOR SELECT * FROM TABLE(CoC_RowTable);

    Error: PL/SQL: SQL Statement ignored
    Line: 81
    Text: OPEN results_cursor FOR SELECT * FROM TABLE(CoC_RowTable);

这行似乎出错了:

    OPEN results_cursor FOR SELECT * FROM TABLE(CoC_RowTable);

我做错了什么?我怎样才能实现我的目标?这是完全错误的实现方式吗?

Oracle 中有两个 "types" 类型:

SQL 类型,由 SQL 语句创建:

CREATE OR REPLACE TYPE...
/

和 PL/SQL 类型,在 PL/SQL 代码中声明。

您正试图在 SQL 语句中使用 PL/SQL 类型。 SQL 语句只知道 SQL 类型。您要么必须创建 SQL "object" 类型,然后创建该对象的 SQL "table" 类型,要么做一些不同的事情。

此外,REF CURSOR 的工作方式与您的代码试图使其工作的方式不同。您需要执行 one SQL 查询 returns 与所有这些 GET() 调用相同的数据,然后 return 游标查询而不做任何提取。客户端进行抓取。

要获得更多详细信息,post CURSOR_TYPE 的定义并显示 GET() 实际查询的内容。

这可能简单也可能不简单,具体取决于您的回答。

此致, 炖阿什顿

为什么不更改现有的过程和查询来同时执行这两项操作?简单例子:

SQL> create table customer_order_charge_cfv(
  2    order_no number,
  3    sequence_no number
  4  );

Table CUSTOMER_ORDER_CHARGE_CFV created.

SQL> insert into customer_order_charge_cfv
  2  select 1,1 from dual union all
  3  select 1,2 from dual;

2 rows inserted.

SQL> create or replace PROCEDURE Get(
  2    order_no_ IN VARCHAR2, 
  3    sequence_no_ IN VARCHAR2 default null, 
  4    results_cursor OUT SYS_REFCURSOR
  5  ) AS
  6  BEGIN
  7  OPEN results_cursor FOR 
  8    SELECT *
  9    FROM customer_order_charge_cfv coc
 10    WHERE coc.ORDER_NO = order_no_
 11    and (coc.sequence_no = sequence_no_ or sequence_no_ is null);
 12  END Get;
 13  /

Procedure GET compiled

SQL> var rc refcursor;

SQL> exec get(1,2,:rc);

PL/SQL procedure successfully completed.


SQL> print :rc;

  ORDER_NO SEQUENCE_NO
---------- -----------
         1           2

SQL> exec get(1,results_cursor => :rc);

PL/SQL procedure successfully completed.

SQL> print :rc;

  ORDER_NO SEQUENCE_NO
---------- -----------
         1           1
         1           2

此致, 炖菜