-------------------------------------------------------------------------------- -- -- SQL schema definition of the Southern Technical Institute of Natural Knowledge -- student records database, as specified in INFO 214 Assignment 1. -- -- Schema written for Oracle11g. -- -------------------------------------------------------------------------------- -- -- NOTE: this script will drop any existing tables automatically so -- that they can be re-created. -- DECLARE TYPE Table_Names_T IS TABLE OF VARCHAR2 ( 32 ) ; Table_Names Table_Names_T := Table_Names_T ( 'STAFF', 'SERVICE', 'OTHER', 'SALES', 'CUSTOMER', 'CAR', 'FEATURE', 'CAR_FEATURE', 'WARRANTY', 'PURCHASE', 'SALE' ) ; Table_Nonexistent EXCEPTION; PRAGMA Exception_Init ( Table_Nonexistent, -942 ) ; BEGIN FOR T IN Table_Names.FIRST..Table_Names.LAST LOOP BEGIN EXECUTE IMMEDIATE 'DROP TABLE ' || Table_Names ( T ) || '' || ' CASCADE CONSTRAINTS'; EXCEPTION -- We only want to suppress exceptions due to the table not existing. That's -- -942: ORA-00942: table or view does not exist -- Other exceptions, such as being unable to drop a table because of locks(!), should not be trapped, so that the user sees an error message. WHEN Table_Nonexistent THEN DBMS_Output.Put_Line ( SQLCODE || ': ' || SQLERRM || ': Ignoring nonexistent table ' || T ) ; -- null; END; END LOOP; END; / -------------------------------------------------------------------------------- -- -- Staff table -- -- CREATE SEQUENCE Staff_ID_Seq START WITH 1000 MAXVALUE 9999; CREATE TABLE Staff ( Staff_ID NUMBER(4), Firstname VARCHAR2(50) NOT NULL, Lastname VARCHAR2(50) NOT NULL, Address VARCHAR2(150) NOT NULL, -- Use VARCHAR2 for phone numbers in order to retain leading zeros. -- Format: leading 0 plus 1-digit area code plus up to 9 digits, e.g., -- 02187654321; longer if we allow punctuation to be included. -- (http://en.wikipedia.org/wiki/Telephone_numbers_in_New_Zealand) Phone VARCHAR2(11) NOT NULL, Date_Hired DATE DEFAULT SYSDATE NOT NULL, Date_of_Birth DATE NOT NULL, -- CONSTRAINT Staff_Valid_Age CHECK ( ( Date_Hired - TO_YMINTERVAL( '18-0' ) ) >= Date_of_Birth ), -- CONSTRAINT Staff_PK PRIMARY KEY ( Staff_ID ) ); -------------------------------------------------------------------------------- -- -- Service table -- CREATE TABLE Service ( Staff_ID NUMBER(4), Hourly_Rate NUMBER(5,2) NOT NULL CONSTRAINT Service_Hourly_Rate_Min CHECK ( Hourly_Rate >= 13.50 ), Total_Hours NUMBER(6,2) DEFAULT 0 NOT NULL CONSTRAINT Service_Total_Hours_Range CHECK ( Total_Hours BETWEEN 0 AND 4500 ) CONSTRAINT Service_Total_Hours_Quarters CHECK ( TRUNC( Total_Hours * 4 ) = ( Total_Hours * 4 ) ), -- CONSTRAINT Service_PK PRIMARY KEY ( Staff_ID ), CONSTRAINT Service_FK_to_Staff FOREIGN KEY ( Staff_ID ) REFERENCES Staff ON DELETE CASCADE ); -------------------------------------------------------------------------------- -- -- Other table -- CREATE TABLE Other ( Staff_ID NUMBER(4), Salary NUMBER(8,2) NOT NULL CONSTRAINT Other_Salary_Min CHECK ( Salary >= 28080 ), -- CONSTRAINT Other_PK PRIMARY KEY ( Staff_ID ), -- CONSTRAINT Other_FK_to_Staff FOREIGN KEY ( Staff_ID ) REFERENCES Staff ON DELETE CASCADE ); -------------------------------------------------------------------------------- -- -- Sales table -- CREATE TABLE Sales ( Staff_ID NUMBER(4), On_Commission CHAR(1) DEFAULT 'N' NOT NULL CONSTRAINT Sales_Valid_On_Commission CHECK ( On_Commission IN ( 'Y', 'N' ) ), Commission_Rate NUMBER(3,2) NOT NULL CONSTRAINT Sales_Valid_Commission_Rate CHECK ( Commission_Rate BETWEEN 0.00 AND 0.30 ), -- We can't make Gross_Earnings a computed column, because it requires data -- from other tables. Gross_Earnings NUMBER(8,2) NOT NULL CONSTRAINT Sales_Valid_Gross_Earnings CHECK ( Gross_Earnings >= 0.00 ), -- CONSTRAINT Sales_Check_Commission CHECK ( ( ( On_Commission = 'N' ) AND ( Commission_Rate = 0 ) ) OR ( ( On_Commission = 'Y' ) AND ( Commission_Rate > 0 ) ) ), -- CONSTRAINT Sales_PK PRIMARY KEY ( Staff_ID ), -- CONSTRAINT Sales_FK_to_Staff FOREIGN KEY ( Staff_ID ) REFERENCES Staff ON DELETE CASCADE ); -------------------------------------------------------------------------------- -- -- Customer table -- -- CREATE SEQUENCE Customer_ID_Seq START WITH 100000 MAXVALUE 999999; CREATE TABLE Customer ( Customer_ID NUMBER(6), Firstname VARCHAR2(50) NOT NULL, Lastname VARCHAR2(50) NOT NULL, Address VARCHAR2(150) NOT NULL, Phone VARCHAR2(11) NOT NULL, Email VARCHAR2(50), -- optionally CHECK format if desired Credit_Rating CHAR(1) CONSTRAINT Customer_Valid_Credit_Rating CHECK ( Credit_Rating IN ( 'A', 'B', 'C', 'D' ) ), Comments CLOB, -- CONSTRAINT Customer_PK PRIMARY KEY ( Customer_ID ) ); -------------------------------------------------------------------------------- -- -- Car table -- CREATE TABLE Car ( VIN CHAR(17), -- optionally CHECK format if desired Registration VARCHAR2(6) NOT NULL, Make VARCHAR2(20) NOT NULL, Model VARCHAR2(30) NOT NULL, Year NUMBER(4) NOT NULL CONSTRAINT Car_Valid_Year CHECK ( Year >= 1995 ), Colour VARCHAR2(20) NOT NULL, Odometer NUMBER(7,1) NOT NULL CONSTRAINT Car_Valid_Odometer CHECK ( Odometer BETWEEN 0.0 AND 999999.9 ), First_Registered DATE NOT NULL, Last_Serviced DATE, Price NUMBER(6) NOT NULL CONSTRAINT Car_Valid_Price CHECK ( Price >= 0 ), Flat_Rate NUMBER(4) NOT NULL CONSTRAINT Car_Valid_Flat_Rate CHECK ( Flat_Rate > 0 ), -- -- Not specified, but makes sense. Bonus marks! CONSTRAINT Car_Valid_Service_Date CHECK ( Last_Serviced >= First_Registered ), -- CONSTRAINT Car_PK PRIMARY KEY ( VIN ) ); -------------------------------------------------------------------------------- -- -- Feature table -- CREATE TABLE Feature ( Feature_Code CHAR(5), Description VARCHAR2(100) NOT NULL, -- CONSTRAINT Feature_PK PRIMARY KEY ( Feature_Code ) ); -------------------------------------------------------------------------------- -- -- Car_Feature table -- CREATE TABLE Car_Feature ( VIN CHAR(17), Feature_Code CHAR(5), -- CONSTRAINT Car_Feature_PK PRIMARY KEY ( VIN, Feature_Code ), -- CONSTRAINT Car_Feature_FK_to_Car FOREIGN KEY ( VIN ) REFERENCES Car ON DELETE CASCADE, CONSTRAINT Car_Feature_FK_to_Feature FOREIGN KEY ( Feature_Code ) REFERENCES Feature ON DELETE CASCADE ); -------------------------------------------------------------------------------- -- -- Warranty table -- CREATE TABLE Warranty ( W_Code CHAR(1), Max_Age NUMBER(1), Max_KM NUMBER(6), Duration NUMBER(1), Distance NUMBER(4), Notes VARCHAR2(250), -- CONSTRAINT Warranty_PK PRIMARY KEY ( W_Code ) ); -- INSERT INTO Warranty ( W_Code, Max_Age, Max_KM, Duration, Distance, Description ) VALUES ( 'A', 4, 50000, 3, 5000, 'Category A motor vehicle' ); -- INSERT INTO Warranty ( W_Code, Max_Age, Max_KM, Duration, Distance, Description ) VALUES ( 'B', 6, 75000, 2, 3000, 'Category B motor vehicle' ); -- INSERT INTO Warranty ( W_Code, Max_Age, Max_KM, Duration, Distance, Description ) VALUES ( 'C', 8, 100000, 1, 1500, 'Category C motor vehicle' ); -- INSERT INTO Warranty ( W_Code, Max_Age, Max_KM, Duration, Distance, Description ) VALUES ( 'D', NULL, NULL, 0, 0, 'Category D motor vehicle' ); -------------------------------------------------------------------------------- -- -- Purchase table -- -- CREATE SEQUENCE Purchase_ID_Seq START WITH 10000000 MAXVALUE 99999999; CREATE TABLE Purchase ( Purchase_ID NUMBER(8), Purchase_Date DATE NOT NULL, Details CLOB NOT NULL, Amount NUMBER(6) NOT NULL CONSTRAINT Purchase_Valid_Amount CHECK ( Amount >= 0 ), VIN CHAR(17) NOT NULL, Customer_ID NUMBER(6) NOT NULL, Salesrep_ID NUMBER(4) NOT NULL, -- CONSTRAINT Purchase_PK PRIMARY KEY ( Purchase_ID ), -- CONSTRAINT Purchase_FK_to_Car FOREIGN KEY ( VIN ) REFERENCES Car, CONSTRAINT Purchase_FK_to_Customer FOREIGN KEY ( Customer_ID ) REFERENCES Customer, CONSTRAINT Purchase_FK_to_Sales FOREIGN KEY ( Salesrep_ID ) REFERENCES Sales ); -------------------------------------------------------------------------------- -- -- Sale table -- -- CREATE SEQUENCE Sale_ID_Seq START WITH 10000000 MAXVALUE 99999999; CREATE TABLE Sale ( Sale_ID NUMBER(8), Sale_Date DATE NOT NULL, Details CLOB NOT NULL, Amount NUMBER(6) NOT NULL CONSTRAINT Sale_Valid_Amount CHECK ( Amount >= 0 ), VIN CHAR(17) NOT NULL, Customer_ID NUMBER(6) NOT NULL, Salesrep_ID NUMBER(4) NOT NULL, W_Code CHAR(1) NOT NULL, Tradein_ID NUMBER(8), -- CONSTRAINT Sale_PK PRIMARY KEY ( Sale_ID ), -- CONSTRAINT Sale_FK_to_Car FOREIGN KEY ( VIN ) REFERENCES Car, CONSTRAINT Sale_FK_to_Customer FOREIGN KEY ( Customer_ID ) REFERENCES Customer, CONSTRAINT Sale_FK_to_Warranty FOREIGN KEY ( W_Code ) REFERENCES Warranty, CONSTRAINT Sale_FK_to_Sales FOREIGN KEY ( Salesrep_ID ) REFERENCES Sales, CONSTRAINT Sale_FK_to_Purchase FOREIGN KEY ( Tradein_ID ) REFERENCES Purchase ); -------------------------------------------------------------------------------- -- -- Here endeth the schema. -- --------------------------------------------------------------------------------