I have this table informationvalues with the contents:
Now I create a procedure where I need to input a date parameter which should output line the correct attr
with given price
. If the date doesn’t exist the latest date should be selected.
The solution table for to_date('01-jan-19')
would look like this:
This would be then output line in the procedure.
Should I select to correct tuple and output line it or would it be best to just bulk collect everything and then check in a for loop with an if statement what tuple I need to display.
What I have so far:
A select statement with the tuples I am looking for:
create or replace procedure print_inf_value(closingDate Date) is cursor d1 (closingDate Date) is select t.attr, t.dateOfValue, t.price from ( select i.*, row_number() over ( partition by attr order by case when dateOfValue = closingdate then 1 else 2 end, dateOfValue desc ) rn from InformationValues i ) t where t.rn = 1; BEGIN dbms_output.put_line('Information Value '); dbms_output.put_line('--------------------------------'); FOR d1_rec IN d1 LOOP dbms_output.put_line(d1_rec.attr || ' ' || d1_rec.price ); END LOOP; END;
Or a procedure where I bulk collect everything and then I need to sort out what tuple I need:
create or replace procedure print_inf_value(closingDate Date) is TYPE d1 IS TABLE OF informationvalues%rowtype; emps d1; begin select * bulk collect into emps from informationvalues; FOR i IN 1 .. emps.COUNT LOOP if emps(i).dateofvalue = closingDate then dbms_output.put_line(emps(i).attr || ' ' || emps(i).price ); /*else*/ end if; END LOOP; END;
Both are not working right, so what am I missing to display tuple with the correct date.
Advertisement
Answer
Please try:
CREATE OR REPLACE PROCEDURE print_inf_value (closingDate DATE) IS BEGIN DBMS_OUTPUT.put_line (RPAD ('ATTR', 20) || RPAD ('PRICE', 20)); FOR o IN (select attr, trim(case when price < 1 then to_char(price,90.9) else to_char(price) end) price from ( select attr, price, dateofvalue, row_number() over (partition by attr order by dateofvalue desc) rn from informationvalues ) i where dateofvalue = closingdate or (rn = 1 and not exists (select 1 from informationvalues iv where iv.attr = i.attr and dateofvalue = closingdate) ) ) LOOP DBMS_OUTPUT.put_line (RPAD (o.attr, 20) || RPAD ( o.price, 20)); END LOOP; END;
Sample execution:
set serveroutput on; begin print_inf_value(date'2019-01-01'); end;
Output:
ATTR PRICE age 2 electronics 0.5 gender 3 hobbies 0.5 homeAddress 7 maritalStatus 1 mobilePhone 5 musicTaste 0.1 socialContacts 1