PL SQL печать с курсором - PullRequest
0 голосов
/ 22 марта 2020

У меня есть таблица с колонкой для категорий, даты и цены. Например:

group 1  - 03.03.2019 - 5.00
group 1  - 03.02.2018 - 4.00
group 2  - 05.05.2019 - 2.25
group 2  - 05.05.2018 - 1.00

Таким образом, в группе всегда есть (почти) две даты с двумя разными ценами. У меня есть оператор sql, который выбирает строку с ближайшей датой к указанной дате, но я не знаю, как напечатать их все курсором. Таким образом, выходные данные за 06.06.2019 должны выглядеть следующим образом:

group 1  - 03.03.2019 - 5.00
group 2  - 05.05.2019 - 2.25

Таким образом, он печатает только одну категорию ie + правильную цену (с правильной даты), но 10 раз.

1 Ответ

0 голосов
/ 22 марта 2020

Конечно, как вы и сказали. Вы зацикливаетесь 10 раз, и - для каждой итерации l oop вы открываете / закрываете один и тот же курсор и печатаете значения, которые он выбирает.

Что вам нужно сделать, это l oop через сам курсор; Более того, как вы говорите, это должны быть две вложенные петли. Примерно так (псевдокод, чтобы сделать его понятнее):

begin
  for cur_1 as (select whatever that makes the first cursor) loop
    for cur_2 as (select whatever that makes the second cursor) loop
      dbms_output.put_line(value from cur_1 || value from cur_2);
    end loop;
  end loop;
end;

Применяется к вашему коду:

Procedure print_inf_value (closingDate Date) is
begin
  for cur_1 as (select t.attr
                from informationvalues t
                where t.dateofValue <= closingDate
                  and not exists (select 1
                                  from informationvalues t1
                                  where t1.attr = t.attr 
                                    and t1.dateofValue <= closingDate 
                                    and t1.dateofValue > t.dateofValue
               )
  loop
    for cur_2 as (select t.price
                  from informationvalues t
                  where t.dateofValue <= closingDate
                    and not exists (select 1
                                    from informationvalues t1
                                    where t1.attr = t.attr 
                                      and t1.dateofValue <= closingDate 
                                      and t1.dateofValue > t.dateofValue
                 )
    loop
      dbms_output.put_line('Attr: ' || cur_1.attr || '    Price: ' || cur_2.price);
    end loop;
  end loop;
end;

Хотя, читая то, что вы на самом деле спросили, возможно, вы Я хотел бы взглянуть на следующий код, который несколько проще вашего:

Пример данных:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> select * From test order by grp, cdate;

       GRP CDATE           PRICE
---------- ---------- ----------
         1 03.02.2018          4
         1 03.03.2019          5
         2 05.05.2018          1
         2 05.05.2019       2,25

Процедура:

SQL> create or replace procedure print_inf_value (par_cdate in date)
  2  is
  3  begin
  4    for cur_r in (select a.grp, a.cdate, a.price
  5                  from test a
  6                  where (a.grp, a.cdate) in (select b.grp, max(b.cdate)
  7                                             from test b
  8                                             where b.cdate <= par_cdate
  9                                             group by b.grp
 10                                            )
 11                 )
 12    loop
 13      dbms_output.put_line(cur_r.grp ||' '|| cur_r.cdate ||' '|| cur_r.price);
 14    end loop;
 15  end;
 16  /

Procedure created.

Тестирование:

SQL> set serveroutput on;
SQL> exec print_inf_value(date '2019-01-01');
1 03.02.2018 4
2 05.05.2018 1

PL/SQL procedure successfully completed.

SQL>
...