You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle游标的最后一条记录重复显示,如何去掉最后一条的'->'符号?

解决Oracle PL/SQL游标最后一行重复显示的问题

嘿,这个问题我太熟啦!你看到的重复的4,根源在于你循环结束后额外打印的那行代码,加上原来的fetch判断时机没处理好。咱们先拆解下你原代码的执行流程,你就明白为啥会重复了:

  1. 第一次fetch拿到1,ch%notfound是false,打印1->
  2. 第二次fetch拿到2,打印2->
  3. 第三次fetch拿到3,打印3->
  4. 第四次fetch拿到4,打印4->
  5. 第五次fetch,游标已经没有数据了,ch%notfound变成true,退出循环
  6. 但此时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:59:38