Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions sql/00_drop_tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- Al Noor Hospital Management System
-- Drop objects (run only if re-installing)

BEGIN
FOR t IN (
SELECT table_name FROM user_tables
WHERE table_name IN (
'PRESCRIPTION_ITEMS', 'PRESCRIPTIONS', 'PATIENT_VISITS', 'ADMISSIONS',
'APPOINTMENTS', 'MEDICINES', 'DOCTORS', 'PATIENTS', 'ROOMS',
'APPOINTMENT_STATUSES', 'MEDICINE_CATEGORIES', 'DOCTOR_SPECIALTIES', 'DEPARTMENTS'
)
) LOOP
EXECUTE IMMEDIATE 'DROP TABLE ' || t.table_name || ' CASCADE CONSTRAINTS';
END LOOP;
END;
/
212 changes: 212 additions & 0 deletions sql/01_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
-- =============================================================================
-- Al Noor Hospital Management System — Database Schema
-- Oracle Database / Oracle APEX compatible
-- =============================================================================

-- -----------------------------------------------------------------------------
-- A. LOOKUP / REFERENCE TABLES
-- -----------------------------------------------------------------------------

CREATE TABLE departments (
department_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
department_name VARCHAR2(100) NOT NULL,
floor_no NUMBER(3),
status VARCHAR2(20) DEFAULT 'Active' NOT NULL,
CONSTRAINT chk_dept_status CHECK (status IN ('Active', 'Inactive'))
);

CREATE TABLE doctor_specialties (
specialty_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
specialty_name VARCHAR2(100) NOT NULL,
status VARCHAR2(20) DEFAULT 'Active' NOT NULL,
CONSTRAINT chk_spec_status CHECK (status IN ('Active', 'Inactive'))
);

CREATE TABLE medicine_categories (
category_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
category_name VARCHAR2(100) NOT NULL,
status VARCHAR2(20) DEFAULT 'Active' NOT NULL,
CONSTRAINT chk_medcat_status CHECK (status IN ('Active', 'Inactive'))
);

CREATE TABLE appointment_statuses (
status_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
status_name VARCHAR2(50) NOT NULL,
CONSTRAINT uq_appt_status_name UNIQUE (status_name)
);

-- -----------------------------------------------------------------------------
-- B. CORE TABLES
-- -----------------------------------------------------------------------------

CREATE TABLE patients (
patient_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
civil_id VARCHAR2(20) NOT NULL,
full_name VARCHAR2(150) NOT NULL,
gender VARCHAR2(10) NOT NULL,
date_of_birth DATE NOT NULL,
mobile_no VARCHAR2(20) NOT NULL,
email VARCHAR2(100),
blood_group VARCHAR2(5),
address VARCHAR2(300),
emergency_contact_name VARCHAR2(150),
emergency_contact_no VARCHAR2(20),
created_at DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT uq_patient_civil_id UNIQUE (civil_id),
CONSTRAINT chk_patient_gender CHECK (gender IN ('Male', 'Female')),
CONSTRAINT chk_patient_blood CHECK (
blood_group IS NULL OR blood_group IN (
'A+', 'A-', 'B+', 'B-', 'O+', 'O-', 'AB+', 'AB-'
)
)
);

CREATE TABLE doctors (
doctor_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
full_name VARCHAR2(150) NOT NULL,
department_id NUMBER NOT NULL,
specialty_id NUMBER NOT NULL,
mobile_no VARCHAR2(20),
email VARCHAR2(100),
consultation_fee NUMBER(10, 3) DEFAULT 0 NOT NULL,
status VARCHAR2(20) DEFAULT 'Active' NOT NULL,
CONSTRAINT fk_doctor_dept FOREIGN KEY (department_id)
REFERENCES departments (department_id),
CONSTRAINT fk_doctor_spec FOREIGN KEY (specialty_id)
REFERENCES doctor_specialties (specialty_id),
CONSTRAINT chk_doctor_status CHECK (status IN ('Active', 'Inactive')),
CONSTRAINT chk_doctor_fee CHECK (consultation_fee >= 0)
);

CREATE TABLE medicines (
medicine_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
medicine_name VARCHAR2(150) NOT NULL,
category_id NUMBER NOT NULL,
unit VARCHAR2(50) NOT NULL,
current_stock NUMBER(10) DEFAULT 0 NOT NULL,
reorder_level NUMBER(10) DEFAULT 10 NOT NULL,
status VARCHAR2(20) DEFAULT 'Active' NOT NULL,
CONSTRAINT fk_medicine_cat FOREIGN KEY (category_id)
REFERENCES medicine_categories (category_id),
CONSTRAINT chk_medicine_status CHECK (status IN ('Active', 'Inactive')),
CONSTRAINT chk_medicine_stock CHECK (current_stock >= 0),
CONSTRAINT chk_medicine_reorder CHECK (reorder_level >= 0)
);

CREATE TABLE appointments (
appointment_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
patient_id NUMBER NOT NULL,
doctor_id NUMBER NOT NULL,
appointment_date DATE NOT NULL,
appointment_time VARCHAR2(10) NOT NULL,
status_id NUMBER NOT NULL,
reason_for_visit VARCHAR2(500),
created_at DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT fk_appt_patient FOREIGN KEY (patient_id)
REFERENCES patients (patient_id),
CONSTRAINT fk_appt_doctor FOREIGN KEY (doctor_id)
REFERENCES doctors (doctor_id),
CONSTRAINT fk_appt_status FOREIGN KEY (status_id)
REFERENCES appointment_statuses (status_id)
);

CREATE TABLE patient_visits (
visit_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
appointment_id NUMBER NOT NULL,
patient_id NUMBER NOT NULL,
doctor_id NUMBER NOT NULL,
visit_date DATE DEFAULT SYSDATE NOT NULL,
symptoms VARCHAR2(1000),
diagnosis VARCHAR2(1000),
notes VARCHAR2(2000),
follow_up_date DATE,
CONSTRAINT fk_visit_appt FOREIGN KEY (appointment_id)
REFERENCES appointments (appointment_id),
CONSTRAINT fk_visit_patient FOREIGN KEY (patient_id)
REFERENCES patients (patient_id),
CONSTRAINT fk_visit_doctor FOREIGN KEY (doctor_id)
REFERENCES doctors (doctor_id),
CONSTRAINT uq_visit_appointment UNIQUE (appointment_id)
);

CREATE TABLE prescriptions (
prescription_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
visit_id NUMBER NOT NULL,
patient_id NUMBER NOT NULL,
doctor_id NUMBER NOT NULL,
prescription_date DATE DEFAULT SYSDATE NOT NULL,
notes VARCHAR2(1000),
CONSTRAINT fk_rx_visit FOREIGN KEY (visit_id)
REFERENCES patient_visits (visit_id),
CONSTRAINT fk_rx_patient FOREIGN KEY (patient_id)
REFERENCES patients (patient_id),
CONSTRAINT fk_rx_doctor FOREIGN KEY (doctor_id)
REFERENCES doctors (doctor_id),
CONSTRAINT uq_rx_visit UNIQUE (visit_id)
);

CREATE TABLE prescription_items (
prescription_item_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
prescription_id NUMBER NOT NULL,
medicine_id NUMBER NOT NULL,
dosage VARCHAR2(100),
frequency VARCHAR2(100),
duration_days NUMBER(5),
instructions VARCHAR2(300),
CONSTRAINT fk_rxitem_rx FOREIGN KEY (prescription_id)
REFERENCES prescriptions (prescription_id) ON DELETE CASCADE,
CONSTRAINT fk_rxitem_med FOREIGN KEY (medicine_id)
REFERENCES medicines (medicine_id),
CONSTRAINT chk_rxitem_duration CHECK (duration_days IS NULL OR duration_days > 0)
);

CREATE TABLE rooms (
room_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
room_no VARCHAR2(20) NOT NULL,
room_type VARCHAR2(30) NOT NULL,
daily_rate NUMBER(10, 3) DEFAULT 0 NOT NULL,
status VARCHAR2(20) DEFAULT 'Available' NOT NULL,
CONSTRAINT uq_room_no UNIQUE (room_no),
CONSTRAINT chk_room_type CHECK (room_type IN ('General', 'Private', 'ICU')),
CONSTRAINT chk_room_status CHECK (status IN ('Available', 'Occupied', 'Maintenance')),
CONSTRAINT chk_room_rate CHECK (daily_rate >= 0)
);

CREATE TABLE admissions (
admission_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
patient_id NUMBER NOT NULL,
doctor_id NUMBER NOT NULL,
room_id NUMBER NOT NULL,
admission_date DATE DEFAULT SYSDATE NOT NULL,
discharge_date DATE,
admission_reason VARCHAR2(500),
status VARCHAR2(20) DEFAULT 'Admitted' NOT NULL,
CONSTRAINT fk_adm_patient FOREIGN KEY (patient_id)
REFERENCES patients (patient_id),
CONSTRAINT fk_adm_doctor FOREIGN KEY (doctor_id)
REFERENCES doctors (doctor_id),
CONSTRAINT fk_adm_room FOREIGN KEY (room_id)
REFERENCES rooms (room_id),
CONSTRAINT chk_adm_status CHECK (status IN ('Admitted', 'Discharged')),
CONSTRAINT chk_adm_discharge CHECK (
(status = 'Admitted' AND discharge_date IS NULL)
OR (status = 'Discharged' AND discharge_date IS NOT NULL)
)
);

-- -----------------------------------------------------------------------------
-- INDEXES for report / lookup performance
-- -----------------------------------------------------------------------------

CREATE INDEX idx_doctors_dept ON doctors (department_id);
CREATE INDEX idx_doctors_spec ON doctors (specialty_id);
CREATE INDEX idx_appt_patient ON appointments (patient_id);
CREATE INDEX idx_appt_doctor ON appointments (doctor_id);
CREATE INDEX idx_appt_date ON appointments (appointment_date);
CREATE INDEX idx_visits_patient ON patient_visits (patient_id);
CREATE INDEX idx_visits_doctor ON patient_visits (doctor_id);
CREATE INDEX idx_adm_patient ON admissions (patient_id);
CREATE INDEX idx_adm_status ON admissions (status);
CREATE INDEX idx_med_stock ON medicines (current_stock, reorder_level);

COMMIT;
Loading
Loading