带有 LOOP 的游标

Cursors with LOOP

抱歉代码太长。我要做的就是将变量 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;
/

作为循环的一部分,没有增量发生,所以它总是相同的。 我不确定您是否将此假设为增加 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 变量 匹配的所有记录。所以你的循环将获取一行耗尽游标。下一次提取不提取任何内容,因此 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;
/