This commit is contained in:
2025-11-03 07:06:56 +01:00
parent 1a06ea5bf2
commit 23e28fb2d8
2 changed files with 113 additions and 13 deletions

View File

@@ -64,7 +64,7 @@ La banque souhaite désormais que toute personne titulaire dun compte ait au
- Un compte bancaire doit pouvoir appartenir à un ou plusieurs titulaires (compte individuel / compte joint).
- Chaque compte dispose dun numéro de compte (_account number_) unique, dun solde, d'une date d'ouverture et une date de clôture.
- Le solde des comptes ne peuvent être négatifs.
- Dans le cas d'un compte joint, les parts de propriété d'un compte doivent pouvoir être précisées.
- Dans le cas d'un compte joint, les parts (_share_) de propriété d'un compte doivent pouvoir être précisées.
### 2.1 Exemple de données
@@ -221,10 +221,6 @@ create table account_holder (
* la procédure doit lever une **erreur explicite** (`RAISE EXCEPTION`) ;
* aucune insertion ne doit être faite (transaction annulée).
---
## 💡 Aide
* Les tableaux peuvent être parcourus avec une boucle :
```sql
@@ -249,33 +245,30 @@ create table account_holder (
---
## Exemple dappel
### Cas valide :
### Exemples dappel
```sql
call create_account(
'FR761234567890',
'Compte commun',
array[1, 2],
array[1, 5],
array[0.5, 0.5]
);
```
➡️ Crée un compte partagé 50/50 entre les titulaires 1 et 2.
Crée un compte partagé 50/50 entre les titulaires 1 et 2.
### Cas invalide :
```sql
call create_account(
'FR009999999999',
'Compte déséquilibré',
array[1, 2],
array[1, 5],
array[0.7, 0.4]
);
```
Doit refuser la création avec une erreur claire :
Doit refuser la création avec une erreur claire :
```
ERROR: La somme des parts (1.1000) doit être égale à 1.0000

View File

@@ -234,6 +234,7 @@ begin
end if;
-- Calcul de la somme des parts
-- select sum(unnest(p_shares)) into v_sum;
for i in 1..array_length(p_shares, 1) loop
v_sum := v_sum + p_shares[i];
end loop;
@@ -264,3 +265,109 @@ begin
end;
$$;
create or replace procedure record_operation(
p_account_id int,
p_kind text,
p_amount numeric,
p_description text default null
)
language plpgsql
as $$
declare
v_balance numeric(12,2);
begin
-- Vérification du type dopération
if p_kind not in ('DEPOSIT', 'WITHDRAWAL') then
raise exception 'Type dopération invalide : % (attendu: DEPOSIT ou WITHDRAWAL)', p_kind;
end if;
-- Vérification que le compte existe
if not exists (select 1 from account where id = p_account_id) then
raise exception 'Le compte % nexiste pas.', p_account_id;
end if;
-- Calcul du solde actuel
select coalesce(sum(case when kind = 'DEPOSIT' then amount else -amount end), 0)
into v_balance
from operation
where account_id = p_account_id;
-- Vérification du solde si retrait
if p_kind = 'WITHDRAWAL' and v_balance < p_amount then
raise exception 'Fonds insuffisants : solde actuel %.2f, retrait demandé %.2f',
v_balance, p_amount;
end if;
-- Insertion de lopération
insert into operation(account_id, kind, amount, description)
values (p_account_id, p_kind, p_amount, p_description);
raise notice 'Opération enregistrée : % de %.2f sur compte %',
p_kind, p_amount, p_account_id;
end;
$$;
CREATE TABLE transaction (
id SERIAL PRIMARY KEY,
account_id INT NOT NULL REFERENCES account(id),
amount NUMERIC(12, 2) NOT NULL CHECK (amount <> 0),
operation_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE OR REPLACE PROCEDURE deposit(p_account_id INT, p_amount NUMERIC)
LANGUAGE plpgsql
AS $$
BEGIN
IF p_amount <= 0 THEN
RAISE EXCEPTION 'Deposit amount must be positive';
END IF;
UPDATE account
SET balance = balance + p_amount
WHERE id = p_account_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Account % not found', p_account_id;
END IF;
INSERT INTO transaction (account_id, amount)
VALUES (p_account_id, p_amount);
END;
$$;
CREATE OR REPLACE PROCEDURE withdraw(p_account_id INT, p_amount NUMERIC)
LANGUAGE plpgsql
AS $$
DECLARE
current_balance NUMERIC;
BEGIN
IF p_amount <= 0 THEN
RAISE EXCEPTION 'Withdraw amount must be positive';
END IF;
SELECT balance INTO current_balance
FROM account
WHERE id = p_account_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Account % not found', p_account_id;
END IF;
IF current_balance < p_amount THEN
RAISE EXCEPTION 'Insufficient funds: balance = %, attempted withdrawal = %',
current_balance, p_amount;
END IF;
UPDATE account
SET balance = balance - p_amount
WHERE id = p_account_id;
INSERT INTO transaction (account_id, amount)
VALUES (p_account_id, -p_amount);
END;
$$;