如何使用多个表循环 SYS_REFCURSOR?
Posted
技术标签:
【中文标题】如何使用多个表循环 SYS_REFCURSOR?【英文标题】:How to loop a SYS_REFCURSOR with multiple tables? 【发布时间】:2014-10-09 19:52:46 【问题描述】:很抱歉问题的标题过于宽泛,但我没有找到进一步简化它的方法。
我正在为客户创建一个包,这个包有一个返回SYS_REFCURSOR
的过程。提供它的查询是一个包含大约 20 个字段的多表选择。在第二个过程中,我需要调用它,并循环遍历结果以提供其他位置。
我在使用循环的into
部分时遇到问题。我不能使用table%ROWTYPE
。我试图在程序上声明一个OBJECT
,但这是不允许的。我需要FETCH XXX INTO LIST_OF_INDVIDUAL_VARIABLES
吗?
DECLARE
dt_field TABLE1.dt_field%TYPE;
p_resultset SYS_REFCURSOR;
p_individual OBJECT (
FIELD0 DATE,
FIELD1 TABLE.FIELD1%TYPE,
FIELD2 TABLE.FIELD2%TYPE,
FIELD3 TABLE.FIELD3%TYPE,
FIELD4 TABLE.FIELD4%TYPE
);
BEGIN
PACKAGE.PROCEDURE1(dt_field);
dbms_output.put_line(dt_field);
PACKAGE.PROCEDURE2(dt_field, p_resultset);
LOOP
-- this do not work
FETCH p_resultset INTO p_individual;
EXIT WHEN p_resultset%NOTFOUND;
-- DO STUFF ON EACH RETURNED ROW
END LOOP;
CLOSE p_resultset;
END;
【问题讨论】:
“我试图在过程中声明一个 OBJECT 但不允许”由于您的企业政策?由于缺乏所需的权限?或者它只是产生某种错误? 看看 Alex Poole 的这个答案也许:***.com/a/11233929/2363712 您需要在 PL/SQL 中声明一个记录类型,而不是一个对象,然后是该记录类型的一个实例。显示你得到的错误会很有帮助。我不确定您是否可以将引用游标提取到记录类型中,即兴发挥。 【参考方案1】:根据我的评论,不能在 PL/SQL 中创建对象类型,需要声明记录类型,然后声明该类型的实例:
DECLARE
type r_individual is record (
FIELD0 DATE,
FIELD1 TABLE1.FIELD1%TYPE,
FIELD2 TABLE1.FIELD2%TYPE,
FIELD3 TABLE1.FIELD3%TYPE,
FIELD4 TABLE1.FIELD4%TYPE
);
p_individual r_individual;
...
您可以将引用游标提取到记录类型中。对象声明上的版本错误,而不是 fetch
。
根据您的问题,这是一个更完整的示例;我没有你的程序,所以我正在创建一个具有相同类型的虚拟结果集,并为 %TYPE
声明使用了一个虚拟表:
create table table1(dt_field date, field1 number, field2 varchar2(1),
field3 number, field4 varchar2(1));
set serveroutput on
DECLARE
type r_individual is record (
FIELD0 DATE,
FIELD1 TABLE1.FIELD1%TYPE,
FIELD2 TABLE1.FIELD2%TYPE,
FIELD3 TABLE1.FIELD3%TYPE,
FIELD4 TABLE1.FIELD4%TYPE
);
dt_field TABLE1.dt_field%TYPE;
p_resultset SYS_REFCURSOR;
p_individual r_individual;
BEGIN
-- Don't have this package
-- PACKAGE.PROCEDURE1(dt_field);
-- dbms_output.put_line(dt_field);
-- PACKAGE.PROCEDURE2(dt_field, p_resultset);
-- Dummy result set for demo instead
OPEN p_resultset FOR q'[select sysdate, 1, 'A', 3, 'C' from dual]'
|| q'[ union all select sysdate, 2, 'B', 4, 'D' from dual]';
LOOP
FETCH p_resultset INTO p_individual;
EXIT WHEN p_resultset%NOTFOUND;
-- DO STUFF ON EACH RETURNED ROW
DBMS_OUTPUT.PUT_LINE(p_individual.field1
|| ':' || p_individual.field2);
END LOOP;
CLOSE p_resultset;
END;
/
得到:
anonymous block completed
1:A
2:B
【讨论】:
谢谢伙计,这正是我失败的地方。从 mysql\MariaDB 迁移是一项巨大的努力。仍在努力寻找自己的方式。 出现:INTO 列表中的表达式“P_INDIVIDUAL”类型错误 @delive - 出现在哪里?这段代码在 SQL*Plus 和 SQL Developer 中运行没有错误,同样是 11g 和 12c。什么是完整的 ORA- 或 PLS- 错误消息?还是您的客户端/IDE 自己生成?如果您遇到无法解决的问题,则需要提出一个新问题。 @Alex Poole 错误出现在 FETCH p_resultset INTO p_individual;我有多个表,我收到此错误。例如,您在此代码中有“TABLE1”。我有“表 1”。 “表 2。” “表3。”与行类型 @delive - 那么您还没有调整它以正确匹配您的查询。就像我说的,提出一个新问题,显示您的表格、您的代码版本以及您遇到的问题。以上是关于如何使用多个表循环 SYS_REFCURSOR?的主要内容,如果未能解决你的问题,请参考以下文章
我试图从 sys_refcursor 获取 bulkcollect 记录并尝试使用 forall 插入另一个表,但它抛出了一条错误消息