首页 > 解决方案 > 带有光标的 PL SQL 打印

问题描述

我有一个表格,其中包含类别、日期和价格列。像这样:

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

所以它只打印一个类别 + 正确的价格(从正确的日期开始)但 10 次。

标签: sqloracleplsqlcursor

解决方案


当然可以,正如你所说的那样。您循环了 10 次,并且 - 对于每次循环迭代 - 您打开/关闭相同的光标并打印它获取的值。

你应该做的是循环游标本身;此外,正如您所说,那应该是两个嵌套循环。像这样的东西(伪代码使其更清晰):

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>

推荐阅读