为什么PL / SQL中的for循环不会打印出最后一次迭代

时间:2014-04-26 22:21:49

标签: database oracle for-loop plsql

我正在创建一个获得费用编号的PL / SQL脚本,然后获得用于支出的现金总额,用于购买的信用额,费用总额以及支付的总金额。我正在使用FOR循环为我的表中的每个expnum完成此操作。获得这些值后,它会查看totalPaid是否小于或等于费用总额。当我的循环运行时,它输出expNum 1到4的信息,即使我的表中有5个。我无法弄清楚为什么脚本没有运行5次并且在第4次执行后停止。下面是我的脚本。任何提示/帮助非常感谢谢谢。

DECLARE
  lineTotal NUMBER;
  cashPaid NUMBER;
  creditPaid NUMBER;
  totalPaid NUMBER;
  expNumMax NUMBER;
BEGIN
  SELECT MAX(EXPNUM)
    INTO expNumMax
    FROM EXPDET;

  dbms_output.put_line ('EXP num max is: ' || expNumMax);

  FOR expNumCounter IN 1..expNumMax
  LOOP
    SELECT SUM(Amt)
      INTO lineTotal
      FROM EXPDET
      WHERE ExpNum = expNumCounter;

    SELECT CASHAMT
      INTO cashPaid
      FROM EXPMAST
      WHERE ExpNum = expNumCounter;

    SELECT SUM(Amt)
      INTO creditPaid
      FROM ExpByCc
      WHERE ExpNum = expNumCounter;

    totalPaid := cashPaid + creditPaid;

    IF totalPaid < lineTotal THEN
      dbms_output.put_line ('SELECT * FROM expmast');
    END IF;

    IF totalPaid = lineTotal THEn
      dbms_output.put_line ('EXPNUM is: ' || expNumCounter);
      dbms_output.put_line ('Line Total is: '|| lineTotal);
      dbms_output.put_line ('cashPaid is: ' || cashPaid);
      dbms_output.put_line ('Credit Paid is: '|| creditPaid);
      dbms_output.put_line ('Total paid is: ' || totalPaid);
    END IF;
  END LOOP;
END;
/

1 个答案:

答案 0 :(得分:0)

只要您在EXPDET中没有这么多记录,就会耗尽内存,以下代码应该满足您的需求。

(注意:我没有运行代码,因为我没有你的数据结构)

DECLARE
  CURSOR c_EXPDET IS
    SELECT EXPNUM
      INTO expNumMax
      FROM EXPDET
    ;
  TYPE t_EXPDET IS TABLE OF c_EXPDET%ROWTYPE INDEX BY PLS_INTEGER;  
  l_EXPDET t_EXPDET;

  l_cur NUMBER;

  lineTotal NUMBER;
  cashPaid NUMBER;
  creditPaid NUMBER;
  totalPaid NUMBER;
  expNumMax NUMBER;
BEGIN
  OPEN c_EXPDET;
  FETCH c_EXPDET BULK COLLECT INTO l_EXPDET;
  CLOSE c_EXPDET;

  l_cur := l_EXPDET.FIRST;
  WHILE (l_cur IS NOT NULL) LOOP
        SELECT SUM(Amt)
          INTO lineTotal
          FROM EXPDET
          WHERE ExpNum = l_EXPDET(l_cur);

        SELECT CASHAMT
          INTO cashPaid
          FROM EXPMAST
          WHERE ExpNum = l_EXPDET(l_cur);

        SELECT SUM(Amt)
          INTO creditPaid
          FROM ExpByCc
          WHERE ExpNum = l_EXPDET(l_cur);

        totalPaid := cashPaid + creditPaid;

        IF totalPaid < lineTotal THEN
          dbms_output.put_line ('SELECT * FROM expmast');
        END IF;

        IF totalPaid = lineTotal THEN
          dbms_output.put_line ('EXPNUM is: ' || l_EXPDET(l_cur));
          dbms_output.put_line ('Line Total is: '|| lineTotal);
          dbms_output.put_line ('cashPaid is: ' || cashPaid);
          dbms_output.put_line ('Credit Paid is: '|| creditPaid);
          dbms_output.put_line ('Total paid is: ' || totalPaid);
        END IF;

        l_cur := l_EXPDET.NEXT(l_cur);
  END LOOP; --Loop through EXPDET  

END;
/