Files
sql/banque.md

667 lines
17 KiB
Markdown
Raw Normal View History

2025-11-02 14:36:58 +01:00
# Modélisation d'un système bancaire
2025-11-02 09:24:15 +01:00
2025-11-05 07:43:14 +01:00
Une banque locale souhaite informatiser la gestion de ses titulaires et de leurs comptes.
Vous êtes chargé(e) de concevoir et dimplémenter le schéma relationnel de base permettant de gérer :
1. Les clients de la banque,
2. Les comptes bancaires,
2025-11-06 09:35:06 +01:00
3. Le lien entre les clients et les comptes.
2025-11-05 13:47:17 +01:00
4. Les dépots et les retraits d'argent.
5. Les virements entre compte.
6. Les devises et les taux de change.
2025-11-05 07:43:14 +01:00
L'objectif de ces travaux pratiques est de :
2025-11-02 14:36:58 +01:00
- Concevoir un **modèle relationnel** à partir dun scénario réaliste.
- Utiliser les **contraintes dintégrité** pour garantir la cohérence des données.
- Manipuler des **jointures** et des **relations nn**.
- Comprendre la notion d**héritage logique** en base de données.
2025-11-05 07:43:14 +01:00
La diffusion de cette application est internationale, vous vous efforcerez d'utiliser des termes anglais pour nommer les entités et les propriétés. Réferrez pour cela vous au [glossaire](banque.glossaire.md)
2025-11-02 14:36:58 +01:00
2025-11-05 07:43:14 +01:00
Pour les entités vous utiliserez le singuler et écrirez le tout en minuscule.
2025-11-02 14:36:58 +01:00
2025-11-07 07:13:51 +01:00
## Séance 1 : Le Diagramme Entités Relations (ERD)
2025-11-06 09:35:06 +01:00
### 1. Les titulaires
2025-11-02 14:36:58 +01:00
2025-11-07 08:45:54 +01:00
Un client de la banque est appelé un titulaire. Il peut être une **personne physique** ou une **entreprise**.
2025-11-02 14:36:58 +01:00
- Quelles informations faut-il conserver pour tous les titulaires ?
- Quelles informations sont spécifiques à chaque type de titulaire ?
- Comment représenter cette distinction en base relationnelle ?
> [!TIP]
> Indice : on peut utiliser une table abstraite `holder`, puis des tables `person` et `company` qui héritent logiquement de celle-ci.
2025-11-03 13:42:34 +01:00
#### Pourquoi séparer `person` et `company` ?
2025-11-02 14:36:58 +01:00
2025-11-03 13:42:34 +01:00
Parce que leurs attributs diffèrent (nom/prénom vs raison sociale).
Cela évite les **colonnes inutiles** et permet des **contraintes spécifiques** à chaque type.
2025-11-02 14:36:58 +01:00
2025-11-03 13:42:34 +01:00
#### Quelle contrainte empêche dinsérer une person sans holder ?
2025-11-02 14:36:58 +01:00
2025-11-03 13:42:34 +01:00
La clé étrangère `references holder(id)` dans `person`.
2025-11-02 14:36:58 +01:00
2025-11-05 16:25:35 +01:00
```mermaid
erDiagram
2025-11-08 06:15:58 +01:00
person {
bigint id PK
text firstname
text lastname
date birthdate
}
company {
bigint id PK
text name
text registration_number
date creation_date
}
holder {
bigint id PK
timestamp creation_date
text type
}
2025-11-05 16:25:35 +01:00
2025-11-06 06:51:21 +01:00
%% Relations
2025-11-05 16:25:35 +01:00
2025-11-06 09:35:06 +01:00
person |o--|| holder : is
company |o--|| holder : is
2025-11-05 16:25:35 +01:00
```
2025-11-07 07:13:51 +01:00
### 2. Les comptes
2025-11-02 14:36:58 +01:00
2025-11-07 08:58:35 +01:00
- Chaque titulaire peut détenir **un** ou **plusieurs comptes**.
- Un compte bancaire doit pouvoir appartenir à **un** ou **plusieurs titulaires** (compte individuel / compte joint).
- Chaque compte dispose dun numéro de compte unique, dun solde et d'une date d'ouverture.
- Dans le cas d'un compte joint, les parts de propriété d'un compte doivent pouvoir être précisées.
2025-11-02 16:21:22 +01:00
2025-11-07 07:03:42 +01:00
```mermaid
erDiagram
person {
bigint id PK
text firstname
text lastname
date birthdate
}
2025-11-02 16:21:22 +01:00
2025-11-07 07:03:42 +01:00
company {
bigint id PK
2025-11-07 14:44:02 +01:00
text name
2025-11-07 07:03:42 +01:00
text registration_number
date creation_date
}
holder {
bigint id PK
2025-11-07 14:41:11 +01:00
timestamp creation_date
2025-11-07 07:03:42 +01:00
text type
}
account {
bigint id PK
2025-11-07 18:33:08 +01:00
timestamp creation_date
2025-11-07 07:03:42 +01:00
decimal balance
}
account_holder {
bigint account_id FK
bigint holder_id FK
decimal share
}
2025-11-02 20:50:39 +01:00
2025-11-07 07:03:42 +01:00
%% Relations
person |o--|| holder : is
company |o--|| holder : is
holder }|--|{ account_holder : a
2025-11-08 06:15:58 +01:00
account_holder ||--|{ account : hold
2025-11-07 07:03:42 +01:00
```
### 3. Les opérations
2025-11-02 20:50:39 +01:00
2025-11-06 06:51:21 +01:00
```mermaid
erDiagram
person {
bigint id PK
text firstname
text lastname
date birthdate
}
company {
bigint id PK
2025-11-07 14:44:02 +01:00
text name
2025-11-06 09:35:06 +01:00
text registration_number
2025-11-06 06:51:21 +01:00
date creation_date
}
2025-11-07 18:33:08 +01:00
bank {
bigint id PK
text name
}
2025-11-06 06:51:21 +01:00
holder {
bigint id PK
2025-11-07 14:41:11 +01:00
timestamp creation_date
2025-11-06 09:35:06 +01:00
text type
2025-11-06 06:51:21 +01:00
}
account {
bigint id PK
2025-11-07 18:33:08 +01:00
timestamp creation_date
2025-11-06 07:17:31 +01:00
decimal balance
2025-11-06 06:51:21 +01:00
text currency_code FK
}
account_holder {
bigint account_id FK
bigint holder_id FK
2025-11-06 07:17:31 +01:00
decimal share
2025-11-06 06:51:21 +01:00
}
2025-11-07 07:03:42 +01:00
2025-11-06 09:35:06 +01:00
operation {
2025-11-06 06:51:21 +01:00
bigint id PK
2025-11-06 09:35:06 +01:00
bigint transaction_id FK
2025-11-07 18:33:08 +01:00
bigint account_id FK
2025-11-06 06:51:21 +01:00
decimal amount
2025-11-06 09:35:06 +01:00
text direction
2025-11-06 06:51:21 +01:00
}
2025-11-06 09:35:06 +01:00
%% Relations
person |o--|| holder : is
company |o--|| holder : is
bank |o--|| holder : is
2025-11-07 07:03:42 +01:00
holder }|--|{ account_holder : a
2025-11-08 06:15:58 +01:00
account_holder ||--|{ account : hold
2025-11-07 07:03:42 +01:00
operation }o--|| account : concerne
2025-11-06 09:35:06 +01:00
```
2025-11-06 10:01:02 +01:00
### 4. Les transactions
2025-11-07 07:13:51 +01:00
#### La double écriture comptable
Jusquà présent, les dépôts et retraits modifiaient directement le solde dun compte.
Mais dans un vrai système bancaire ou comptable, chaque opération financière doit être enregistrée en double :
- Un débit sur un compte (celui qui reçoit)
- Un crédit sur un autre (celui qui cède)
La somme des débits doit toujours être égale à la somme des crédits.
2025-11-06 10:01:02 +01:00
Chaque opération comporte au moins :
* un **compte concerné** ;
* une **date** ;
* un **montant** ;
* un **sens** (débit ou crédit).
2025-11-07 13:07:30 +01:00
#### Méthode 1 : montant relatif (positif/négatif)
2025-11-06 10:01:02 +01:00
2025-11-07 07:03:42 +01:00
On stocke un seul champ `montant`.
* **Crédit** → montant positif
* **Débit** → montant négatif
2025-11-07 07:13:51 +01:00
##### Exemple
2025-11-06 10:01:02 +01:00
| id | compte | date | montant |
| -- | ------ | ---------- | ------- |
| 1 | 123 | 2025-11-06 | +200.00 |
| 2 | 123 | 2025-11-07 | -50.00 |
2025-11-07 07:13:51 +01:00
##### Avantages
2025-11-06 10:01:02 +01:00
* **Simple à manipuler** pour les calculs (sommes, soldes, agrégations).
* Pas besoin de colonne supplémentaire pour le sens.
* Représente naturellement le comportement du solde dun compte.
2025-11-07 07:13:51 +01:00
##### Inconvénients
2025-11-06 10:01:02 +01:00
* Le **signe a une signification métier** implicite → risque derreur dinterprétation.
* **Moins lisible** pour les utilisateurs finaux ou pour des exports comptables.
* Pas toujours compatible avec les règles de la **comptabilité en partie double** (où débit et crédit doivent être visibles séparément).
2025-11-07 13:07:30 +01:00
#### Méthode 2 : deux colonnes (débit / crédit)
2025-11-06 10:01:02 +01:00
2025-11-07 07:03:42 +01:00
Deux colonnes numériques, lune pour le débit, lautre pour le crédit.
Une seule des deux contient une valeur non nulle.
2025-11-07 07:13:51 +01:00
##### Exemple
2025-11-06 10:01:02 +01:00
| id | compte | date | debit | credit |
| -- | ------ | ---------- | ----- | ------ |
| 1 | 123 | 2025-11-06 | 0.00 | 200.00 |
| 2 | 123 | 2025-11-07 | 50.00 | 0.00 |
2025-11-07 07:13:51 +01:00
##### Avantages
2025-11-06 10:01:02 +01:00
* Très **clair visuellement** et **conforme aux usages comptables**.
* Facilite les **exports vers des logiciels comptables**.
* On peut facilement filtrer les débits et crédits séparément.
2025-11-07 07:13:51 +01:00
##### Inconvénients
2025-11-06 10:01:02 +01:00
* **Redondance potentielle** (une des deux colonnes sera toujours à zéro).
* Les calculs de soldes nécessitent des **expressions plus complexes** :
`SUM(credit) - SUM(debit)`
* Risque dincohérence si les deux colonnes contiennent des valeurs remplies par erreur.
2025-11-07 13:07:30 +01:00
#### Méthode 3 : montant absolu + colonne sens ('D' / 'C')
2025-11-06 10:01:02 +01:00
2025-11-07 07:03:42 +01:00
Le montant est toujours positif.
Le sens est indiqué par une lettre (`D` ou `C`).
2025-11-07 07:13:51 +01:00
##### Exemple
2025-11-06 10:01:02 +01:00
| id | compte | date | montant | sens |
| -- | ------ | ---------- | ------- | ---- |
| 1 | 123 | 2025-11-06 | 200.00 | C |
| 2 | 123 | 2025-11-07 | 50.00 | D |
2025-11-07 07:13:51 +01:00
##### Avantages
2025-11-06 10:01:02 +01:00
* **Lisible** et **intuitif** : correspond au vocabulaire métier.
* Facilite la lecture humaine et les exports comptables.
* Pas dambiguïté sur le signe numérique.
2025-11-07 07:13:51 +01:00
##### Inconvénients
2025-11-06 10:01:02 +01:00
* Nécessite une **jointure logique** du sens pour les calculs :
`SUM(CASE WHEN sens='C' THEN montant ELSE -montant END)`
* Moins direct pour les traitements purement mathématiques.
* Lusage de lettres rend le **stockage un peu moins compact** (mais négligeable en pratique).
2025-11-07 13:07:30 +01:00
#### Méthode 4 : montant absolu + colonne sens numérique (1 / -1)
2025-11-06 10:01:02 +01:00
2025-11-07 07:03:42 +01:00
Le montant est toujours positif, et une colonne numérique `sens` vaut `1` (crédit) ou `-1` (débit).
2025-11-07 07:13:51 +01:00
##### Exemple
2025-11-06 10:01:02 +01:00
| id | compte | date | montant | sens |
| -- | ------ | ---------- | ------- | ---- |
| 1 | 123 | 2025-11-06 | 200.00 | 1 |
| 2 | 123 | 2025-11-07 | 50.00 | -1 |
2025-11-07 07:13:51 +01:00
##### Avantages
2025-11-06 10:01:02 +01:00
* **Compact et performant** pour les calculs :
`SUM(montant * sens)` donne directement le solde.
* Moins dambiguïté quun signe caché dans le montant.
* Combine la **rigueur du modèle mathématique** avec la **clarté du stockage absolu**.
2025-11-07 07:13:51 +01:00
##### Inconvénients
2025-11-06 10:01:02 +01:00
* **Moins lisible** pour un utilisateur non technique.
* Moins standard pour la comptabilité classique (on préfère `D` / `C`).
* Nécessite une convention claire sur la signification de `1` et `-1`.
2025-11-07 07:13:51 +01:00
#### Synthèse comparative
2025-11-06 10:01:02 +01:00
2025-11-07 08:58:35 +01:00
| Méthode | Structure | Lisibilité | Facilité calculs | Conformité comptable | Risque d'erreur |
| ------- | ---------------------- | ------------| ---------------- | -------------------- | --------------- |
2025-11-06 10:01:02 +01:00
| 1 | montant relatif (+/-) | ★☆☆ | ★★★ | ★☆☆ | Moyen |
| 2 | débit / crédit séparés | ★★★ | ★☆☆ | ★★★ | Faible |
| 3 | valeur + sens 'D'/'C' | ★★★ | ★★☆ | ★★★ | Faible |
| 4 | valeur + sens 1/-1 | ★★☆ | ★★★ | ★★☆ | Moyen |
### 5. Les devises
2025-11-06 09:35:06 +01:00
```mermaid
erDiagram
person {
bigint id PK
text firstname
text lastname
date birthdate
}
company {
bigint id PK
2025-11-07 14:44:02 +01:00
text name
2025-11-06 09:35:06 +01:00
text registration_number
date creation_date
}
bank {
bigint id PK
2025-11-07 14:41:11 +01:00
text name
2025-11-06 09:35:06 +01:00
}
holder {
bigint id PK
2025-11-07 14:41:11 +01:00
timestamp creation_date
2025-11-06 09:35:06 +01:00
text type
2025-11-06 06:51:21 +01:00
}
2025-11-06 09:35:06 +01:00
account {
bigint id PK
2025-11-07 18:33:08 +01:00
timestamp creation_date
2025-11-06 09:35:06 +01:00
decimal balance
text currency_code FK
}
account_holder {
2025-11-07 21:29:15 +01:00
bigint account_id PK,FK
bigint holder_id PK,FK
2025-11-06 09:35:06 +01:00
decimal share
}
2025-11-07 07:03:42 +01:00
2025-11-06 06:51:21 +01:00
currency {
text code PK
}
2025-11-06 06:58:42 +01:00
exchange_rate {
date date PK
2025-11-07 21:29:15 +01:00
text currency_code PK,FK
2025-11-06 06:58:42 +01:00
decimal rate
}
2025-11-06 06:51:21 +01:00
2025-11-06 07:13:27 +01:00
transaction {
bigint id PK
2025-11-07 20:55:42 +01:00
timestamp transaction_date
2025-11-06 07:13:27 +01:00
decimal amount
}
2025-11-06 07:17:31 +01:00
operation {
bigint id PK
2025-11-06 09:35:06 +01:00
bigint transaction_id FK
2025-11-07 17:33:51 +01:00
bigint account_id FK
2025-11-06 07:17:31 +01:00
decimal amount
text direction
}
2025-11-06 06:58:42 +01:00
%% Relations
2025-11-06 06:51:21 +01:00
2025-11-06 09:35:06 +01:00
person |o--|| holder : is
company |o--|| holder : is
bank |o--|| holder : is
2025-11-06 07:22:45 +01:00
holder }|--|{ account_holder : a
2025-11-08 06:15:58 +01:00
account_holder ||--|{ account : hold
2025-11-06 07:27:31 +01:00
currency ||--|{ account : tenu
2025-11-06 07:22:45 +01:00
exchange_rate }o--|| currency : a
2025-11-08 13:10:09 +01:00
transaction ||--|{ operation : a
operation }o--|| account : a
2025-11-06 06:51:21 +01:00
```
2025-11-07 07:03:42 +01:00
---
2025-11-07 13:07:30 +01:00
# Séance 2 : Implémentation du modèle
2025-11-07 13:49:27 +01:00
Voir les adresses des serveurs [postgreSQL](https://sources.neotech.fr/Universite/tp/src/branch/main/geii3_2025.md)
2025-11-08 05:51:25 +01:00
Voir la syntaxe de [postgreSQL](syntaxe.md)
2025-11-07 07:45:45 +01:00
### 1. Titulaires
2025-11-07 07:03:42 +01:00
2025-11-08 13:10:09 +01:00
Création de la table `holder`.
```sql
create table holder (
"id" bigint primary key generated always as identity,
"type" text,
"created_at" timestamp
);
```
- entier sur 64 bits : `bigint`
- clé primaire : `primary key`
- incrément automatique : `generated always as identity`
Création de la table `person`.
```sql
create table person (
"id" bigint primary key references holder(id),
"firstname" text,
"lastname" text,
"birthdate" date
);
```
2025-11-07 08:45:54 +01:00
- Créer un compte individuel pour _Françoise Zanetti_, née le 12 avril 1995.
- Créer une entreprise nommée _Boulangerie de Valorgue_, créée le 19 août 2014, numéro dimmatriculation FR19803269968.
- Ajouter un nouveau titulaire : _Justin Hébrard_ né le 11/03/1993.
2025-11-07 07:03:42 +01:00
2025-11-08 14:56:53 +01:00
```sql
create table bank (
"id" bigint primary key references holder(id),
"name" text
);
```
```sql
insert into holder (type) values ('BANK') returning holder;
```
```sql
2025-11-09 10:26:00 +01:00
insert into bank (id, name) values (10, 'Banque de l''Est');
2025-11-08 14:56:53 +01:00
```
2025-11-07 07:45:45 +01:00
#### 1.1 Contraintes à respecter
- Chaque `person` ou `company` doit correspondre à exactement un seul `holder`.
- La suppression dun `holder` doit supprimer automatiquement la ligne correspondante dans `person` ou `company`.
2025-11-08 05:51:25 +01:00
- La banque souhaite désormais que toute personne titulaire dun compte ait au moins 15 ans à la date de création de sa fiche. Il n'y a pas de restriction sur l'âge de la société.
2025-11-07 07:45:45 +01:00
- Le type doit être contraint à `'PERSON'` ou `'COMPANY'`.
2025-11-07 11:11:08 +01:00
Il existe deux méthodes pour gérer le type.
1. vérifier par la commande `CHECK` la validité de la valeur.
2. utiliser une énumération `enum`.
2025-11-09 10:26:00 +01:00
```sql
create type holder_type as enum ('BANK', 'PERSON', 'COMPANY');
```
2025-11-07 11:11:08 +01:00
2025-11-07 07:45:45 +01:00
#### 1.2 Vérifications
2025-11-06 09:35:06 +01:00
- Lister tous les titulaires. Pour réutiliser rapidement la requête enregistrer la dans une vue.
- Supprimer un titulaire, vérifier que cela supprime l'individu ou la société correspondante.
2025-11-07 13:07:30 +01:00
#### 1.4 L'intégrité des données
2025-11-06 09:35:06 +01:00
Lorsque lon tente d'insèrer une nouvelle personne qui n'a pas l'âge requis. La ligne dans `holder` est d'abord créée, puis l'insertion dans `person` échoue à cause de la vérification d'âge. Mais la ligne du titulaire est toujours présente **sans être rattachée** à une personne. On parle alors d'enregistrement **orphelin**.
Chaque commande SQL est exécutée indépendamment. Si la deuxième commande échoue, la première nest pas annulée automatiquement.
Réalisez linsertion dun titulaire complet (dans holder et person) à laide dune **transaction**.
Testez le cas où la contrainte dâge échoue et vérifiez que rien nest inséré dans holder.
```sql
begin;
...
commit;
```
2025-11-07 13:07:30 +01:00
#### 1.5 Procédure stockée
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
Pour fiabiliser le process et être sûr que l'execution s'effectue toujours dans une transaction,
nous allons encapsuler la création dun titulaire dans une **procédure stockée**.
2025-11-02 20:50:39 +01:00
2025-11-07 13:07:30 +01:00
Créez une **procédure stockée** appelée `create_person_holder`.
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
Cette procédure prend en paramètre :
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
* le prénom (`p_firstname text`)
* le nom (`p_lastname text`)
* la date de naissance (`p_birthdate date`)
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
Cette procédure doit :
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
* Vérifier que la personne a **au moins 15 ans** ;
* Créer automatiquement un enregistrement dans `holder` de type `'PERSON'`;
* Récupérer lidentifiant généré et créer la fiche dans `person` ;
* Afficher un message de confirmation.
2025-11-02 20:50:39 +01:00
3. Si la personne a moins de 15 ans :
2025-11-03 13:42:34 +01:00
* La procédure doit **refuser la création** et afficher une erreur claire.
2025-11-02 20:50:39 +01:00
>[!NOTE]
> La procédure garantit l**atomicité** : soit tout est créé, soit rien.
2025-11-07 13:07:30 +01:00
### 2. Les comptes
2025-11-02 20:50:39 +01:00
2025-11-08 13:23:25 +01:00
```sql
create table account (
"id" bigint primary key generated always as identity,
"creation_date" date default current_date,
"balance" decimal check (balance >= 0),
"currency_code" text references currency (code)
);
```
2025-11-07 13:07:30 +01:00
- Le solde des comptes ne peuvent être négatifs.
2025-11-07 08:45:54 +01:00
- Créez un compte joint à 50/50 pour Françoise et Justin.
2025-11-03 13:42:34 +01:00
Écrire une requête pour vérifier la somme des parts
2025-11-02 20:50:39 +01:00
Jusquà présent, nous savons créer des titulaires (`holder`) de façon sûre.
Il est temps de leur ouvrir des **comptes bancaires**.
Un compte doit toujours :
* être associé à **au moins un titulaire**,
* et la somme des parts (`share`) des titulaires doit être exactement **égale à 1** (cest-à-dire 100 % du compte).
Nous allons donc écrire une **procédure stockée** `create_account` qui vérifie ces règles avant denregistrer les données.
1. Créez une **procédure stockée** `create_account` qui :
2025-11-03 13:42:34 +01:00
* prend en paramètre :
* `p_holders int[]` (tableau des identifiants de titulaires),
* `p_shares numeric[]` (tableau des parts correspondantes).
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
* vérifie que :
2025-11-02 20:50:39 +01:00
2025-11-03 13:42:34 +01:00
* le nombre déléments dans `p_holders` et `p_shares` est identique ;
* la somme des parts est **exactement égale à 1** ;
* chaque `holder_id` existe dans la table `holder`.
2025-11-02 20:50:39 +01:00
2. Si tout est correct :
2025-11-03 13:42:34 +01:00
* crée un nouveau compte dans `account` ;
* insère les lignes correspondantes dans `account_holder`.
2025-11-02 20:50:39 +01:00
3. Si une condition échoue :
2025-11-03 13:42:34 +01:00
* la procédure doit lever une **erreur explicite** (`RAISE EXCEPTION`) ;
* aucune insertion ne doit être faite (transaction annulée).
2025-11-02 20:50:39 +01:00
* Les tableaux peuvent être parcourus avec une boucle :
2025-11-03 13:42:34 +01:00
```sql
for i in 1..array_length(p_holders, 1) loop
...
end loop;
```
2025-11-02 20:50:39 +01:00
* Pour vérifier la somme :
2025-11-03 13:42:34 +01:00
```sql
select sum(unnest(p_shares));
```
2025-11-02 20:50:39 +01:00
(ou additionner dans la boucle)
* Vous pouvez lever une erreur personnalisée :
2025-11-03 13:42:34 +01:00
```sql
raise exception 'La somme des parts doit être égale à 1 (%.4f)', somme;
```
2025-11-02 20:50:39 +01:00
2025-11-07 07:13:51 +01:00
#### Exemples dappel
2025-11-02 20:50:39 +01:00
```sql
call create_account(
'FR761234567890',
'Compte commun',
2025-11-03 07:06:56 +01:00
array[1, 5],
2025-11-02 20:50:39 +01:00
array[0.5, 0.5]
);
```
2025-11-03 07:06:56 +01:00
Crée un compte partagé 50/50 entre les titulaires 1 et 2.
2025-11-02 20:50:39 +01:00
```sql
call create_account(
'FR009999999999',
'Compte déséquilibré',
2025-11-03 07:06:56 +01:00
array[1, 5],
2025-11-02 20:50:39 +01:00
array[0.7, 0.4]
);
```
2025-11-03 07:06:56 +01:00
Doit refuser la création avec une erreur claire :
2025-11-02 20:50:39 +01:00
```
ERROR: La somme des parts (1.1000) doit être égale à 1.0000
```
2025-11-08 13:23:25 +01:00
### 3. Monnaies et taux de change
2025-11-07 13:07:30 +01:00
2025-11-08 13:23:25 +01:00
```sql
create table currency (
2025-11-08 13:39:12 +01:00
"code" text primary key
2025-11-08 13:23:25 +01:00
);
```
2025-11-08 13:39:12 +01:00
```sql
insert into currency values ('EUR');
insert into currency values ('YEN');
```
2025-11-08 13:23:25 +01:00
```sql
create table exchange_rate (
"currency_code" text references currency(code) on delete cascade,
"date" date ,
"rate" decimal not null,
primary key (currency_code, date)
);
```
2025-11-08 13:39:12 +01:00
```sql
insert into exchange_rate values
('YEN', '2025-11-03', 177.57),
('YEN', '2025-11-04', 176.39),
('YEN', '2025-11-05', 176.67),
('YEN', '2025-11-06', 177.15),
('YEN', '2025-11-07', 176.99);
```
2025-11-08 13:23:25 +01:00
### 4. Les opérations et transactions
2025-11-07 13:07:30 +01:00
Implémenter les transactions et opérations.
2025-11-08 13:23:25 +01:00
```sql
create table transaction (
"id" bigint primary key generated always as identity,
"transaction_date" timestamp default current_timestamp,
2025-11-08 13:39:12 +01:00
"amount" decimal check (amount > 0)
2025-11-08 13:23:25 +01:00
);
```
```sql
create table operation (
"id" bigint primary key generated always as identity,
"transaction_id" bigint references transaction(id),
"account_id" bigint references account(id),
2025-11-08 13:39:12 +01:00
"amount" decimal check (amount > 0),
"direction" text check (direction in ('DEBIT', 'CREDIT'))
2025-11-08 13:23:25 +01:00
);
```