Transakčná funkcia

Transakčná funkcia

Jednoduchá funkcia, ktorá pomáha pri transakciách peňazí medzi dvoma užívateľmi.
Funkcia kontroluje, či je možné previesť danú čiastku a podobne.

Dostupné online:
REXtester

Štruktúra DB - Diagram

audit_trigger_diagram

Vytvorenie tabulky a jej naplnenie

1
2
3
4
5
6
7
8
CREATE TABLE ucty (
majitel_uctu TEXT,
zostatok NUMERIC,
ciastka NUMERIC
);
INSERT INTO ucty VALUES ('Rob', 100);
INSERT INTO ucty VALUES ('Maria', 200);

Transakcia

Takto by vyzeralo prevedenie transakcie medzi dvoma účtami. Na jeden účet suma pribudne a z druhého ubudne.

1
2
3
4
5
6
UPDATE ucty
SET zostatok = zostatok - 14.00
WHERE majitel_uctu = 'Rob';
UPDATE ucty
SET zostatok = zostatok + 14.00
WHERE majitel_uctu = 'Maria';

Riešenie pomocou UPDATE má však veľa chýb. K príkladu, čo by sa stalo keby Rob nemal dostatok financií (kreditu) na učte? Jeho financie by šli do mínusu a to je nechcený stav.

Funkcia

Jednoduché riešenie kontroly integrity pomocou funkcie v PL/pgSQL. Funkcia ma tri argumenty platcu, príjemcu a čiastku, ktorá poputuje z účtu na účet. Funkcia taktiež vracia stav platby.

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
CREATE OR REPLACE FUNCTION transakcia(
i_platca TEXT,
i_prijemca TEXT,
-- Numeric(15,2) znamena ze max 15 cisel a 2 decimalne
i_ciastka NUMERIC(15, 2))
RETURNS TEXT
AS
$$
DECLARE
platca_zostatok NUMERIC;
BEGIN
SELECT zostatok
INTO platca_zostatok
FROM ucty
WHERE majitel_uctu = i_platca
FOR UPDATE;
IF NOT FOUND
THEN
RETURN 'Ucet platcu nenajdeny';
END IF;
IF platca_zostatok < i_ciastka
THEN
RETURN 'Nedostatok prostriedkov';
END IF;
UPDATE ucty
SET zostatok = zostatok + i_ciastka
WHERE majitel_uctu = i_prijemca;
IF NOT FOUND
THEN
RETURN 'Prijemca neexistuje';
END IF;
UPDATE ucty
SET zostatok = zostatok - i_ciastka
WHERE majitel_uctu = i_platca;
RETURN 'OK';
END;
$$ LANGUAGE plpgsql;

Test

Názorné použitie funkcie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT * FROM ucty;
majitel_uctu | zostatok
-------+---------
Rob | 100
Maria | 200
(2 rows)
SELECT transakcia('Rob','Maria',14.00);
transakcia
----------
OK
(1 row)
SELECT * FROM ucty;
majitel_uctu | zostatok
-------+---------
Maria | 214.00
Rob | 86.00
(2 rows)

Testovanie chýb pri transakcií:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT * FROM transakcia('Fred','Maria',14.00);
transakcia
-------------------------
Ucet platcu nenajdeny
(1 row)
SELECT * FROM transakcia('Rob','Fred',14.00);
transakcia
-------------------------
Prijemca neexistuje
(1 row)
SELECT * FROM transakcia('Rob','Maria',500.00);
transakcia
-------------------------
Nedostatok prostriedkov
(1 row)