-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDB Tables + Constraints + Triggers.sql
355 lines (260 loc) · 8.15 KB
/
DB Tables + Constraints + Triggers.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
CREATE TABLE user_info (
user_id VARCHAR2(20) PRIMARY KEY,
firstname VARCHAR2(50) NOT NULL,
lastname VARCHAR2(50) NOT NULL,
email_address VARCHAR2(100) DEFAULT 'example@example.com' NOT NULL,
gender CHAR(1) CHECK (gender IN ('F', 'M')),
user_type CHAR(1) CHECK (user_type IN ('S', 'F'))
);
ALTER TABLE user_info ADD CONSTRAINT user_id_format_check
CHECK (
REGEXP_LIKE(user_id, '^20[0-9]{2}[A-Z][0-9]PS[0-9]{4}H$')
);
CREATE TABLE rental (
rental_id NUMBER PRIMARY KEY,
borrower_id VARCHAR2(20) NOT NULL,
rental_date DATE NOT NULL,
deadline DATE,
return_date DATE,
rental_status VARCHAR2(10) DEFAULT 'active' CHECK (rental_status IN ('active', 'inactive','damaged','extended')),
late_fees NUMBER DEFAULT 0,
damage_fees NUMBER DEFAULT 0,
amount_due NUMBER DEFAULT 0,
bicycle_id NUMBER NOT NULL
);
CREATE TABLE bicycle (
bicycle_id NUMBER PRIMARY KEY,
bicycle_type VARCHAR2(100) NOT NULL,
lender_id VARCHAR2(20) NOT NULL,
model_type VARCHAR2(100) NOT NULL,
bicycle_status VARCHAR2(20) DEFAULT 'available' CHECK (bicycle_status IN ('available', 'unavailable', 'damaged', 'stolen')),
CONSTRAINT bicycle_lender_fk FOREIGN KEY (lender_id) REFERENCES user_info(user_id) ON DELETE CASCADE
);
ALTER TABLE rental
ADD CONSTRAINT fk_bicycle_id FOREIGN KEY (bicycle_id) REFERENCES bicycle(bicycle_id) ON DELETE CASCADE;
ALTER TABLE rental
ADD CONSTRAINT fk_borrower_id FOREIGN KEY (borrower_id) REFERENCES user_info(user_id) ON DELETE CASCADE;
CREATE OR REPLACE TRIGGER calculate_deadline
BEFORE INSERT ON rental
FOR EACH ROW
BEGIN
:NEW.deadline := :NEW.rental_date + 1; -- Assuming deadline is set exactly one day after rental_date
END;
/
CREATE OR REPLACE TRIGGER update_rental_status_and_return_date
AFTER INSERT ON rental
FOR EACH ROW
BEGIN
IF :NEW.return_date IS NOT NULL THEN
UPDATE rental
SET rental_status = 'inactive'
WHERE rental_id = :NEW.rental_id;
END IF;
END;
/
CREATE OR REPLACE TRIGGER calculate_late_fees
BEFORE INSERT OR UPDATE OF return_date ON rental
FOR EACH ROW
BEGIN
IF :NEW.return_date IS NOT NULL AND :NEW.return_date > :NEW.deadline THEN
:NEW.late_fees := (:NEW.return_date - :NEW.deadline) * 100; -- Assuming late fees of 100 units per day
END IF;
END;
/
CREATE OR REPLACE TRIGGER update_damage_fees
BEFORE INSERT OR UPDATE OF rental_status ON rental
FOR EACH ROW
BEGIN
IF :NEW.rental_status = 'damage' THEN
:NEW.damage_fees := 1000; -- Assuming flat damage fee of 1000 units
END IF;
END;
/
CREATE OR REPLACE TRIGGER calculate_amount_due
BEFORE INSERT OR UPDATE OF return_date, damage_fees ON rental
FOR EACH ROW
BEGIN
:NEW.amount_due := 100 + :NEW.late_fees + :NEW.damage_fees;
END;
/
CREATE TABLE feedback (
feedback_id NUMBER PRIMARY KEY,
user_id VARCHAR2(20) NOT NULL,
rating NUMBER CHECK (rating >= 1 AND rating <= 10),
comments VARCHAR2(1000),
CONSTRAINT feedback_user_fk FOREIGN KEY (user_id) REFERENCES user_info(user_id) ON DELETE CASCADE
);
CREATE TABLE maintenance_schedule (
maintenance_id NUMBER PRIMARY KEY,
maintenance_date DATE DEFAULT SYSDATE NOT NULL,
maintenance_task VARCHAR2(255) NOT NULL,
bicycle_id NUMBER NOT NULL,
CONSTRAINT maintenance_bicycle_fk FOREIGN KEY (bicycle_id) REFERENCES bicycle(bicycle_id) ON DELETE CASCADE
);
CREATE OR REPLACE TRIGGER update_bicycle_status
AFTER INSERT OR UPDATE OF rental_status ON rental
FOR EACH ROW
DECLARE
v_bicycle_status VARCHAR2(20);
BEGIN
-- Get the bicycle status based on the return status
IF :NEW.rental_status = 'inactive' THEN
v_bicycle_status := 'available';
ELSIF :NEW.rental_status = 'damaged' THEN
v_bicycle_status := 'damaged';
END IF;
-- Update the bicycle status
UPDATE bicycle
SET bicycle_status = v_bicycle_status
WHERE bicycle_id = :NEW.bicycle_id;
END;
/
CREATE TABLE extension (
extension_id NUMBER PRIMARY KEY,
rental_id NUMBER NOT NULL,
extra_duration NUMBER NOT NULL,
extra_charges NUMBER,
CONSTRAINT extension_rental_fk FOREIGN KEY (rental_id) REFERENCES rental(rental_id) ON DELETE CASCADE
);
CREATE OR REPLACE TRIGGER calculate_extra_charges
BEFORE INSERT ON extension
FOR EACH ROW
BEGIN
:NEW.extra_charges := 100 * :NEW.extra_duration;
END;
/
CREATE OR REPLACE TRIGGER update_rental_status_on_extension
FOR INSERT ON extension
COMPOUND TRIGGER
TYPE t_rental_ids IS TABLE OF rental.rental_id%TYPE INDEX BY PLS_INTEGER;
v_rental_ids t_rental_ids;
BEFORE STATEMENT IS
BEGIN
-- Initialize the collection
v_rental_ids.DELETE;
END BEFORE STATEMENT;
AFTER EACH ROW IS
BEGIN
-- Store the rental_id of the inserted row
v_rental_ids(v_rental_ids.COUNT + 1) := :NEW.rental_id;
END AFTER EACH ROW;
AFTER STATEMENT IS
v_extra_duration extension.extra_duration%TYPE;
v_new_return_date rental.return_date%TYPE;
BEGIN
FOR i IN 1..v_rental_ids.COUNT LOOP
-- Get the extra duration for the current rental_id
SELECT extra_duration INTO v_extra_duration
FROM extension
WHERE rental_id = v_rental_ids(i);
-- Update rental status to 'extended'
UPDATE rental
SET rental_status = 'extended'
WHERE rental_id = v_rental_ids(i);
-- Calculate new return date and update in rental table
SELECT deadline + v_extra_duration INTO v_new_return_date
FROM rental
WHERE rental_id = v_rental_ids(i);
UPDATE rental
SET return_date = v_new_return_date
WHERE rental_id = v_rental_ids(i);
END LOOP;
END AFTER STATEMENT;
END update_rental_status_on_extension;
/
CREATE TABLE customization_request (
custom_id NUMBER PRIMARY KEY,
request_type VARCHAR2(100),
requirements VARCHAR2(1000),
approval_status VARCHAR2(20) CHECK (approval_status IN ('approved', 'not approved')),
extra_charges NUMBER DEFAULT 100
);
CREATE TABLE rental_custom (
rental_id NUMBER,
custom_id NUMBER,
CONSTRAINT pk_rental_custom PRIMARY KEY (rental_id, custom_id),
CONSTRAINT fk_rental FOREIGN KEY (rental_id) REFERENCES rental(rental_id) ON DELETE CASCADE,
CONSTRAINT fk_customization_request FOREIGN KEY (custom_id) REFERENCES customization_request(custom_id) ON DELETE CASCADE
);
CREATE TABLE user_phno (
user_id VARCHAR2(20),
phno VARCHAR2(10) UNIQUE CHECK (LENGTH(phno) = 10),
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES user_info(user_id) ON DELETE CASCADE
);
CREATE TABLE bicycle_color (
bicycle_id NUMBER,
color VARCHAR2(50),
CONSTRAINT fk_bicycle FOREIGN KEY (bicycle_id) REFERENCES bicycle(bicycle_id) ON DELETE CASCADE
);
-- Create sequence
CREATE SEQUENCE rental_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER rental_trigger
BEFORE INSERT ON rental
FOR EACH ROW
BEGIN
:NEW.rental_id := rental_seq.NEXTVAL;
END;
/
-- Create sequence
CREATE SEQUENCE feedback_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER feedback_trigger
BEFORE INSERT ON feedback
FOR EACH ROW
BEGIN
:NEW.feedback_id := feedback_seq.NEXTVAL;
END;
/
-- Create sequence
CREATE SEQUENCE maintenance_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER maintenance_trigger
BEFORE INSERT ON maintenance_schedule
FOR EACH ROW
BEGIN
:NEW.maintenance_id := maintenance_seq.NEXTVAL;
END;
/
-- Create sequence
CREATE SEQUENCE bicycle_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER bicycle_trigger
BEFORE INSERT ON bicycle
FOR EACH ROW
BEGIN
:NEW.bicycle_id := bicycle_seq.NEXTVAL;
END;
/
-- Create sequence
CREATE SEQUENCE extension_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER extension_trigger
BEFORE INSERT ON extension
FOR EACH ROW
BEGIN
:NEW.extension_id := extension_seq.NEXTVAL;
END;
/
-- Create sequence
CREATE SEQUENCE custom_seq
START WITH 1
INCREMENT BY 1;
-- Create trigger
CREATE OR REPLACE TRIGGER custom_trigger
BEFORE INSERT ON customization_request
FOR EACH ROW
BEGIN
:NEW.custom_id := custom_seq.NEXTVAL;
END;
/