DatabaseProgramming: programming.sql

File programming.sql, 13.8 KB (added by 231069, 8 hours ago)
Line 
1
2---Programming
3
4--Trigger1: avtomatska presmetka na vkupnata suma na site kazni za eden zapisnik vo Uplata
5
6CREATE OR REPLACE FUNCTION azuriraj_iznos_uplata()
7 RETURNS TRIGGER
8 LANGUAGE plpgsql
9AS $$
10DECLARE
11 v_id_zapisnik int;
12 v_nov_iznos numeric(10,2);
13BEGIN
14
15 IF TG_OP = 'DELETE' THEN
16 v_id_zapisnik := OLD.id_na_zapisnik;
17 ELSE
18 v_id_zapisnik := NEW.id_na_zapisnik;
19 END IF;
20
21
22 SELECT COALESCE(SUM(k.iznos_kazna), 0)
23 INTO v_nov_iznos
24 FROM Stavka_Zapisnik sz
25 JOIN Prekrsok p ON sz.id_na_prekrsok = p.id_prekrsok
26 JOIN Kazna k ON p.id_kazna = k.id_kazna
27 WHERE sz.id_na_zapisnik = v_id_zapisnik;
28
29
30 UPDATE Uplata
31 SET iznos = v_nov_iznos
32 WHERE id_zapisnik = v_id_zapisnik
33 AND status = 'Neplateno';
34
35 IF TG_OP = 'DELETE' THEN
36 RETURN OLD;
37 ELSE
38 RETURN NEW;
39 END IF;
40END;
41$$;
42
43
44
45CREATE OR REPLACE TRIGGER trigger_azuriraj_iznos_uplata
46 AFTER INSERT OR UPDATE OR DELETE ON Stavka_Zapisnik
47 FOR EACH ROW
48 EXECUTE FUNCTION azuriraj_iznos_uplata();
49
50
51
52
53--Trigger 2: Proverka na podatoci i zastita na dupli aktivni stanici vo Raboti_vo
54
55
56CREATE OR REPLACE FUNCTION proverka_raboti_vo_integritet()
57 RETURNS TRIGGER
58 LANGUAGE plpgsql
59AS $$
60BEGIN
61 IF NOT EXISTS (SELECT 1 FROM Policaec WHERE EMBG_P = NEW.EMBG_P) THEN
62 RAISE EXCEPTION 'Policaecot so EMBG % ne postoi vo sistemot!', NEW.EMBG_P;
63 END IF;
64
65 IF NEW.datum_od IS NULL THEN
66 RAISE EXCEPTION 'Pocetokot na rabotniot odnos (datum_od) mora da bide definiran!';
67 END IF;
68
69 IF NEW.datum_do IS NULL THEN
70 IF EXISTS (
71 SELECT 1 FROM Raboti_vo
72 WHERE EMBG_P = NEW.EMBG_P AND datum_do IS NULL AND id_stanica <> NEW.id_stanica
73 ) THEN
74 RAISE EXCEPTION 'Policaecot so EMBG % vekje ima aktiven angazhman vo druga stanica!', NEW.EMBG_P;
75 END IF;
76 END IF;
77
78 RETURN NEW;
79END;
80$$;
81
82CREATE OR REPLACE TRIGGER trigger_proverka_raboti_vo
83 BEFORE INSERT OR UPDATE ON Raboti_vo
84 FOR EACH ROW
85 EXECUTE FUNCTION proverka_raboti_vo_integritet();
86
87--Trigger 3: Proverka na EMBG,broj na shasija i format na tablica vo Registracija
88
89CREATE OR REPLACE FUNCTION proverka_registracija_integritet()
90 RETURNS TRIGGER
91 LANGUAGE plpgsql
92AS $$
93DECLARE
94 v_tablica text;
95BEGIN
96 IF NOT EXISTS (SELECT 1 FROM Sopstvenost WHERE id_sopstvenost = NEW.id_sopstvenost) THEN
97 RAISE EXCEPTION 'Sopstvenosta so id % ne postoi vo sistemot!', NEW.id_sopstvenost;
98 END IF;
99
100 IF NEW.id_tablica IS NOT NULL THEN
101 SELECT region || '-' || broj || '-' || kod
102 INTO v_tablica
103 FROM Registerska_tablica
104 WHERE id_tablica = NEW.id_tablica;
105
106 IF v_tablica IS NULL THEN
107 RAISE EXCEPTION 'Registerskata tablica so id % ne postoi!', NEW.id_tablica;
108 END IF;
109
110 IF NOT (UPPER(v_tablica) ~ '^[A-Z]{2,3}-[0-9]{3,4}-[A-Z]{2}$') THEN
111 RAISE EXCEPTION 'Registarskata tablica "%" ne e vo validen format! Ocekuvan format: ZZ-0000-ZZ', v_tablica;
112 END IF;
113 END IF;
114
115 RETURN NEW;
116END;
117$$;
118
119
120-----------------------------------------------------------------------------------------------
121
122--Procedure 1:Kreiranje na nov zapisnik i insert na soodvetni podatoci vo Stavka_Zapisnik i Uplata
123
124CREATE OR REPLACE PROCEDURE kreiraj_zapisnik_so_prekrsok(
125 p_embg_prekrsuvac char(13),
126 p_broj_sasija varchar(17),
127 p_embg_policaec char(13),
128 p_lokacija varchar(100),
129 p_id_slucaj int,
130 p_id_prekrsok int,
131 p_vreme time DEFAULT CURRENT_TIME,
132 p_datum date DEFAULT CURRENT_DATE,
133 p_potpis boolean DEFAULT false
134)
135 LANGUAGE plpgsql
136AS $$
137DECLARE
138 v_id_zapisnik int;
139BEGIN
140
141 IF NOT EXISTS (SELECT 1 FROM Gragjanin WHERE EMBG = p_embg_prekrsuvac) THEN
142 RAISE EXCEPTION 'Gragjaninot so EMBG % ne postoi!', p_embg_prekrsuvac;
143 END IF;
144
145 IF NOT EXISTS (SELECT 1 FROM Policaec WHERE EMBG_P = p_embg_policaec) THEN
146 RAISE EXCEPTION 'Policaecot so EMBG % ne postoi!', p_embg_policaec;
147 END IF;
148
149 IF NOT EXISTS (SELECT 1 FROM Vozilo WHERE broj_na_sasija = p_broj_sasija) THEN
150 RAISE EXCEPTION 'Voziloto so broj na sasija % ne postoi!', p_broj_sasija;
151 END IF;
152
153 IF NOT EXISTS (SELECT 1 FROM Prekrsok WHERE id_prekrsok = p_id_prekrsok) THEN
154 RAISE EXCEPTION 'Prekrsokot so id % ne postoi!', p_id_prekrsok;
155 END IF;
156
157 IF NOT EXISTS (SELECT 1 FROM Slucaj WHERE id_slucaj = p_id_slucaj) THEN
158 RAISE EXCEPTION 'Slucajot so id % ne postoi!', p_id_slucaj;
159 END IF;
160
161
162 INSERT INTO Zapisnik (
163 vreme, datum, lokacija, Potpis,
164 id_slucaj, EMBG_Prekrsuvach, Vozilo_Broj_Sasija, EMBG_Policaec
165 )
166 VALUES (
167 p_vreme, p_datum, p_lokacija, p_potpis,
168 p_id_slucaj, p_embg_prekrsuvac, p_broj_sasija, p_embg_policaec
169 )
170 RETURNING id_na_zapisnik INTO v_id_zapisnik;
171
172
173 INSERT INTO Uplata (iznos, status, Uplatil_Gragjanin, id_zapisnik)
174 VALUES (0, 'Neplateno', p_embg_prekrsuvac, v_id_zapisnik);
175
176
177 INSERT INTO Stavka_Zapisnik (reden_broj, id_na_zapisnik, id_na_prekrsok)
178 VALUES (1, v_id_zapisnik, p_id_prekrsok);
179
180 RAISE NOTICE 'Kreiran zapisnik so id % so prv prekrsok %.', v_id_zapisnik, p_id_prekrsok;
181END;
182$$;
183
184-----------------------------------------------------------------------------------------------
185
186--Procedure 2:Kreiranje na nova stavka na veke postoecki zapisnik i proverki vo validnost na podatoci
187
188CREATE OR REPLACE PROCEDURE dodadi_stavka_zapisnik(
189 p_id_zapisnik int,
190 p_id_prekrsok int
191)
192 LANGUAGE plpgsql
193AS $$
194DECLARE
195 v_reden_broj int;
196 v_status_uplata varchar(30);
197BEGIN
198
199 IF NOT EXISTS (SELECT 1 FROM Zapisnik WHERE id_na_zapisnik = p_id_zapisnik) THEN
200 RAISE EXCEPTION 'Zapisnikot so id % ne postoi!', p_id_zapisnik;
201 END IF;
202
203 IF NOT EXISTS (SELECT 1 FROM Prekrsok WHERE id_prekrsok = p_id_prekrsok) THEN
204 RAISE EXCEPTION 'Prekrsokot so id % ne postoi!', p_id_prekrsok;
205 END IF;
206
207
208 SELECT status INTO v_status_uplata
209 FROM Uplata
210 WHERE id_zapisnik = p_id_zapisnik;
211
212 IF v_status_uplata = 'Plateno' THEN
213 RAISE EXCEPTION 'Zapisnik % e vekje platen, ne moze da se dodavaat novi stavki!', p_id_zapisnik;
214 END IF;
215
216
217 SELECT COALESCE(MAX(reden_broj), 0) + 1 INTO v_reden_broj
218 FROM Stavka_Zapisnik
219 WHERE id_na_zapisnik = p_id_zapisnik;
220
221 INSERT INTO Stavka_Zapisnik (reden_broj, id_na_zapisnik, id_na_prekrsok)
222 VALUES (v_reden_broj, p_id_zapisnik, p_id_prekrsok);
223
224 RAISE NOTICE 'Dodadena stavka so reden_broj % vo zapisnik %.', v_reden_broj, p_id_zapisnik;
225END;
226$$;
227
228-----------------------------------------------------------------------------------------------
229--Procedure 3: Naplata na kazna vrzana za daden zapisnik, go menjava statusot na uplatata od 'Neplateno' vo 'Plateno'
230
231CREATE OR REPLACE PROCEDURE plati_kazna(
232 p_id_zapisnik int,
233 p_nacin_plakanje varchar(30)
234)
235 LANGUAGE plpgsql
236AS $$
237DECLARE
238 v_status varchar(30);
239 v_iznos numeric(10,2);
240BEGIN
241
242 SELECT status, iznos INTO v_status, v_iznos
243 FROM Uplata
244 WHERE id_zapisnik = p_id_zapisnik;
245
246 IF v_status IS NULL THEN
247 RAISE EXCEPTION 'Ne postoi uplata za zapisnik %!', p_id_zapisnik;
248 END IF;
249
250 IF v_status = 'Plateno' THEN
251 RAISE EXCEPTION 'Kaznata za zapisnik % e vekje platena!', p_id_zapisnik;
252 END IF;
253
254 IF v_iznos <= 0 THEN
255 RAISE EXCEPTION 'Zapisnikot % nema stavki/kazni za naplata!', p_id_zapisnik;
256 END IF;
257
258 IF p_nacin_plakanje NOT IN ('E-bankarstvo', 'Platezna karticka', 'Gotovo/Uplatnica') THEN
259 RAISE EXCEPTION 'Nepoznat nacin na plakanje: %. Dozvoleni: E-bankarstvo, Platezna karticka, Gotovo/Uplatnica.', p_nacin_plakanje;
260 END IF;
261
262
263 UPDATE Uplata
264 SET status = 'Plateno',
265 datum_uplata = CURRENT_DATE,
266 nacin_plakanje = p_nacin_plakanje
267 WHERE id_zapisnik = p_id_zapisnik;
268
269 RAISE NOTICE 'Uspesno naplatena kazna od % za zapisnik % (%).', v_iznos, p_id_zapisnik, p_nacin_plakanje;
270END;
271$$;
272
273
274
275--Procedure 4: Dodavanje na nova kategorija na postoecka vozacka
276
277REATE OR REPLACE PROCEDURE dodadi_kategorija_na_vozacka(
278 p_broj_dozvola varchar(30),
279 p_id_kategorija int,
280 p_datum_polaganje date DEFAULT CURRENT_DATE
281)
282 LANGUAGE plpgsql
283AS $$
284DECLARE
285 v_datum_vaznost_do date;
286 v_datum_izdavanje date;
287 v_kod_kategorija varchar(3);
288BEGIN
289
290 SELECT datum_vaznost_do, datum_izdavanje
291 INTO v_datum_vaznost_do, v_datum_izdavanje
292 FROM Vozacka_dozvola
293 WHERE broj_dozvola = p_broj_dozvola;
294
295 IF v_datum_vaznost_do IS NULL THEN
296 RAISE EXCEPTION 'Vozackata dozvola so broj % ne postoi!', p_broj_dozvola;
297 END IF;
298
299
300 IF v_datum_vaznost_do < CURRENT_DATE THEN
301 RAISE EXCEPTION 'Vozackata dozvola % e istechena (vaznost do %)! Mora prvo da se obnovi.',
302 p_broj_dozvola, v_datum_vaznost_do;
303 END IF;
304
305
306 SELECT kod INTO v_kod_kategorija
307 FROM Kategorija
308 WHERE id_kategorija = p_id_kategorija;
309
310 IF v_kod_kategorija IS NULL THEN
311 RAISE EXCEPTION 'Kategorijata so id % ne postoi!', p_id_kategorija;
312 END IF;
313
314
315 IF EXISTS (
316 SELECT 1 FROM Kategorija_Vozacka_dozvola
317 WHERE broj_dozvola = p_broj_dozvola
318 AND id_kategorija = p_id_kategorija
319 ) THEN
320 RAISE EXCEPTION 'Kategorijata % vekje e dodadena na vozackata %!',
321 v_kod_kategorija, p_broj_dozvola;
322 END IF;
323
324
325 IF p_datum_polaganje > CURRENT_DATE THEN
326 RAISE EXCEPTION 'Datumot na polaganje % ne moze da bide vo idnina!', p_datum_polaganje;
327 END IF;
328
329 IF p_datum_polaganje < v_datum_izdavanje THEN
330 RAISE EXCEPTION 'Datumot na polaganje % ne moze da bide pred izdavanjeto na vozackata (%).',
331 p_datum_polaganje, v_datum_izdavanje;
332 END IF;
333
334
335 INSERT INTO Kategorija_Vozacka_dozvola (id_kategorija, broj_dozvola, datum_polaganje)
336 VALUES (p_id_kategorija, p_broj_dozvola, p_datum_polaganje);
337
338 RAISE NOTICE 'Uspesno dodadena kategorija % na vozackata % (polagano na %).',
339 v_kod_kategorija, p_broj_dozvola, p_datum_polaganje;
340END;
341$$;
342
343
344--Procedure 5: Zatvoranje na zapisnik po izvrsena uplata
345
346CREATE OR REPLACE PROCEDURE zatvori_zapisnik_po_uplata(
347 p_id_zapisnik int
348)
349 LANGUAGE plpgsql
350AS $$
351DECLARE
352 v_status_uplata varchar(30);
353 v_status_zapisnik varchar(20);
354BEGIN
355
356 SELECT status_zapisnik INTO v_status_zapisnik
357 FROM Zapisnik
358 WHERE id_na_zapisnik = p_id_zapisnik;
359
360 IF v_status_zapisnik IS NULL THEN
361 RAISE EXCEPTION 'Zapisnikot so id % ne postoi!', p_id_zapisnik;
362 END IF;
363
364 IF v_status_zapisnik = 'Zatvoren' THEN
365 RAISE EXCEPTION 'Zapisnikot % e vekje zatvoren!', p_id_zapisnik;
366 END IF;
367
368
369 SELECT status INTO v_status_uplata
370 FROM Uplata
371 WHERE id_zapisnik = p_id_zapisnik;
372
373 IF v_status_uplata IS NULL THEN
374 RAISE EXCEPTION 'Ne postoi uplata za zapisnik %!', p_id_zapisnik;
375 END IF;
376
377 IF v_status_uplata <> 'Plateno' THEN
378 RAISE EXCEPTION 'Zapisnikot % ne moze da se zatvori bidejki uplatata e so status "%" (mora da bide Plateno)!',
379 p_id_zapisnik, v_status_uplata;
380 END IF;
381
382
383 UPDATE Zapisnik
384 SET status_zapisnik = 'Zatvoren'
385 WHERE id_na_zapisnik = p_id_zapisnik;
386
387 RAISE NOTICE 'Zapisnik % e zatvoren po izvrshena uplata.', p_id_zapisnik;
388END;
389$$;
390
391
392
393--test za proceduri, trigeri i funckija
394--proverka za procedura 1: kreiranje zapisnik
395CALL kreiraj_zapisnik_so_prekrsok(
396 '1508004480145',
397 'CE8C5F1D5AA4C0871',
398 '1609966470237',
399 'Bulevar Partizanski Odredi',
400 1,
401 1
402);
403
404select *
405from zapisnik vsz
406where vsz.embg_prekrsuvach='1508004480145';
407
408--proverka za procedura 2: dodavannje stavka na zapisnikot
409CALL dodadi_stavka_zapisnik(30000005, 3);
410
411select * from stavka_zapisnik sz
412where sz.id_na_zapisnik =30000005;
413
414--proverka za procedura 3: plakanje na kazna
415CALL plati_kazna(30000005, 'E-bankarstvo');
416
417select * from uplata u
418where u.id_zapisnik =30000005;
419
420
421--proverka za procedura 4:Dodavanje nova kategorija na postoechka vozacka dozvola
422-- (npr. vozacot polozhi kategorija C - id_kategorija = 7)
423CALL dodadi_kategorija_na_vozacka('L8207294', 7);
424--proverka za procedura 5: zatvoranje na zapisnik po plakanje
425CALL zatvori_zapisnik_po_uplata(30000005)
426
427-- so naveduvanje na datumot na polaganje:
428CALL dodadi_kategorija_na_vozacka('L8207294', 9, '2025-11-15');
429
430
431select * from kategorija_vozacka_dozvola kvd
432where kvd.broj_dozvola ='L8207294'
433
434
435
436
437
438-----------------Funkcija za scheduled update na kazni so pominat rok za 50 %
439
440
441CREATE OR REPLACE FUNCTION azuriraj_kazna_plakanja()
442 RETURNS text
443 LANGUAGE plpgsql
444AS $$
445BEGIN
446
447 UPDATE Uplata u
448 SET iznos = u.iznos + (u.iznos * 0.50),
449 kazna_zgolemena = true
450 FROM Zapisnik z
451 WHERE u.id_zapisnik = z.id_na_zapisnik
452 AND u.status = 'Neplateno'
453 AND u.kazna_zgolemena = false
454 AND z.datum < CURRENT_DATE - INTERVAL '8 days';
455
456
457 UPDATE Uplata u
458 SET status = 'Sudska_postapka'
459 FROM Zapisnik z
460 WHERE u.id_zapisnik = z.id_na_zapisnik
461 AND u.status = 'Neplateno'
462 AND z.datum < CURRENT_DATE - INTERVAL '2 months';
463
464
465 RETURN 'Постапката за автоматско ажурирање на неплатените казни е успешно извршена.';
466END;
467$$;
468
469
470
471-------------test za funkcija 2----
472
473
474SELECT azuriraj_kazna_plakanja();
475select * from Uplata;
476
477
478