带 LOOP 的光标
Posted
技术标签:
【中文标题】带 LOOP 的光标【英文标题】:Cursors with LOOP 【发布时间】:2017-06-06 20:55:54 【问题描述】:抱歉,代码太长了。我要做的就是将变量YM1
(201702, 201703, 201704) 增加一个月,执行 SQL 语句并使用 CURSOR 显示结果。
当前行为:YM1
变量未递增。代码执行但始终使用YM1 = '201702'
。
YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 0
YEAR_MONTH 201701 201704 0
预期结果:
YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 10
YEAR_MONTH 201701 201704 20
请让我知道我缺少什么。打破我的头。非常感谢您的时间。
set serveroutput on
DECLARE
YM VARCHAR2(10) := '201701';
YM1 VARCHAR2(10) := '201702';
row1 number := 0;
CURSOR counts is
SELECT COUNT(*)
FROM **table1 a**
WHERE a.year_month = YM
AND EXISTS
( SELECT 'Y'
FROM **table2 b**
WHERE a.id = b.id
AND b.year_month = YM1 );
BEGIN
OPEN counts;
LOOP
FETCH counts INTO row1;
dbms_output.put_line('YEAR_MONTH '||YM||' '||YM1||' '||row1);
YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
EXIT WHEN YM1 > '201704'
END LOOP;
CLOSE counts;
END;
/
【问题讨论】:
【参考方案1】:问题是,当您打开游标时,它会选择所有匹配YM1
变量的记录在打开时。因此,您的循环将获取耗尽游标的一行。下一次 fetch 什么都没有,所以 row1
的值不会更新。
要获取新值,您需要每次打开和关闭光标:
DECLARE
YM VARCHAR2(10) := '201701'
YM1 VARCHAR2(10) := '201702'
row1 number := 0;
CURSOR counts is
SELECT COUNT(*)
FROM table1 a
WHERE a.YEAR_MONTH = YM
AND EXISTS (SELECT 'Y'
FROM table2 b
WHERE a.id = b.id
AND b.YEAR_MONTH = YM1);
BEGIN
LOOP
OPEN counts;
FETCH counts INTO row1;
dbms_output.put_line('YEAR_MONTH '||YM||' '||YM1||' '||row1);
YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
EXIT WHEN YM1 > '201704'
CLOSE counts;
END LOOP;
END;
/
【讨论】:
【参考方案2】:循环中没有增量发生,所以它总是相同的。 我不确定您是否将此假设为增加 YM1 值的逻辑,但它永远不会这样做。 ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1)
你想增加 YM 吗?尝试使用以下 YM1 语句递增 YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
编辑为您提供输出..
set serveroutput on
DECLARE
YM VARCHAR2(10) := '201701';
YM1 VARCHAR2(10) := '201702';
BEGIN
dbms_output.put_line(' Timing YM YM1');
dbms_output.put_line('Before Increment'||YM||' '||YM1);
LOOP
YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
dbms_output.put_line('After Increment '||YM||' '||YM1);
EXIT WHEN YM1 > '201704';
END LOOP;
END;
/
Timing YM YM1
Before Increment201701 201702
After Increment 201701 201703
After Increment 201701 201704
After Increment 201701 201705
PL/SQL procedure successfully completed.
我刚刚删除了表格和光标..
【讨论】:
我正在尝试增加 YM1。这是我上面粘贴的代码中的错字,我使用了 YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');请参阅当前结果,YM 相同(201701),但 YM1 仅在结果中递增(201702,201703,201704)。希望这很清楚。 我刚刚给了你我执行的输出,它正在增加..检查一次 我正在尝试增加 YM1 并在 EXISTS 子句内的 CURSOR 块中使用它。您的代码缺少 CURSOR,这是我想要实现的。谢谢你分享这个。以上是关于带 LOOP 的光标的主要内容,如果未能解决你的问题,请参考以下文章