0

我们有一个名为“Get()”的现有 PL SQL 过程,当提供 order_no_ 和 sequence_no_ 时,它返回一个名为“CURSOR_TYPE”的命名 REF CURSOR 类型。我需要对此方法进行“重载”,程序员只需传入 order_no_(无 sequence_no_),它会重复调用该方法并将所有 sequence_no_ 值的所有记录收集到单个返回“CURSOR_TYPE”REF CURSOR 中。以下是我为尝试完成此操作而写的内容,并尝试按照此处显示的示例进行操作。

    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);

我究竟做错了什么?我怎样才能实现我的目标?这完全是实现这一目标的错误途径吗?

4

2 回答 2

1

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

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

问候,炖

于 2019-09-13T15:26:07.893 回答
0

Oracle中有两种“类型”的TYPE:

SQL 类型,由 SQL 语句创建:

CREATE OR REPLACE TYPE...
/

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

您正在尝试在 SQL 语句中使用 PL/SQL 类型。SQL 语句只知道 SQL 类型。您要么必须创建一个 SQL“对象”类型,然后是该对象的 SQL“表”类型,要么做一些不同的事情。

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

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

这可能很容易,也可能不取决于您的答案。

最好的问候,炖阿什顿

于 2019-09-13T15:09:11.303 回答