I have the following piece of code. For the last line of the cursor I don't need to print the '->' symbol. If you run the query you can see that the fourth record is displayed twice
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;
begin
open ch;
loop
fetch ch into v_ch;
exit when ch%notfound;
dbms_output.put_line(LPAD(' ',5)||v_ch.n || '->');
end loop;
dbms_output.put_line(LPAD(' ',5)||v_ch.n);
close ch;
end;
result
1->
2->
3->
4->
4
This will work, just a bit of shifting when to print arrows / newlines:
set serveroutput on
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;
first boolean := true;
begin
open ch;
loop
fetch ch into v_ch;
exit when ch%notfound;
-- Append the arrow after all rows except the first and implicitly (because of the
-- above exit) except the last, too
if not first then
dbms_output.put_line('->');
end if;
first := false;
-- Use put here, instead of put_line, such that the arrow will be appended on the
-- same line as the value on the next loop iteration
dbms_output.put(LPAD(' ',5)||v_ch.n);
end loop;
-- Finally, print a newline character
dbms_output.put_line('');
close ch;
end;
/
Of course, you can generate the arrow also in SQL:
set serveroutput on
declare
cursor ch is
select n, case
when row_number() over (order by n) =
count(*) over () then '' else '->' end arrow
from (
select 1 as n from dual union
select 2 from dual union
select 3 from dual union
select 4 from dual
) t;
v_ch ch%rowtype;
begin
open ch;
loop
fetch ch into v_ch;
exit when ch%notfound;
dbms_output.put_line(LPAD(' ',5)||v_ch.n||v_ch.arrow);
end loop;
dbms_output.put_line('');
close ch;
end;
/
Or even:
select listagg(n, '->' || chr(10)) within group (order by n)
from (
select 1 as n from dual union
select 2 from dual union
select 3 from dual union
select 4 from dual
);
This only works if your string won't reach the VARCHAR2
length limit
You could modify the cursor to identify the position of each row; without any ordering information that's a bit clunky:
declare
cursor ch is
select n, count(*) over () - rownum as c from (
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;
begin
open ch;
loop
fetch ch into v_ch;
exit when ch%notfound;
dbms_output.put_line(LPAD(' ',5)||v_ch.n || case when v_ch.c > 0 then '->' end);
end loop;
close ch;
end;
/
1->
2->
3->
4
PL/SQL procedure successfully completed.
In this example the c
column is zero for the final row returned; so the output uses a case expression to only show the arrow when that is greater than zero - ie all except that last row.
With a real query you might be able to just add a column to the current result set using row_number() over (order by <something> desc
, which would make the last row #1, and you could base the display logic on that instead. You probably wouldn't need a subquery then either. We can't see your real query though so can only guess how it can best be applied.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.