首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > oracle >

fetch . bulk collect into . limit xxx 中 limit 的取值有关问题

2012-03-18 
fetch .. bulk collect into .. limit xxx 中 limit 的取值问题SQL codedeclare--声明需要集合类型及变量,

fetch .. bulk collect into .. limit xxx 中 limit 的取值问题

SQL code
declare  --声明需要集合类型及变量,参照字段的 type 来声明类型  type id_type is table of sr_contacts.sr_contact_id%type;  v_id id_type;    type phone_type is table of sr_contacts.contact_phone%type;  v_phone phone_type;    type remark_type is table of sr_contacts.remark%type;  v_remark remark_type;  cursor all_contacts_cur is --用 rownum 来限定取出的记录数来测试     select sr_contact_id,contact_phone,remark from sr_contacts where rownum <= 50begin        open all_contacts_cur;    loop                fetch all_contacts_cur bulk collect into v_id,v_phone,v_remark limit 20        exit when all_contacts_cur%notfound;        for i in 1..v_id.count loop --遍历集合            --用 v_id(i)/v_phone(i)/v_remark(i) 取出字段值来执行你的业务逻辑            null; --这里只放置一个空操作,只为测试循环取数的效率            dbms_output.put_line('here');        end loop;            end loop;    close all_contacts_cur;end;


像上面的执行过程,如果去除外层的循环直接不带 limit 参数用
fetch all_contacts_cur bulk collect into v_id,v_phone,v_remark
是能够遍历到所有的记录。

而带了 limit 20 参数,因为返回的记录数是 50,执行了两次 fetch bulk 后,还剩下 10 条记录,不足 20 时,第三次 fetch bulk 根本就不取记录,所以程序只会打印出 40 行的 here.

也就是说当 limit 参数值大于游标中的记录数,fetch bulk into 根本不工作,那么这个 limit 该如何指定合适的值呢,因为游标的记录值是没法知道的。

[解决办法]
SQL code
        fetch all_contacts_cur bulk collect into v_id,v_phone,v_remark limit 20;        for i in 1..v_id.count loop --遍历集合            --用 v_id(i)/v_phone(i)/v_remark(i) 取出字段值来执行你的业务逻辑            null; --这里只放置一个空操作,只为测试循环取数的效率            dbms_output.put_line('here');        end loop;[color=#FF0000]        exit when all_contacts_cur%notfound;[/color]
[解决办法]
什么版本的数据库? 10.2.0.1的可以. 下面是执行的LOG.


SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 CURSOR CUR_1 IS
3 SELECT TABLE_NAME FROM DBA_TABLES
4 WHERE ROWNUM < 50;
5 TYPE T_CUR_1 IS TABLE OF CUR_1%ROWTYPE;
6 V_CUR1 T_CUR_1;
7
8 BEGIN
9 OPEN CUR_1;
 10 LOOP
 11 FETCH CUR_1 BULK COLLECT INTO V_CUR1 LIMIT 20;
 12 FOR X IN 1..V_CUR1.COUNT LOOP
 13 NULL;
 14 DBMS_OUTPUT.PUT_LINE(X);
 15 END LOOP;
 16 EXIT WHEN CUR_1%NOTFOUND;
 17 END LOOP;
 18 CLOSE CUR_1;
 19
 20 END;
 21 /
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9

PL/SQL 过程已成功完成。

SQL> SPOOL OFF

[解决办法]

exit when all_contacts_cur%notfound;
改为:
exit when v_id.count=0;


[解决办法]
你循环退出条件不对,若用notfound的话,若每次取10条记录,而最后只剩下5条记录,fetch后,notfound将标记为true,很显然还是有数据的,可以通过楼上说的exit when
 v_id.count=0; 解决

慢慢学习吧
[解决办法]

探讨
你循环退出条件不对,若用notfound的话,若每次取10条记录,而最后只剩下5条记录,fetch后,notfound将标记为true,很显然还是有数据的,可以通过楼上说的exit when
v_id.count=0; 解决

慢慢学习吧

热点排行