简体   繁体   中英

Procedure for generating monthly business report

I am trying to write a procedure the generates a monthly business report. I need to show the total number of business rentals and the CarRentalSites that have business rentals in that month. Only months with business rentals should be displayed and The ordering of months should be from the earliest to the latest and the ordering of CarRentalSites should be by CarRentalSiteName attribute.

I wrote the following to do this

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;
    /   

It gives me an output, but not whats expected I need help fixing it. My output vs expected is this

---- 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

These are the table and data files to be used

Data file Tables file

The problem seems to me that your manual control of the fetch loop means you're losing data. It's simpler and safer to let Oracle control it:

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;
/   

There are things about your code I would do differently but I have tried to change only the things which are responsible for producing the wrong results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM