需要帮助在游标 PLSQL 中运行 2 个查询
Posted
技术标签:
【中文标题】需要帮助在游标 PLSQL 中运行 2 个查询【英文标题】:Need help running 2 queries in a Cursor PLSQL 【发布时间】:2015-03-09 15:18:24 【问题描述】:我是 PLSQL 的新手,需要根据用户输入运行两个查询之一。到目前为止,我创建了这个......
Set serveroutput on;
Declare
cv_prod SYS_REFCURSOR;
rec_d dd_pledge%ROWTYPE;
rec_s dd_pledge%ROWTYPE;
userinput varchar(1):='&Enter';
Begin
If lower(userinput)= 'd' THEN
OPEN cv_prod FOR Select dd_payment.idpay, dd_pledge.idpledge, dd_pledge.iddonor, dd_payment.paydate, pledgeamt/paymonths
from dd_pledge
join dd_payment
on dd_pledge.idpledge=dd_payment.idpledge
where iddonor=308
order by idpay, dd_pledge.iddonor;
LOOP
FETCH cv_prod into rec_d;
EXIT WHEN cv_prod%NOTFOUND;
--DBMS_OUTPUT.PUT_LINE(rec_d);
END LOOP;
ELSIF lower(userinput)= 's' THEN
OPEN cv_prod FOR Select dd_pledge.idpledge, sum(pledgeamt/paymonths)
from dd_pledge
join dd_payment
on dd_pledge.idpledge=dd_payment.idpledge
where iddonor=308
group by dd_pledge.idpledge;
LOOP
FETCH cv_prod into rec_s;
EXIT WHEN cv_prod%NOTFOUND;
--DBMS_OUTPUT.PUT_LINE(rec_s);
END LOOP;
END IF;
结束; 所以我得到的错误是结果集变量或查询的返回类型不匹配。我不明白,因为我的记录或篮子应该与列所来自的表具有相同的行类型。请帮忙!
已编辑记录的声明声明... 声明
cv_prod SYS_REFCURSOR;
type rec_d is Record(idpay dd_payment.idpay%type, idpledge dd_pledge.idpledge%type, iddonor dd_pledge.iddonor%type, paydate dd_payment.paydate%type);
cv prod rec_d;
type rec_s is Record(pledge dd_pledge.idpledge%type)
cv_prod rec_s
rec_s dd_pledge%ROWTYPE;
userinput varchar(1):='&Enter';
必须接近...新代码。 --捐助者 ID = 308 /* Lucas Gutknecht 第 4 章 */
Set serveroutput on;
Declare
cv_prod SYS_REFCURSOR;
type rec_d is Record(idpay dd_payment.idpay%type, idpledge dd_pledge.idpledge%type, iddonor dd_pledge.iddonor%type, paydate dd_payment.paydate%type);
rec_d1 rec_d;
type rec_s is Record(pledge dd_pledge.idpledge%type);
rec_s1 rec_s;
userinput varchar(1):='&Enter';
Begin
If lower(userinput)= 'd' THEN
OPEN cv_prod FOR Select dd_payment.idpay, dd_pledge.idpledge, dd_pledge.iddonor, dd_payment.paydate /*pledgeamt/paymonths*/
from dd_pledge
join dd_payment
on dd_pledge.idpledge=dd_payment.idpledge
where iddonor=308
order by idpay, dd_pledge.iddonor;
LOOP
FETCH cv_prod into rec_d1;
EXIT WHEN cv_prod%NOTFOUND;
--DBMS_OUTPUT.PUT_LINE(rec_d);
END LOOP;
ELSIF lower(userinput)= 's' THEN
OPEN cv_prod FOR Select dd_pledge.idpledge, /*sum(pledgeamt/paymonths)*/
from dd_pledge
join dd_payment
on dd_pledge.idpledge=dd_payment.idpledge
where iddonor=308
group by dd_pledge.idpledge;
LOOP
FETCH cv_prod into rec_s1;
EXIT WHEN cv_prod%NOTFOUND;
--DBMS_OUTPUT.PUT_LINE(rec_s);
END LOOP;
END IF;
End
;
【问题讨论】:
dd_pledge 表是什么样子的? 【参考方案1】:在第一个光标中,您选择了 5 列 -
OPEN cv_prod FOR Select dd_payment.idpay, dd_pledge.idpledge, dd_pledge.iddonor, dd_payment.paydate, pledgeamt/paymonths
在第二个光标中,您只选择了 2 列 -
OPEN cv_prod FOR Select dd_pledge.idpledge, sum(pledgeamt/paymonths)
这两个游标都被提取到一个相同类型的变量中,即dd_pledge%ROWTYPE;
。
表有 5 列或 2 列。根据表 dd_pledge
的结构更改未返回与基表相同列数的游标。
如果您选择不同的数据,我建议为此创建两个单独的过程,或者创建两个具有与其各自光标匹配的不同数据类型的记录变量。
【讨论】:
谢谢你说得有道理。是否可以使用一个游标创建具有不同列和数据类型的两条记录?我需要在一个游标中运行这两个查询。我该怎么做?我对游标的理解很模糊。 您不能在游标中“运行”两个查询。游标是指向单个 SQL 区域的指针。完成第一个 sql 后,您可以重新分配指针以指向不同的 sql。我建议阅读this article 了解一些基础知识。 我的意思是说一次只运行一个查询,但可以根据用户输入运行两个不同的查询。根据输入的“s”或“d”,光标不会只运行一次,并且该光标不会与信息的来源具有相同的类型吗? 光标只是一个指针。像这样的弱游标可以指向一个有 1 列的查询或一个有 100 列的查询。这与任何基表有多少列无关。问题是 FETCH 语句。当您从此游标中获取 1 行到变量中时,该变量应具有与游标指向的列数相同的列数。在您的情况下,您已将变量定义为rec_d dd_pledge%ROWTYPE;
和rec_s dd_pledge%ROWTYPE;
。这两个变量都采用表格中一行的格式dd_pledge
您可能想做的是创建另一个记录类型变量(查找CREATE TYPE ... AS RECORD ...
),然后将游标的结果提取到该变量中。以上是关于需要帮助在游标 PLSQL 中运行 2 个查询的主要内容,如果未能解决你的问题,请参考以下文章