#oracle #plsql
#Oracle #plsql
Вопрос:
Я пытаюсь написать процедуру, которая генерирует ежемесячный бизнес-отчет. Мне нужно показать общее количество арендованных бизнес-объектов и CarRentalSites, на которых есть бизнес-аренда за этот месяц. Должны отображаться только месяцы с арендой бизнеса, и порядок месяцев должен быть от самого раннего к последнему, а порядок сайтов CarRentalSites должен быть по атрибуту CarRentalSiteName.
Для этого я написал следующее
create or replace procedure MonthlyBusinessRentalsReport as
CURSOR d_cursor is
Select Extract(year from Rentals.RentalDate) as oYear, Extract(month from Rentals.RentalDate) as oMonth, Count(*) as t
from Rentals where Rentals.Status = 'BUSINESS'
Group By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate)
Order By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate);
d_res d_cursor%ROWTYPE;
CURSOR d_retail is
Select Extract(year from Rentals.RentalDate) as oYear, Extract(month from Rentals.RentalDate) as oMonth, CarRentalSite.CarRentalSiteName, numOfDays
from Rentals INNER JOIN CarRentalSite on Rentals.CarRentalSiteId=CarRentalSite.CarRentalSiteId where Rentals.Status='BUSINESS'
Group By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate), CarRentalSite.CarRentalSiteName, numOfDays
Order By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate), CarRentalSite.CarRentalSiteName, numOfDays;
d_res2 d_retail%ROWTYPE;
BEGIN
OPEN d_retail;
Fetch d_retail into d_res2;
for d_res in d_cursor loop
dbms_output.put_line('Total Business Rentals in ' || d_res.oYear || '-' || d_res.oMonth || ': ' || d_res.t);
dbms_output.put_line('In Car Rental Sites:');
loop
dbms_output.put_line('- ' || d_res2.CarRentalSiteName || ': ' || d_res2.numOfDays || ' days');
Fetch d_retail into d_res2;
exit when d_retail%NOTFOUND or d_res2.oYear != d_res.oYear or d_res2.oMonth != d_res.oMonth;
end loop;
end loop;
Close d_retail;
END MonthlyBusinessRentalsReport;
/
show errors;
BEGIN
MonthlyBusinessRentalsReport;
End;
/
Это дает мне результат, но не тот, который ожидался, мне нужна помощь в его исправлении.
Мой результат по сравнению с ожидаемым таков
---- Result of Procedure 2:
Total Business Rentals in 2018-1: 2
In Car Rental Sites:
- Hertz: 15 days
Expected:
Total Business Rentals in 2018-1: 2
In Car Rental Sites:
- Hertz: 36 days
---- Result of Procedure 2:
- Hertz: 21 days
Total Business Rentals in 2018-2: 2
In Car Rental Sites:
- Alamo: 10 days
Expected:
Total Business Rentals in 2018-2: 2
In Car Rental Sites:
- Alamo: 10 days
- Hertz: 14 days
---- Result of Procedure 2:
- Hertz: 14 days
Total Business Rentals in 2018-4: 1
In Car Rental Sites:
Expected:
Total Business Rentals in 2018-4: 1
In Car Rental Sites:
- Enterprise: 2 days
---- Result of Procedure 2:
- Enterprise: 2 days
Total Business Rentals in 2018-5: 3
In Car Rental Sites:
- Avis: 2 days
- Budget: 3 days
Expected:
Total Business Rentals in 2018-5: 3
In Car Rental Sites:
- Avis: 2 days
- Budget: 3 days
- Hertz: 25 days
---- Result of Procedure 2:
- Hertz: 25 days
Total Business Rentals in 2018-6: 1
In Car Rental Sites:
Expected:
Total Business Rentals in 2018-6: 1
In Car Rental Sites:
- Alamo: 10 days
Это таблица и файлы данных, которые будут использоваться
Комментарии:
1. Второй запрос содержит столбец
numOfDays
. Это должно быть каким-то образом агрегировано? Это выглядит неправильно.2. Да, я так считаю. Нам нужно добавить количество дней для каждой аренды. например, если есть две аренды, вам нужно добавить значение в таблицу для каждой
Ответ №1:
Мне кажется, проблема в том, что ваше ручное управление циклом выборки означает, что вы теряете данные. Проще и безопаснее позволить Oracle управлять этим:
create or replace procedure MonthlyBusinessRentalsReport as
BEGIN
for d_res in
(Select Extract(year from Rentals.RentalDate) as oYear
, Extract(month from Rentals.RentalDate) as oMonth
, Count(*) as t
from Rentals
where Rentals.Status = 'BUSINESS'
Group By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate)
Order By Extract(year from Rentals.RentalDate), Extract(month from Rentals.RentalDate)
)
loop
dbms_output.put_line('Total Business Rentals in ' || d_res.oYear || '-' || d_res.oMonth || ': ' || d_res.t);
dbms_output.put_line('In Car Rental Sites:');
for d_res2 in (
Select CarRentalSite.CarRentalSiteName
, sum(numOfDays) as numOfDays
from Rentals
INNER JOIN CarRentalSite on Rentals.CarRentalSiteId=CarRentalSite.CarRentalSiteId
where Rentals.Status='BUSINESS'
and Extract(year from Rentals.RentalDate) = d_res.oYear
and Extract(month from Rentals.RentalDate) = d_res.oMonth
group by CarRentalSite.CarRentalSiteName
Order By CarRentalSite.CarRentalSiteName
)
loop
dbms_output.put_line('- ' || d_res2.CarRentalSiteName || ': ' || d_res2.numOfDays || ' days');
end loop;
end loop;
END MonthlyBusinessRentalsReport;
/
В вашем коде есть вещи, которые я бы сделал по-другому, но я попытался изменить только те вещи, которые ответственны за получение неправильных результатов.
Комментарии:
1. Привет @APC спасибо за ваш ответ. Я запущу этот код со своей стороны и обновлю вас. Кстати, вам не удалось загрузить файлы так, как я их загрузил? Должен ли я загружать их другим способом?
2. Файлы загружаются на uploadfiles.io они зашифрованы и проверены на вирусы. Можете ли вы загрузить и просмотреть выходные данные вашего кода?