8. VEHICLE_PARTS
3.1
CREATE OR REPLACE FUNCTION INVOICETOTAL( --- This function will apply to
InvoiceTotal
I_IN_ID INVOICE.IN_ID%TYPE) --- the customer bill Return Number
RETURN NUMBER
IS
V_INVOICE_TOTAL INVOICE.TOTAL%TYPE;
BEGIN
SELECT SUM(LABOUR_COST+SET_PRICE+P_PRICE) --- The select statement will
sum labour cost, service price and part price
INTO V_INVOICE_TOTAL
FROM SERVICE,SERVICE_TYPE,PARTS,STOCK,SERVICE_STOCK --- will retrieve
details from this table
WHERE SERVICE_TYPE.SET_ID=SERVICE.SET_ID --- join tables together using
thier primary key
AND PARTS.P_ID=STOCK.P_ID
AND STOCK.ST_ID=SERVICE_STOCK.ST_ID
AND SERVICE.SER_ID=SERVICE_STOCK.SER_ID
AND SERVICE.SER_ID = I_IN_ID;
RETURN V_INVOICE_TOTAL; --- returns v_invoice_total back to procedure
END ;
/
9. CREATE OR REPLACE PROCEDURE POP_AMOUNTOTAL --- creat procedure to populate
AmountTotal
AS
CURSOR C_INVOICE --- cursor that holds the select statement
IS
SELECT SER_ID --- create a select statment
FROM SERVICE;
-- SELECT IN_ID
-- FROM INVOICE;
V_IN_ID INVOICE.IN_ID%TYPE; --- declare variables
V_INVOICE_TOTAL INVOICE.TOTAL%TYPE;
BEGIN
OPEN C_INVOICE;
LOOP --- will execute sequence of statement
FETCH C_INVOICE INTO V_IN_ID; --- fetches the invoice into the
variable V_IV_ID
EXIT WHEN C_INVOICE%NOTFOUND; --- exit loop if condition is true
V_INVOICE_TOTAL := INVOICETOTAL(V_IN_ID); /* calls function, with SER_ID
*/
DBMS_OUTPUT.PUT_LINE('TOTAL AMOUNT IS :'|| TO_CHAR(V_INVOICE_TOTAL));
-- UPDATE INVOICE --- Update the invoice total
-- SET TOTAL=V_INVOICE_TOTAL
-- WHERE IN_ID=V_IN_ID;
END LOOP;
DBMS_OUTPUT.PUT_LINE('TOTAL = ' || TO_CHAR(V_INVOICE_TOTAL));
CLOSE C_INVOICE;
END;
/
10. 3.2. CREATE OR REPLACE TRIGGER LIMIT_BRANCH_TO_10_SERVICE --- create a
before trigger to check service
BEFORE UPDATE OR INSERT ON SERVICE
FOR EACH ROW
DECLARE
SERVICECOUNT NUMBER; --- declare variables
MAX_SERVICE NUMBER := 10;
BEGIN
SELECT COUNT(*) --- The select statement will count number of
INTO SERVICECOUNT --- vehicle serviced in a particular branch
FROM SERVICE --- statement count all from service table
WHERE S_DATE = :NEW.S_DATE
AND B_ID = :NEW.B_ID;
IF SERVICECOUNT <= MAX_SERVICE THEN --- will be raised when above if
statment equals true
RAISE_APPLICATION_ERROR (-20000,'BRANCH_' ||:NEW.B_ID || ' IS FULL
FOR SERVICES. PLEASE TRY ANOTHER BRANCH');
END IF;
END;
/
11. 3.3.
CREATE OR REPLACE TRIGGER CHECK_STOCK --- CREATE A TRIGGER TO CHECK_STOCK
BEFORE INSERT OR UPDATE OF QINS,MOH ON STOCK
FOR EACH ROW
DECLARE
CURSOR C_STK IS --- CREATE A CURSOR WITH THE
SELECT STATEMENT BELOW
SELECT S_NAME,SU_NAME
FROM STAFF E, SUPPLIERS S, BRANCH B, BRANCH_SUPPLIERS A --- STATEMENT
FETCHES STAFF NAME AND SUPPLIER NAME
WHERE E.S_ID=:new.S_ID
AND B.B_ID=:new.B_ID
AND S.SU_ID = A.SU_ID;
V_S_N STAFF.S_NAME%TYPE;
V_SU_N SUPPLIERS.SU_NAME%TYPE;
BEGIN
OPEN C_STK; --- opens cursor and populates
FETCH C_STK INTO V_S_N,V_SU_N; --- variables V_S_N and V_SU_N
IF:NEW.QINS<= :NEW.MOH THEN --- checks newly inserted/updated stock
quantity against minimum stock
:NEW.REORDER := 'YES'; --- if stock quantity lower than
minimum stock then display the msg below
DBMS_OUTPUT.PUT_LINE('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');---
message will display staff name and
DBMS_OUTPUT.PUT_LINE(V_S_N||' RE-ORDER STOCK FOR '|| :NEW.ST_ID||' FROM
'||V_SU_N); --- supplier name for that stock
DBMS_OUTPUT.PUT_LINE('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
ELSE
:NEW.REORDER :='NO'; --- if stock quantity higher than
minimum stock then display the msg below
DBMS_OUTPUT.PUT_LINE('XXXXXXXXXXXXXXXXXXXXXXXXXXXX');
DBMS_OUTPUT.PUT_LINE('STOCK LEVEL GOOD FOR '|| :NEW.ST_ID);
DBMS_OUTPUT.PUT_LINE('XXXXXXXXXXXXXXXXXXXXXXXXXXXX');
END IF;
END;
/
12. Below is the stock quantity in stock and minimum in hand.
After the trigger is created, stock ST81 is updated to be lower than minimum in hand, and the
message display below.
The table above shows which stock needs to be reordered.
13. When the stock quantity is above the minimum stock, the message above display for that stock.
The minimum quantity in stock table above, displays message when it’s updated
INTEGRITY CONSTRAINTS
4.1. Customer gender should be recorded as ‘M’ or ‘F’.
ALTER TABLE CUSTOMER ADD CONSTRAINT GENDER CHECK (C_GENDER IN ('M','F'));
4.2. The Supplier’s name must be Unique and not null.
ALTER TABLE SUPPLIERS ADD CONSTRAINT SU_NAME UNIQUE (SU_NAME) MODIFY
SU_NAME NOT NULL;
14. 4.3. Implement at least one table that demonstrate primary and foreign key constraints using
the ALTER TABLE command.
ALTER TABLE CITY ADD PRIMARY KEY (CITY_ID) ADD FOREIGN KEY (COUNTRY_ID)
REFERENCES COUNTRY (COUNTRY_ID);
END USER QUESTIONS
4.4 Can you list all customers’ details?
SELECT * FROM CUSTOMER;
4.5 List all the customers, their car details in for a service and the mechanic who made the
booking.
SELECT
A.C_NO,D.V_ID,A.V_MAKE,A.V_MODEL,A.CURRENT_MILEAGE,D.S_ID_BK,D.SER_ID
FROM SERVICE D,CUSTOMER C,STAFF B,VEHICLE A
WHERE A.C_NO=C.C_NO
AND D.V_ID=A.V_ID
AND D.S_ID_BK=B.S_ID;
15. 4.6. List by branch the number of cars booked in for service at each branch order by date.
SELECT C.B_ID,B.NAME,C.V_ID,A.V_MAKE,C.SER_ID,C.S_DATE,COUNT(*)AS"NUMBER OF
VEHICLES"
FROM SERVICE C,BRANCH B,VEHICLE A
WHERE C.B_ID=B.B_ID
AND C.V_ID=A.V_ID
GROUP BY C.B_ID,B.NAME,C.V_ID,A.V_MAKE,C.SER_ID,C.S_DATE
ORDER BY S_DATE;
4.7. Can you list all the sub-parts that go into the Vauxhall Astra’s engine and their individual
prices?
SELECT DISTINCT P_NAME,P_PRICE,V_MODEL,V_MAKE
FROM PARTS, VEHICLE, SUBPARTS, VEHICLE_PARTS
WHERE PARTS.P_ID=VEHICLE_PARTS.P_ID
AND VEHICLE.V_ID=VEHICLE_PARTS.V_ID
AND PARTS.P_ID=SUBPARTS.PART2
AND VEHICLE.V_MAKE='VAUXHALL'
AND VEHICLE.V_MODEL='ASTRA';