Oracle 从自定义游标类型获取引用游标

Oracle 从自定义游标类型获取引用游标,oracle,plsql,oracle11g,ref-cursor,rowtype,Oracle,Plsql,Oracle11g,Ref Cursor,Rowtype,我们有一个名为“Get()”的现有PL SQL过程,当提供一个order\u no\u和一个sequence\u no\u时,它返回一个名为“CURSOR\u type”的命名引用游标类型。我需要对这个方法做一个“重载”,程序员只按顺序传递(无序列),它重复调用该方法,并将所有序列值的所有记录收集到一个返回的“CURSOR\u TYPE”REF CURSOR中。下面是我写的,试图实现这一点,尝试遵循的例子 但是,当我尝试将此代码编译到我的包中时,出现以下错误: Compilation e

我们有一个名为“Get()”的现有PL SQL过程,当提供一个order\u no\u和一个sequence\u no\u时,它返回一个名为“CURSOR\u type”的命名引用游标类型。我需要对这个方法做一个“重载”,程序员只按顺序传递(无序列),它重复调用该方法,并将所有序列值的所有记录收集到一个返回的“CURSOR\u TYPE”REF CURSOR中。下面是我写的,试图实现这一点,尝试遵循的例子

但是,当我尝试将此代码编译到我的包中时,出现以下错误:

    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中有两种类型:

由SQL语句创建的SQL类型:

CREATE OR REPLACE TYPE...
/
和PL/SQL类型,在PL/SQL代码中声明

您正试图在SQL语句中使用PL/SQL类型。SQL语句只知道SQL类型。您要么创建一个SQL“对象”类型,然后创建该对象的SQL“表”类型,要么执行其他操作

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

要获得更多详细信息,请发布游标类型的定义,并显示get()实际查询的内容

这可能是容易的,也可能不是,这取决于你的答案

致以最良好的祝愿,
Stew Ashton

为什么不将现有的过程和查询更改为两者都做呢?简单的例子:

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
问候,,
斯图

您是否调查了您遇到的错误?有许多问题和答案解释了不能在这样的SQL查询中使用PL/SQL集合类型。您可以改为创建架构级对象和表类型吗?(正如关于您链接的问题的公认答案所做的那样;注释指的是并不总是可取的…@AlexPoole对于此更改的要求,我不允许创建任何架构级别的对象/类型,所有内容都必须限定在此包/方法的范围内。那么您恐怕有点卡住了。你将不得不让这个过程复制原始过程,只是没有序列号。这对可维护性来说不是什么好消息,但对性能来说可能是个好消息。@AlexPoole谢谢,这正是我所担心的-必须复制并粘贴原始Get()方法并修改其where子句。。。我想通过过载来避免这种情况,正如您所说,以提高可维护性。。。。但是如果你说不创建一个新的模式级对象就不可能实现这个目标。。。然后呃。。。我想我必须做我必须做的。。。谢谢你的帮助,太好了!我没有想到为序列号设置默认值,并为“备用版本”匹配空值。那应该很有效,谢谢!
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