Oracle Последние Записи из Курсора - PullRequest
0 голосов
/ 15 мая 2018

У меня есть следующий кусок кода.Для последней строки курсора мне не нужно печатать символ «->».Если вы выполните запрос, вы увидите, что четвертая запись отображается дважды

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;

результат

 1->
 2->
 3->
 4->
 4

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Вы можете изменить курсор, чтобы определить положение каждой строки; без какой-либо информации о заказе это немного неуклюже:

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.

В этом примере столбец c равен нулю для последней возвращенной строки; поэтому в выходных данных используется выражение case, которое показывает стрелку только в том случае, если она больше нуля, т. е. все, кроме последней строки.

С реальным запросом вы могли бы просто добавить столбец к текущему набору результатов, используя row_number() over (order by <something> desc, что сделало бы последнюю строку # 1, и вместо этого вы могли бы основывать логику отображения на этом. Тебе, вероятно, тоже не понадобится подзапрос. Мы не видим ваш реальный запрос, поэтому можем только догадываться, как его лучше всего применить.

0 голосов
/ 15 мая 2018

Решение PL / SQL

Это будет работать, только немного сдвинув, когда печатать стрелки / переводы строк:

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;
/

Решение SQL

КонечноВы можете сгенерировать стрелку также в 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;
/

Или даже:

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
);

Это работает, только если ваша строка не достигнет ограничения длины VARCHAR2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...