0

I have been tasked to populate a table called Sales_Facts with a PL/SQL block but I return 0 results. The procedure is executed with out error and I run my script to populate my table but my SELECT COUNT script returns nothing. I cannot see what I am doing wrong.

Here's what I have:

CREATE TABLE Sales (
    sale_ID VARCHAR2(10) NOT NULL,
    salesperson_ID VARCHAR2(10) NOT NULL,
    cust_ID VARCHAR2(10) NOT NULL,
    sale_date DATE,
    VIN VARCHAR2(20) NOT NULL,
    mileage INT,
    vehicle_status VARCHAR2(15),
    gross_sale_price NUMBER(8,2) NOT NULL,
    PRIMARY KEY (sale_ID),
    CONSTRAINT FK_Customer_ID FOREIGN KEY (cust_ID) REFERENCES Customers(cust_ID),
    CONSTRAINT FK_VIN_ID FOREIGN KEY (VIN) REFERENCES Sale_Vehicles(VIN));


CREATE TABLE Times (
    sale_day DATE NOT NULL, --populated from Sales sale_date
    day_type VARCHAR2(50) NOT NULL, 
    PRIMARY KEY (sale_day));

CREATE TABLE Vehicles (
    vehicle_Code VARCHAR2(10),
    description VARCHAR2(100),
    PRIMARY KEY (vehicle_Code));

Vehicles is populated with this:

CREATE SEQUENCE veh_code_seq
    MINVALUE 1
    START WITH 1
    INCREMENT BY 1
    CACHE 20;
COMMIT;

--PL/SQL Block

SET SERVEROUTPUT ON
DECLARE
vehType VARCHAR2(50);
v_make OLTP_Vehicles.make%type;
v_model OLTP_Vehicles.model%type;

CURSOR v_type IS SELECT DISTINCT make, model FROM OLTP_Vehicles;
BEGIN
    OPEN v_type;
    LOOP
        FETCH v_type INTO v_make, v_model;
        vehType := v_make || ', ' || v_model;
        INSERT INTO Vehicles (vehicle_Code, description)
        VALUES (veh_code_seq.NEXTVAL, vehType);
        EXIT WHEN v_type%notfound;
    END LOOP;
    CLOSE v_type;
END;
/

CREATE TABLE Financing_Plans (
    plan_ID VARCHAR2(10) NOT NULL,
    institution VARCHAR2(25) NOT NULL,
    loan_type VARCHAR2(15) NOT NULL,
    percentage DECIMAL(4,2) NOT NULL,
    min_down NUMBER(8,2) NOT NULL,
    max_loan_amt NUMBER(8,2) NOT NULL,
    max_term INT NOT NULL,
    PRIMARY KEY (plan_ID));

CREATE TABLE Dealerships (
    dealer_ID VARCHAR2(5) NOT NULL,
    location VARCHAR(30) NULL,
    region_ID VARCHAR(5) NULL,
    street_address VARCHAR2(100) NOT NULL,
    city VARCHAR2(25) NOT NULL,
    state VARCHAR2(15) NOT NULL,
    zip VARCHAR2(5) NOT NULL,
    phone VARCHAR2(10) NOT NULL,
    sqft NUMERIC(8,2) NULL,
    opened_date DATE,
    manager VARCHAR2(100) NULL,
    district_ID VARCHAR2(5) NOT NULL,
    PRIMARY KEY (dealer_ID),
    CONSTRAINT UC_Dealership UNIQUE (dealer_ID,district_ID));

CREATE TABLE Sales_Facts (
    sale_day DATE NOT NULL,
    vehicle_Code VARCHAR2(10) NOT NULL, 
    plan_ID VARCHAR2(10) NOT NULL,
    dealer_ID VARCHAR2(5) NOT NULL,
    vehicles_sold NUMBER(8,2) NOT NULL,
    gross_sales_amt NUMBER(8,2) NOT NULL,
    CONSTRAINT PK_Sales_Facts PRIMARY KEY (sale_day, vehicle_Code, plan_ID, dealer_ID),
    CONSTRAINT FK_Sale_Day FOREIGN KEY(sale_day) References Times(sale_day),
    CONSTRAINT FK_Vehicle_Code FOREIGN KEY(vehicle_Code) References Vehicles(vehicle_Code),
    CONSTRAINT FK_Fin_Plan_ID FOREIGN KEY(plan_ID) References Financing_Plans(plan_ID),
    CONSTRAINT FK_Dealer_ID FOREIGN KEY(dealer_ID) References Dealerships(dealer_ID));

And here is my procedure that is not returning any results:

CREATE OR REPLACE PROCEDURE Populate_Sales_Facts
AS
    l_sale_day DATE;
    l_vehicle_Code VARCHAR2(10);
    l_plan_ID VARCHAR2(10);
    l_dealer_ID VARCHAR2(5);
    l_vehicles_sold NUMBER(8,2);
    l_gross_sales_amt NUMBER(8,2); 

    CURSOR c1 IS SELECT sale_day,vehicle_Code,fp.plan_ID,d.dealer_ID,
        COUNT (*) AS vehicles_sold,
        SUM (s.gross_sale_price) AS gross_sales_amt
    FROM Times t, Sales s, Financing_Plans fp, Dealerships d, Vehicles v
    WHERE t.sale_day = s.sale_date
    GROUP BY sale_day, vehicle_Code, fp.plan_ID, d.dealer_ID;

BEGIN
    OPEN c1;
    LOOP
      FETCH c1 INTO l_sale_day, l_vehicle_Code, l_plan_ID, l_dealer_ID, l_vehicles_sold, l_gross_sales_amt;
      EXIT WHEN c1%NOTFOUND;
      IF l_vehicles_sold <> 0 THEN
        INSERT INTO SALES_FACTS (sale_day,vehicle_Code,plan_ID,dealer_ID,vehicles_sold, gross_sales_amt)
        VALUES (l_sale_day,l_vehicle_Code,l_plan_ID,l_dealer_ID,l_vehicles_sold,l_gross_sales_amt);
    END IF;
    END LOOP;
CLOSE c1; 
END;
/

BEGIN
    Populate_Sales_Facts;
END;
/

I was given the fields to populate the Sales table and they cannot be changed per my requirements but I did fix my WHERE statement to pull sale_day from the Times table where equal to the sale_date in the Sales table because those are the only fields that linked. So I was able to get the table to populate but now instead of getting no more than 200 rows, I am getting 61065 rows of data. Here are my requirements: get every possible combination of the dimension tables’ primary keys and then the total vehicles sold and gross sales amount for each combination. If these values for Total_Vehicles_Sold and Gross_Sales_Amount for a combination are zero then don’t INSERT a row into the SALES_FACT table. Only insert rows for combinations of the four foreign key columns where there were some vehicles sold. Maybe I am just misunderstanding the task but I feel like I am getting too many rows now.

  • 1
    there are no COMMITs in your code, also have you tried adding some debug code in your loop, say a DBMS_OUTPUT.PUT_LINE(l_sale_day); to make sure your fetch is working as expected? you'll need to turn serveroutput on to see the dbms_output – thatjeffsmith Apr 16 '18 at 15:33
  • 1
    Are you sure `WHERE s.sale_ID = fp.plan_ID` is correct? You haven't shown the `Sales` table, or any data, but that doesn't seem like an obvious relationship. You should also consider using modern join syntax; and why are you using slow PL/SQL loops with single inserts instead of simple `insert...select...` statements? – Alex Poole Apr 16 '18 at 15:44
  • @Alex Poole What do you mean by modern join syntax? Are my joins not the conventional way to do it? I am still new to sql and pl/sql. – beginnerDeveloper Apr 16 '18 at 16:10
  • 1
    They're the older Oracle-specific syntax. See here for more details: https://stackoverflow.com/questions/18891148/oracle-joins-comparison-between-conventional-syntax-vs-ansi-syntax – kfinity Apr 16 '18 at 16:35
  • If you just run your select statement from cursor c1 by itself, do you get any results? Results where vehicles_sold is not 0? – kfinity Apr 16 '18 at 16:47
  • @kfinity I'm not sure WHERE-clause joins are specific to Oracle. – William Robertson Apr 17 '18 at 16:32
  • In your cursor `c1` (by the way, naming variables is generally a better system than numbering them) what is `t.sale_day`? I don't see any `t` in the `from` list. Where are the joins for `fp`, `d` and `v`? It seems odd that the `SALES` table does not record the dealer. – William Robertson Apr 17 '18 at 16:44
  • @WilliamRobertson thanks, you're right - "implicit join syntax" is still standard (ANSI SQL-92), it's just implicit *outer joins* which are non-standard across vendors. – kfinity Apr 17 '18 at 19:04

0 Answers0