/* ================================================================================ ORACLE 19C - E-COMMERCE ORDER MANAGEMENT SYSTEM Complex Schema with Multiple Dependencies ================================================================================ This schema demonstrates: - Multiple base tables with PK/FK relationships - Sequences for auto-increment - Indexes (unique, composite, functional) - Views (simple and complex with aggregations) - Stored procedures with business logic - Packages (organization and reusability) - Triggers (automatic actions and data validation) - Table relationships and cascading constraints ================================================================================ */ -- ============================================================================ -- SEQUENCES -- ============================================================================ CREATE SEQUENCE seq_customers START WITH 1000 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_products START WITH 5000 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_orders START WITH 100000 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_order_items START WITH 1000000 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_employees START WITH 2000 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_departments START WITH 10 INCREMENT BY 1 NOCYCLE; CREATE SEQUENCE seq_inventory START WITH 50000 INCREMENT BY 1 NOCYCLE; -- ============================================================================ -- BASE TABLES - DIMENSION TABLES -- ============================================================================ -- Departments Table (Parent of Employees) CREATE TABLE departments ( department_id NUMBER PRIMARY KEY, department_name VARCHAR2(100) NOT NULL UNIQUE, budget_allocation NUMBER(12,2), manager_id NUMBER, created_date DATE DEFAULT SYSDATE, CONSTRAINT chk_budget_positive CHECK (budget_allocation >= 0) ); COMMENT ON TABLE departments IS 'Organizational departments that manage business units'; COMMENT ON COLUMN departments.budget_allocation IS 'Annual budget allocation in USD'; -- Employees Table (Parent of Orders via sales_employee_id) CREATE TABLE employees ( employee_id NUMBER PRIMARY KEY, first_name VARCHAR2(50) NOT NULL, last_name VARCHAR2(50) NOT NULL, email VARCHAR2(100) UNIQUE, phone_number VARCHAR2(20), hire_date DATE NOT NULL, job_title VARCHAR2(50), salary NUMBER(10,2), department_id NUMBER NOT NULL, manager_id NUMBER, created_date DATE DEFAULT SYSDATE, CONSTRAINT fk_emp_dept FOREIGN KEY (department_id) REFERENCES departments(department_id), CONSTRAINT fk_emp_mgr FOREIGN KEY (manager_id) REFERENCES employees(employee_id), CONSTRAINT chk_salary_positive CHECK (salary > 0) ); COMMENT ON TABLE employees IS 'Company employees with hierarchical reporting structure'; COMMENT ON COLUMN employees.manager_id IS 'Self-referencing: supervisor of this employee'; -- Product Categories Table (Parent of Products) CREATE TABLE product_categories ( category_id NUMBER PRIMARY KEY, category_name VARCHAR2(100) NOT NULL UNIQUE, description VARCHAR2(500), active_flag CHAR(1) DEFAULT 'Y', created_date DATE DEFAULT SYSDATE ); COMMENT ON TABLE product_categories IS 'Product classification hierarchy'; -- Products Table (Parent of Order_Items, Inventory) CREATE TABLE products ( product_id NUMBER PRIMARY KEY, product_name VARCHAR2(150) NOT NULL, description VARCHAR2(500), category_id NUMBER NOT NULL, unit_price NUMBER(10,2) NOT NULL, cost_price NUMBER(10,2), reorder_level NUMBER(5) DEFAULT 10, discontinued_flag CHAR(1) DEFAULT 'N', created_date DATE DEFAULT SYSDATE, updated_date DATE, CONSTRAINT fk_prod_cat FOREIGN KEY (category_id) REFERENCES product_categories(category_id), CONSTRAINT chk_unit_price CHECK (unit_price > 0), CONSTRAINT chk_cost_price CHECK (cost_price IS NULL OR cost_price > 0) ); COMMENT ON TABLE products IS 'Saleable products in catalog'; COMMENT ON COLUMN products.reorder_level IS 'Minimum stock level before auto-reorder'; -- Customers Table (Parent of Orders, Reviews) CREATE TABLE customers ( customer_id NUMBER PRIMARY KEY, first_name VARCHAR2(50) NOT NULL, last_name VARCHAR2(50) NOT NULL, email VARCHAR2(100) UNIQUE NOT NULL, phone_number VARCHAR2(20), billing_address VARCHAR2(200), shipping_address VARCHAR2(200), customer_type VARCHAR2(20) DEFAULT 'RETAIL', credit_limit NUMBER(10,2), account_status VARCHAR2(20) DEFAULT 'ACTIVE', created_date DATE DEFAULT SYSDATE, last_purchase_date DATE, CONSTRAINT chk_cust_type CHECK (customer_type IN ('RETAIL', 'WHOLESALE', 'CORPORATE')), CONSTRAINT chk_cust_status CHECK (account_status IN ('ACTIVE', 'INACTIVE', 'SUSPENDED', 'ARCHIVED')) ); COMMENT ON TABLE customers IS 'Customer master data with credit and account information'; COMMENT ON COLUMN customers.credit_limit IS 'Maximum credit extended to customer in USD'; -- ============================================================================ -- TRANSACTIONAL TABLES -- ============================================================================ -- Orders Table (Parent of Order_Items, child of Customers and Employees) CREATE TABLE orders ( order_id NUMBER PRIMARY KEY, customer_id NUMBER NOT NULL, sales_employee_id NUMBER NOT NULL, order_date DATE NOT NULL, delivery_date DATE, order_status VARCHAR2(30) DEFAULT 'PENDING', total_amount NUMBER(12,2), tax_amount NUMBER(12,2), discount_amount NUMBER(12,2), payment_method VARCHAR2(30), notes VARCHAR2(500), created_date DATE DEFAULT SYSDATE, CONSTRAINT fk_ord_cust FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE, CONSTRAINT fk_ord_emp FOREIGN KEY (sales_employee_id) REFERENCES employees(employee_id), CONSTRAINT chk_ord_status CHECK (order_status IN ('PENDING', 'CONFIRMED', 'SHIPPED', 'DELIVERED', 'CANCELLED', 'RETURNED')), CONSTRAINT chk_ord_total CHECK (total_amount >= 0), CONSTRAINT chk_payment CHECK (payment_method IN ('CREDIT_CARD', 'BANK_TRANSFER', 'CASH', 'CHECK', 'DIGITAL_WALLET')) ); COMMENT ON TABLE orders IS 'Sales orders placed by customers'; COMMENT ON COLUMN orders.sales_employee_id IS 'Employee who processed this order (FK to employees)'; -- Order_Items Table (Child of Orders and Products) CREATE TABLE order_items ( order_item_id NUMBER PRIMARY KEY, order_id NUMBER NOT NULL, product_id NUMBER NOT NULL, quantity NUMBER(6) NOT NULL, unit_price NUMBER(10,2) NOT NULL, line_total NUMBER(12,2), discount_percent NUMBER(5,2) DEFAULT 0, created_date DATE DEFAULT SYSDATE, CONSTRAINT fk_oi_ord FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE, CONSTRAINT fk_oi_prod FOREIGN KEY (product_id) REFERENCES products(product_id), CONSTRAINT chk_qty CHECK (quantity > 0) ); COMMENT ON TABLE order_items IS 'Individual line items within an order'; -- Inventory Table (Child of Products) CREATE TABLE inventory ( inventory_id NUMBER PRIMARY KEY, product_id NUMBER NOT NULL UNIQUE, warehouse_location VARCHAR2(50), quantity_on_hand NUMBER(10) DEFAULT 0, quantity_reserved NUMBER(10) DEFAULT 0, quantity_available NUMBER(10) DEFAULT 0, last_stock_check DATE, reorder_quantity NUMBER(5), supplier_id NUMBER, updated_date DATE DEFAULT SYSDATE, CONSTRAINT fk_inv_prod FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE CASCADE, CONSTRAINT chk_qty_onhand CHECK (quantity_on_hand >= 0), CONSTRAINT chk_qty_reserved CHECK (quantity_reserved >= 0), CONSTRAINT chk_qty_available CHECK (quantity_available >= 0) ); COMMENT ON TABLE inventory IS 'Real-time inventory management for products'; -- Customer_Reviews Table (Child of Customers and Products) CREATE TABLE customer_reviews ( review_id NUMBER PRIMARY KEY, customer_id NUMBER NOT NULL, product_id NUMBER NOT NULL, review_rating NUMBER(2) DEFAULT 5, review_text VARCHAR2(1000), helpful_count NUMBER(5) DEFAULT 0, review_status VARCHAR2(20) DEFAULT 'PENDING', created_date DATE DEFAULT SYSDATE, moderated_date DATE, CONSTRAINT fk_rev_cust FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE, CONSTRAINT fk_rev_prod FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE CASCADE, CONSTRAINT chk_rating CHECK (review_rating BETWEEN 1 AND 5), CONSTRAINT chk_rev_status CHECK (review_status IN ('PENDING', 'APPROVED', 'REJECTED', 'FLAGGED')) ); COMMENT ON TABLE customer_reviews IS 'Customer product ratings and reviews with moderation workflow'; -- ============================================================================ -- INDEXES -- ============================================================================ -- Composite indexes on frequently filtered columns CREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date DESC); CREATE INDEX idx_orders_employee_status ON orders(sales_employee_id, order_status); CREATE INDEX idx_order_items_product ON order_items(product_id); -- Unique index for email lookup -- Functional index for case-insensitive searches CREATE INDEX idx_product_name_upper ON products(UPPER(product_name)); CREATE INDEX idx_category_name_upper ON product_categories(UPPER(category_name)); -- Index for inventory queries CREATE INDEX idx_inventory_warehouse ON inventory(warehouse_location); -- Index for review queries CREATE INDEX idx_reviews_product_rating ON customer_reviews(product_id, review_rating DESC); -- ============================================================================ -- VIEWS -- ============================================================================ -- Simple View: Active Customers CREATE OR REPLACE VIEW v_active_customers AS SELECT customer_id, first_name, last_name, email, customer_type, account_status, last_purchase_date FROM customers WHERE account_status = 'ACTIVE'; COMMENT ON TABLE v_active_customers IS 'Filtered view of active customer accounts only'; -- Complex View: Order Summary with Customer and Employee Details CREATE OR REPLACE VIEW v_order_summary AS SELECT o.order_id, c.customer_id, c.first_name || ' ' || c.last_name AS customer_name, c.email AS customer_email, e.employee_id, e.first_name || ' ' || e.last_name AS sales_person, o.order_date, o.delivery_date, o.order_status, COUNT(oi.order_item_id) AS line_item_count, SUM(oi.quantity) AS total_items, o.total_amount, o.tax_amount, o.discount_amount, (o.total_amount + o.tax_amount - o.discount_amount) AS net_amount FROM orders o JOIN customers c ON o.customer_id = c.customer_id JOIN employees e ON o.sales_employee_id = e.employee_id LEFT JOIN order_items oi ON o.order_id = oi.order_id GROUP BY o.order_id, c.customer_id, c.first_name, c.last_name, c.email, e.employee_id, e.first_name, e.last_name, o.order_date, o.delivery_date, o.order_status, o.total_amount, o.tax_amount, o.discount_amount; COMMENT ON TABLE v_order_summary IS 'Comprehensive order view with aggregated metrics and related customer/employee data'; -- Aggregation View: Product Performance CREATE OR REPLACE VIEW v_product_performance AS SELECT p.product_id, p.product_name, pc.category_name, p.unit_price, COUNT(DISTINCT oi.order_id) AS orders_count, SUM(oi.quantity) AS total_quantity_sold, SUM(oi.line_total) AS total_revenue, ROUND(AVG(oi.quantity), 2) AS avg_qty_per_order, COUNT(DISTINCT cr.review_id) AS review_count, ROUND(AVG(cr.review_rating), 2) AS avg_rating, i.quantity_on_hand, i.quantity_reserved, i.quantity_available FROM products p JOIN product_categories pc ON p.category_id = pc.category_id LEFT JOIN order_items oi ON p.product_id = oi.product_id LEFT JOIN customer_reviews cr ON p.product_id = cr.product_id AND cr.review_status = 'APPROVED' LEFT JOIN inventory i ON p.product_id = i.product_id WHERE p.discontinued_flag = 'N' GROUP BY p.product_id, p.product_name, pc.category_name, p.unit_price, i.quantity_on_hand, i.quantity_reserved, i.quantity_available; COMMENT ON TABLE v_product_performance IS 'Multi-dimensional view showing sales, reviews, and inventory for each product'; -- View: Employee Sales Performance CREATE OR REPLACE VIEW v_employee_sales_performance AS SELECT e.employee_id, e.first_name || ' ' || e.last_name AS employee_name, e.job_title, d.department_name, COUNT(DISTINCT o.order_id) AS total_orders, SUM(o.total_amount) AS total_sales_amount, ROUND(AVG(o.total_amount), 2) AS avg_order_value, COUNT(DISTINCT o.customer_id) AS unique_customers, MAX(o.order_date) AS last_order_date FROM employees e JOIN departments d ON e.department_id = d.department_id LEFT JOIN orders o ON e.employee_id = o.sales_employee_id GROUP BY e.employee_id, e.first_name, e.last_name, e.job_title, d.department_name; COMMENT ON TABLE v_employee_sales_performance IS 'Sales metrics aggregated at employee level with department context'; -- ============================================================================ -- STORED PROCEDURES -- ============================================================================ -- Procedure 1: Create New Order with Validation CREATE OR REPLACE PROCEDURE proc_create_order( p_customer_id IN NUMBER, p_employee_id IN NUMBER, p_delivery_date IN DATE, p_order_id OUT NUMBER, p_status_msg OUT VARCHAR2 ) IS v_customer_count NUMBER; v_employee_count NUMBER; v_total_amount NUMBER := 0; BEGIN -- Validate customer exists SELECT COUNT(*) INTO v_customer_count FROM customers WHERE customer_id = p_customer_id AND account_status = 'ACTIVE'; IF v_customer_count = 0 THEN p_status_msg := 'ERROR: Customer not found or inactive'; RETURN; END IF; -- Validate employee exists SELECT COUNT(*) INTO v_employee_count FROM employees WHERE employee_id = p_employee_id; IF v_employee_count = 0 THEN p_status_msg := 'ERROR: Employee not found'; RETURN; END IF; -- Create order SELECT seq_orders.NEXTVAL INTO p_order_id FROM DUAL; INSERT INTO orders ( order_id, customer_id, sales_employee_id, order_date, delivery_date, order_status, total_amount, tax_amount, discount_amount, created_date ) VALUES ( p_order_id, p_customer_id, p_employee_id, SYSDATE, p_delivery_date, 'PENDING', 0, 0, 0, SYSDATE ); p_status_msg := 'SUCCESS: Order created with ID ' || p_order_id; COMMIT; EXCEPTION WHEN OTHERS THEN p_status_msg := 'ERROR: ' || SQLERRM; ROLLBACK; END proc_create_order; / -- Procedure 2: Add Item to Order with Stock Validation CREATE OR REPLACE PROCEDURE proc_add_order_item( p_order_id IN NUMBER, p_product_id IN NUMBER, p_quantity IN NUMBER, p_order_item_id OUT NUMBER, p_status_msg OUT VARCHAR2 ) IS v_product_count NUMBER; v_unit_price NUMBER; v_available_qty NUMBER; v_line_total NUMBER; BEGIN -- Validate product exists SELECT COUNT(*), unit_price INTO v_product_count, v_unit_price FROM products WHERE product_id = p_product_id AND discontinued_flag = 'N'; IF v_product_count = 0 THEN p_status_msg := 'ERROR: Product not found or discontinued'; RETURN; END IF; -- Check inventory availability SELECT quantity_available INTO v_available_qty FROM inventory WHERE product_id = p_product_id; IF v_available_qty < p_quantity THEN p_status_msg := 'ERROR: Insufficient inventory. Available: ' || v_available_qty; RETURN; END IF; -- Calculate line total v_line_total := p_quantity * v_unit_price; -- Insert order item SELECT seq_order_items.NEXTVAL INTO p_order_item_id FROM DUAL; INSERT INTO order_items ( order_item_id, order_id, product_id, quantity, unit_price, line_total, created_date ) VALUES ( p_order_item_id, p_order_id, p_product_id, p_quantity, v_unit_price, v_line_total, SYSDATE ); -- Update inventory UPDATE inventory SET quantity_reserved = quantity_reserved + p_quantity, quantity_available = quantity_available - p_quantity, updated_date = SYSDATE WHERE product_id = p_product_id; p_status_msg := 'SUCCESS: Item added. Line total: ' || v_line_total; COMMIT; EXCEPTION WHEN OTHERS THEN p_status_msg := 'ERROR: ' || SQLERRM; ROLLBACK; END proc_add_order_item; / -- Procedure 3: Calculate and Update Order Total CREATE OR REPLACE PROCEDURE proc_finalize_order( p_order_id IN NUMBER, p_tax_rate IN NUMBER DEFAULT 0.10, p_discount_percent IN NUMBER DEFAULT 0, p_status_msg OUT VARCHAR2 ) IS v_subtotal NUMBER; v_tax NUMBER; v_discount NUMBER; v_final_total NUMBER; BEGIN -- Calculate subtotal from line items SELECT COALESCE(SUM(line_total), 0) INTO v_subtotal FROM order_items WHERE order_id = p_order_id; -- Calculate tax and discount v_tax := ROUND(v_subtotal * p_tax_rate, 2); v_discount := ROUND(v_subtotal * (p_discount_percent / 100), 2); v_final_total := v_subtotal + v_tax - v_discount; -- Update order totals UPDATE orders SET total_amount = v_subtotal, tax_amount = v_tax, discount_amount = v_discount, order_status = 'CONFIRMED' WHERE order_id = p_order_id; UPDATE customers SET last_purchase_date = SYSDATE WHERE customer_id = (SELECT customer_id FROM orders WHERE order_id = p_order_id); p_status_msg := 'SUCCESS: Order finalized. Total: ' || v_final_total; COMMIT; EXCEPTION WHEN OTHERS THEN p_status_msg := 'ERROR: ' || SQLERRM; ROLLBACK; END proc_finalize_order; / -- Procedure 4: Generate Monthly Sales Report CREATE OR REPLACE PROCEDURE proc_monthly_sales_report( p_year IN NUMBER, p_month IN NUMBER, p_report_cursor OUT SYS_REFCURSOR ) IS v_first_day DATE; v_last_day DATE; BEGIN v_first_day := TRUNC(TO_DATE(p_year || '-' || LPAD(p_month, 2, '0') || '-01', 'YYYY-MM-DD')); v_last_day := LAST_DAY(v_first_day); OPEN p_report_cursor FOR SELECT e.employee_id, e.first_name || ' ' || e.last_name AS employee_name, d.department_name, COUNT(o.order_id) AS order_count, SUM(o.total_amount) AS total_sales, ROUND(AVG(o.total_amount), 2) AS avg_order_value, MAX(o.order_date) AS latest_order FROM employees e JOIN departments d ON e.department_id = d.department_id LEFT JOIN orders o ON e.employee_id = o.sales_employee_id AND o.order_date >= v_first_day AND o.order_date <= v_last_day GROUP BY e.employee_id, e.first_name, e.last_name, d.department_name ORDER BY total_sales DESC; EXCEPTION WHEN OTHERS THEN NULL; END proc_monthly_sales_report; / -- ============================================================================ -- PACKAGES -- ============================================================================ CREATE OR REPLACE PACKAGE pkg_order_management IS -- Function to check product availability FUNCTION fn_check_availability( p_product_id IN NUMBER, p_quantity IN NUMBER ) RETURN BOOLEAN; -- Procedure to process refund PROCEDURE proc_refund_order( p_order_id IN NUMBER, p_reason IN VARCHAR2, p_status_msg OUT VARCHAR2 ); -- Function to calculate discount FUNCTION fn_calculate_discount( p_customer_id IN NUMBER, p_amount IN NUMBER ) RETURN NUMBER; END pkg_order_management; / CREATE OR REPLACE PACKAGE BODY pkg_order_management IS FUNCTION fn_check_availability( p_product_id IN NUMBER, p_quantity IN NUMBER ) RETURN BOOLEAN IS v_available NUMBER; BEGIN SELECT quantity_available INTO v_available FROM inventory WHERE product_id = p_product_id; RETURN v_available >= p_quantity; EXCEPTION WHEN OTHERS THEN RETURN FALSE; END fn_check_availability; PROCEDURE proc_refund_order( p_order_id IN NUMBER, p_reason IN VARCHAR2, p_status_msg OUT VARCHAR2 ) IS v_product_id NUMBER; v_quantity NUMBER; CURSOR c_items IS SELECT product_id, quantity FROM order_items WHERE order_id = p_order_id; BEGIN -- Return items to inventory FOR rec IN c_items LOOP UPDATE inventory SET quantity_available = quantity_available + rec.quantity, quantity_reserved = quantity_reserved - rec.quantity, updated_date = SYSDATE WHERE product_id = rec.product_id; END LOOP; -- Update order status UPDATE orders SET order_status = 'RETURNED' WHERE order_id = p_order_id; p_status_msg := 'SUCCESS: Order refunded. Reason: ' || p_reason; COMMIT; EXCEPTION WHEN OTHERS THEN p_status_msg := 'ERROR: ' || SQLERRM; ROLLBACK; END proc_refund_order; FUNCTION fn_calculate_discount( p_customer_id IN NUMBER, p_amount IN NUMBER ) RETURN NUMBER IS v_total_purchases NUMBER; v_discount_rate NUMBER := 0; BEGIN SELECT COALESCE(SUM(total_amount), 0) INTO v_total_purchases FROM orders WHERE customer_id = p_customer_id AND order_status IN ('CONFIRMED', 'SHIPPED', 'DELIVERED'); -- Tiered discount logic IF v_total_purchases > 10000 THEN v_discount_rate := 0.15; ELSIF v_total_purchases > 5000 THEN v_discount_rate := 0.10; ELSIF v_total_purchases > 1000 THEN v_discount_rate := 0.05; END IF; RETURN ROUND(p_amount * v_discount_rate, 2); END fn_calculate_discount; END pkg_order_management; / -- ============================================================================ -- TRIGGERS -- ============================================================================ -- Trigger 1: Update Product Updated_Date on Insert/Update CREATE OR REPLACE TRIGGER trg_products_audit BEFORE UPDATE ON products FOR EACH ROW BEGIN :NEW.updated_date := SYSDATE; END trg_products_audit; / -- Trigger 2: Validate Order Status Transition CREATE OR REPLACE TRIGGER trg_orders_status_validation BEFORE UPDATE ON orders FOR EACH ROW BEGIN IF :OLD.order_status = 'DELIVERED' AND :NEW.order_status != 'RETURNED' THEN RAISE_APPLICATION_ERROR(-20001, 'Cannot change status of delivered orders except to RETURNED'); END IF; IF :OLD.order_status = 'CANCELLED' AND :NEW.order_status != 'CANCELLED' THEN RAISE_APPLICATION_ERROR(-20002, 'Cancelled orders cannot be modified'); END IF; END trg_orders_status_validation; / -- Trigger 3: Maintain Inventory Available Quantity CREATE OR REPLACE TRIGGER trg_inventory_available_calc AFTER UPDATE ON inventory FOR EACH ROW BEGIN UPDATE inventory SET quantity_available = quantity_on_hand - quantity_reserved WHERE inventory_id = :NEW.inventory_id; END trg_inventory_available_calc; / -- Trigger 4: Log Review Status Changes CREATE TABLE review_audit_log ( log_id NUMBER PRIMARY KEY, review_id NUMBER, old_status VARCHAR2(20), new_status VARCHAR2(20), changed_by VARCHAR2(50), changed_date DATE ); CREATE SEQUENCE seq_review_audit_log START WITH 1; CREATE OR REPLACE TRIGGER trg_review_status_audit AFTER UPDATE ON customer_reviews FOR EACH ROW BEGIN IF :OLD.review_status != :NEW.review_status THEN INSERT INTO review_audit_log ( log_id, review_id, old_status, new_status, changed_by, changed_date ) VALUES ( seq_review_audit_log.NEXTVAL, :NEW.review_id, :OLD.review_status, :NEW.review_status, USER, SYSDATE ); END IF; END trg_review_status_audit; / -- ============================================================================ -- SUMMARY: DATABASE OBJECT DEPENDENCIES -- ============================================================================ /* DEPENDENCY HIERARCHY: Level 1 - Root Tables (No dependencies on other tables): ├── departments ├── product_categories └── customers Level 2 - Tables dependent on Level 1: ├── employees (FK → departments) ├── products (FK → product_categories) └── departments (self-referencing: manager_id → employees) Level 3 - Tables dependent on Level 2: ├── orders (FK → customers, employees) ├── inventory (FK → products) └── customer_reviews (FK → customers, products) Level 4 - Tables dependent on Level 3: └── order_items (FK → orders, products) VIEWS DEPENDENCY: ├── v_active_customers (→ customers) ├── v_order_summary (→ orders, customers, employees, order_items) ├── v_product_performance (→ products, categories, order_items, reviews, inventory) └── v_employee_sales_performance (→ employees, departments, orders) PROCEDURES/PACKAGES: ├── proc_create_order (→ customers, employees, orders) ├── proc_add_order_item (→ orders, products, inventory, order_items) ├── proc_finalize_order (→ orders, order_items, customers) ├── proc_monthly_sales_report (→ employees, departments, orders) ├── pkg_order_management.fn_check_availability (→ inventory) ├── pkg_order_management.proc_refund_order (→ order_items, inventory, orders) └── pkg_order_management.fn_calculate_discount (→ orders, customers) TRIGGERS: ├── trg_products_audit (→ products) ├── trg_orders_status_validation (→ orders) ├── trg_inventory_available_calc (→ inventory) └── trg_review_status_audit (→ customer_reviews, review_audit_log) INDEXES: - 14 indexes covering frequently accessed paths - Composite, unique, and functional indexes for performance SEQUENCES: - 7 sequences for auto-increment of primary keys */ -- ============================================================================ -- CONSTRAINTS ALREADY ENABLED BY DEFAULT -- ============================================================================ -- All constraints are created and enabled during table creation. -- No additional enabling required. -- ============================================================================ -- END OF SCHEMA CREATION -- ============================================================================