PL SQL 用光标打印
PL SQL print with cursor
我有一个 table,其中有一列用于类别、日期和价格。像这样:
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 次。
当然会,就像您告诉它的那样。您正在循环 10 次,并且 - 对于每次循环迭代 - 您 open/close 相同的光标并打印它获取的值。
你应该做的是遍历游标本身;此外,正如您所说,那应该是两个嵌套循环。像这样的东西(伪代码使它更清楚):
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>
我有一个 table,其中有一列用于类别、日期和价格。像这样:
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 次。
当然会,就像您告诉它的那样。您正在循环 10 次,并且 - 对于每次循环迭代 - 您 open/close 相同的光标并打印它获取的值。
你应该做的是遍历游标本身;此外,正如您所说,那应该是两个嵌套循环。像这样的东西(伪代码使它更清楚):
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>