从自定义游标类型获取参考游标
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
此致,
炖菜
我们有一个名为 "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
此致, 炖菜