1:关于游标中的LOOP语句什么时候结束循环的问题
先看下面一段代码,通常显示游标提取的数据不会只有一条,而是多条记录。这样就需要一个遍历结果集的方式,而LOOP就能实现该功能。下面是实验的代码:
DECLARE
CURSOR pdct_loop_cur
IS
SELECT PRODUCTID, PRODUCTNAME, PRODUCTPRICE FROM PRODUCTINFO
WHERE PRODUCTPRICE > 2500;
cur_productid productinfo.productid%TYPE;
cur_productname productinfo.productname%TYPE;
cur_productprice productinfo.productprice%TYPE;
BEGIN
OPEN pdct_loop_cur;
LOOP
FETCH pdct_loop_cur INTO cur_productid, cur_productname, cur_productprice;
EXIT WHEN pdct_loop_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('产品ID: ' || cur_productid || '产品名称:'
|| cur_productname || '产品价格:' || cur_productprice);
END LOOP;
CLOSE pdct_loop_cur;
END;
/
注意EXIT WHEN pdct_loop_cur%NOTFOUND;它是放在FETCH的下面一行,运行结果如下:
如果把EXIT WHEN pdct_loop_cur%NOTFOUND;放在循环的最后:
DECLARE
CURSOR pdct_loop_cur
IS
SELECT PRODUCTID, PRODUCTNAME, PRODUCTPRICE FROM PRODUCTINFO
WHERE PRODUCTPRICE > 2500;
cur_productid productinfo.productid%TYPE;
cur_productname productinfo.productname%TYPE;
cur_productprice productinfo.productprice%TYPE;
BEGIN
OPEN pdct_loop_cur;
LOOP
FETCH pdct_loop_cur INTO cur_productid, cur_productname, cur_productprice;
DBMS_OUTPUT.PUT_LINE('产品ID: ' || cur_productid || '产品名称:'
|| cur_productname || '产品价格:' || cur_productprice);
EXIT WHEN pdct_loop_cur%NOTFOUND;
END LOOP;
CLOSE pdct_loop_cur;
END;
/
注意这里最后多输出了一条,而且是跟游标中的最后一条记录是一样。
那如果取消EXIT WHEN pdct_loop_cur%NOTFOUND;呢?
DECLARE
CURSOR pdct_loop_cur
IS
SELECT PRODUCTID, PRODUCTNAME, PRODUCTPRICE FROM PRODUCTINFO
WHERE PRODUCTPRICE > 2500;
cur_productid productinfo.productid%TYPE;
cur_productname productinfo.productname%TYPE;
cur_productprice productinfo.productprice%TYPE;
BEGIN
OPEN pdct_loop_cur;
LOOP
FETCH pdct_loop_cur INTO cur_productid, cur_productname, cur_productprice;
--EXIT WHEN pdct_loop_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('产品ID: ' || cur_productid || '产品名称:'
|| cur_productname || '产品价格:' || cur_productprice);
END LOOP;
CLOSE pdct_loop_cur;
END;
/
如图:
这里会无限循环,但是最后输出的都是游标中的最后一条记录。由此是否可以这样推测(自己的推测):
游标的指针初始时它指向首记录,而后每次循环向后移一个位置,并且如果最后是没有记录的,即WHEN pdct_loop_cur%NOTFOUND时会发出已经到了记录末尾的信息,不过这时指针指向的还是有效记录的最后一个位置。这样就可以解释为什么去掉了EXIT WHEN pdct_loop_cur%NOTFOUND;之后,输出的是连续的最后一个记录的值。