为啥我在 PL/SQL 中的 for 循环没有打印出最后一次迭代
Posted
技术标签:
【中文标题】为啥我在 PL/SQL 中的 for 循环没有打印出最后一次迭代【英文标题】:why is my for loop in PL/SQL not printing out the last iteration为什么我在 PL/SQL 中的 for 循环没有打印出最后一次迭代 【发布时间】:2014-04-26 22:21:49 【问题描述】:我正在创建一个获取费用编号的 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;
/
【问题讨论】:
也许您的表中有重复的EXPNUM
值,或者这些值从 0 而不是 1 开始。此外,您可能可以使用分析函数做您想做的事情,但这样会更容易知道您是否提供了示例数据和所需的输出。
如果您没有连续的一系列 expnum
值,您的代码也会失败 - 即这些数字之间的差距。首先,循环内的第二个选择将获得no_data_found
的不存在值。如果您确实想在循环中执行此操作作为练习,您可以将所有 expnum
值批量选择到一个集合中并对其进行迭代。但这仍然不是查看这些数据的最有效方式。
您可能需要考虑在 EXPDET 表上使用游标 FOR 循环,而不是使用值 FOR 循环。根据我的经验,价值 FOR 循环在 PL/SQL 中几乎没有用处,而游标 FOR 循环是该语言的基础。 YMMV。分享和享受。
正如已经讨论过的,肯定有更好的方法来解决这个问题,但也许你在最后一行有totalPaid > lineTotal
?在这种情况下,你不会写任何东西......
【参考方案1】:
只要您在 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;
/
【讨论】:
以上是关于为啥我在 PL/SQL 中的 for 循环没有打印出最后一次迭代的主要内容,如果未能解决你的问题,请参考以下文章