-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.sql
67 lines (57 loc) · 1.77 KB
/
init.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
DROP TABLE IF EXISTS clientes;
DROP TABLE IF EXISTS transacoes;
CREATE TABLE IF NOT EXISTS clientes (
id INTEGER PRIMARY KEY,
limite INTEGER NOT NULL,
saldo INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS transacoes (
id SERIAL PRIMARY KEY,
cliente_id INTEGER NOT NULL,
tipo CHAR(1) NOT NULL,
valor INTEGER NOT NULL,
descricao VARCHAR(10) NOT NULL,
realizada_em TIMESTAMPTZ NOT NULL
);
CREATE INDEX ON transacoes (cliente_id, realizada_em DESC);
INSERT INTO clientes
(id, limite, saldo)
VALUES
(1, 100000, 0),
(2, 80000, 0),
(3, 1000000, 0),
(4, 10000000, 0),
(5, 500000, 0);
CREATE OR REPLACE FUNCTION update_saldo_cliente(id INT, valor INT, tipo VARCHAR, descricao VARCHAR)
RETURNS TABLE(new_saldo INT, limite INT) AS $$
DECLARE
saldo INTEGER;
limite INTEGER;
new_saldo INTEGER;
BEGIN
SELECT c.saldo, c.limite INTO saldo, limite
FROM clientes c
WHERE c.id = update_saldo_cliente.id FOR UPDATE;
IF NOT FOUND THEN
RAISE EXCEPTION 'Cliente with ID % does not exist', id USING ERRCODE = 'P0002';
END IF;
IF update_saldo_cliente.tipo = 'd' THEN
new_saldo := saldo - update_saldo_cliente.valor;
IF new_saldo + limite < 0 THEN
RAISE EXCEPTION 'Updating saldo failed: new saldo exceeds the limit' USING ERRCODE = 'P0000';
END IF;
ELSE
new_saldo := saldo + update_saldo_cliente.valor;
END IF;
UPDATE clientes c SET saldo = new_saldo WHERE c.id = update_saldo_cliente.id;
INSERT INTO transacoes (cliente_id, tipo, valor, descricao, realizada_em)
VALUES (
update_saldo_cliente.id,
update_saldo_cliente.tipo,
update_saldo_cliente.valor,
update_saldo_cliente.descricao,
CURRENT_TIMESTAMP
);
RETURN QUERY SELECT new_saldo, limite;
END;
$$ LANGUAGE plpgsql;