Oracle游标的最后一条记录重复显示,如何去掉最后一条的'->'符号?
解决Oracle PL/SQL游标最后一行重复显示的问题
嘿,这个问题我太熟啦!你看到的重复的4,根源在于你循环结束后额外打印的那行代码,加上原来的fetch判断时机没处理好。咱们先拆解下你原代码的执行流程,你就明白为啥会重复了:
- 第一次
fetch拿到1,ch%notfound是false,打印1-> - 第二次
fetch拿到2,打印2-> - 第三次
fetch拿到3,打印3-> - 第四次
fetch拿到4,打印4-> - 第五次
fetch,游标已经没有数据了,ch%notfound变成true,退出循环 - 但此时
v_ch里还存着最后一次fetch到的4,所以你最后那句dbms_output.put_line(LPAD(' ',5)||v_ch.n)又把4打了一遍,就出现重复了!
接下来给你几个靠谱的解决办法,从简单到灵活都有:
方法一:用PL/SQL游标FOR循环(最推荐)
PL/SQL的游标FOR循环会自动帮你处理游标的打开、遍历和关闭,逻辑清晰还不容易出错。我们可以先拿到总记录数,然后用%rowcount判断当前是不是最后一行:
declare cursor ch is select 1 as n from dual union select 2 from dual union select 3 from dual union select 4 from dual; v_total number; begin -- 先获取游标结果集的总记录数 select count(*) into v_total from (select * from ch); -- 用FOR循环遍历游标 for v_ch in ch loop if ch%rowcount < v_total then -- 不是最后一行,打印带->的格式 dbms_output.put_line(LPAD(' ',5)||v_ch.n || '->'); else -- 最后一行,直接打印数字 dbms_output.put_line(LPAD(' ',5)||v_ch.n); end if; end loop; end; /
方法二:修正原有的LOOP-FETCH逻辑
如果你想保留原来的手动游标操作,调整fetch的顺序,先判断下一行是否存在,来决定当前行要不要加->:
declare cursor ch is select 1 as n from dual union select 2 from dual union select 3 from dual union select 4 from dual; v_ch ch%rowtype; v_current number; begin open ch; -- 先取第一行数据 fetch ch into v_ch; while ch%found loop -- 保存当前行的数值 v_current := v_ch.n; -- 尝试取下一行 fetch ch into v_ch; if ch%found then -- 下一行存在,说明当前行不是最后一行,打印带-> dbms_output.put_line(LPAD(' ',5)||v_current || '->'); else -- 下一行不存在,当前行是最后一行,直接打印 dbms_output.put_line(LPAD(' ',5)||v_current); end if; end loop; close ch; end; /
方法三:用BULK COLLECT把数据存入集合再处理
如果数据量不大,也可以一次性把所有数据取到集合里,然后遍历集合判断最后一个元素:
declare -- 定义存储数字的集合类型 type num_table is table of number; v_num_list num_table; begin -- 一次性把游标结果存入集合 select n bulk collect into v_num_list from ( select 1 as n from dual union select 2 from dual union select 3 from dual union select 4 from dual ); -- 遍历集合 for i in 1..v_num_list.count loop if i < v_num_list.count then dbms_output.put_line(LPAD(' ',5)||v_num_list(i) || '->'); else dbms_output.put_line(LPAD(' ',5)||v_num_list(i)); end if; end loop; end; /
这三种方法都能解决你的问题,其中方法一的FOR循环是PL/SQL里处理游标的最佳实践,代码最简洁也最不容易出错。
内容的提问来源于stack exchange,提问作者Dumitru Gutu
相关产品推荐
相关产品推荐

