PL / SQL процедура для вывода строки заданной даты, если она не существует, должна быть указана самая поздняя дата - PullRequest
1 голос
/ 24 марта 2020

У этой таблицы есть информационные значения с содержанием: enter image description here

Теперь я создаю процедуру, в которой мне нужно ввести параметр даты, который должен вывести строку правильного значения attr с учитывая price. Если дата не существует, следует выбрать самую последнюю дату.

Таблица решений для to_date('01-jan-19') будет выглядеть следующим образом:

enter image description here

Это будет тогда строка вывода в процедуре.

Должен ли я выбрать исправление кортежа и строки вывода или лучше будет просто собрать все подряд, а затем зарегистрировать a для l oop с оператор if, какой кортеж мне нужно отобразить.

То, что у меня есть до сих пор:

Оператор select с кортежами, которые я ищу:

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;

Или процедура, где я собираю все вместе, а затем мне нужно разобраться, какой кортеж мне нужен:

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;

Оба не работают правильно, так что мне не хватает, чтобы отобразить кортеж с правильной датой.

1 Ответ

1 голос
/ 24 марта 2020

Пожалуйста, попробуйте:

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;

Пример исполнения:

set serveroutput on;

begin
    print_inf_value(date'2019-01-01');
end;

Выход:

ATTR                PRICE               
age                 2                   
electronics         0.5               
gender              3                   
hobbies             0.5               
homeAddress         7                   
maritalStatus       1                   
mobilePhone         5                   
musicTaste          0.1               
socialContacts      1        
...