ORM_ResetSequence
Recalage de la séquence d'auto-incrément d'une clé primaire sur MAX(PK)+1. Indispensable après un import de données avec IDs explicites — sans recalage, le prochain INSERT en auto-incrément génère un conflit de clé primaire. PostgreSQL uniquement à ce jour.
📋 Description
ORM_ResetSequence resynchronise la séquence d'auto-incrément d'une colonne clé primaire sur la valeur MAX(PK) + 1. Cette opération est nécessaire après tout chargement de données qui contourne le mécanisme d'auto-incrément du moteur — typiquement un import avec IDs explicites.
Sans ce recalage, le moteur SQL conserve son compteur interne à la valeur précédant l'import. Le prochain INSERT sans ID explicite générera donc une valeur inférieure ou égale à celles déjà présentes en base, et provoquera une erreur de conflit de clé primaire.
1. Après un import de données avec IDs explicites. Cas le plus fréquent : reprise depuis une autre base, restauration partielle, migration entre environnements. Les IDs ont été insérés tels quels mais le compteur interne de la séquence n'a pas été mis à jour automatiquement.
2. Après une copie de table par INSERT INTO ... SELECT qui préserve les valeurs originales de la clé primaire — même problématique que pour un import depuis l'extérieur.
3. Après une opération de fusion ou de réorganisation qui a inséré des enregistrements avec des IDs supérieurs à la valeur courante de la séquence.
L'implémentation actuelle ne couvre que PostgreSQL. Les providers MySQL et MariaDB (qui utilisent ALTER TABLE ... AUTO_INCREMENT au lieu de ALTER SEQUENCE) ne sont pas encore supportés. Un appel avec un autre provider provoque actuellement un arrêt en mode test ou un comportement non spécifié en production. Le support multi-provider est prévu — voir le journal d'évolution du framework.
L'instruction ALTER SEQUENCE ... RESTART de PostgreSQL est non bloquante : elle ne pose pas de verrou exclusif sur la table associée. La procédure peut donc être appelée en concurrence avec un trafic applicatif. Cela dit, en pratique on l'invoque typiquement après un import en mode maintenance, donc le point a peu d'impact opérationnel.
🔑 Signature
LOCAL sTableSQL est une chaîne,
LOCAL sCléPrimaire est une chaîne
) : (booléen, entier, chaîne)
| Élément | Valeur |
|---|---|
| Visibilité | PUBLIQUE |
Paramètres
| Paramètre | Type | Rôle |
|---|---|---|
sTableSQL | chaîne | Nom de la table SQL dont la séquence d'auto-incrément doit être recalée. |
sCléPrimaire | chaîne | Nom de la colonne clé primaire auto-incrémentée associée à la séquence. |
Valeur de retour
| Élément | Type | Description |
|---|---|---|
bProcessing | booléen | Vrai si le recalage a réussi, Faux en cas d'échec. |
nErrorCode | entier | Code d'erreur négatif en cas d'échec, 0 sinon. Voir §05. |
sErrorMessage | chaîne | Message d'erreur lisible en cas d'échec, vide sinon. |
🛡️ Étapes du recalage
Le recalage s'effectue en trois étapes successives. Chaque étape peut échouer indépendamment et déclenche un code d'erreur dédié pour faciliter le diagnostic.
PostgreSQL — 3 étapes
| Étape | Opération | Effet |
|---|---|---|
1. Lecture du MAX(PK) | SELECT MAX(<clé>) FROM <table> | Récupère la plus grande valeur de clé primaire actuellement présente dans la table. |
| 2. Identification de la séquence | Requête sur les catalogues système PostgreSQL | Localise le nom de la séquence PostgreSQL liée à la colonne clé primaire (chaque colonne SERIAL/BIGSERIAL/IDENTITY est associée à une séquence dédiée par le moteur). |
| 3. Recalage | ALTER SEQUENCE "<séquence>" RESTART <max+1> | Repositionne le compteur interne de la séquence sur MAX(PK) + 1. Le prochain INSERT en auto-incrément génèrera donc une valeur strictement supérieure à toutes celles déjà présentes. |
Si la table est vide, MAX(<clé>) renvoie NULL. La séquence est alors recalée à NULL + 1 = 1 — donc le prochain INSERT obtiendra l'ID 1. Ce comportement convient pour réinitialiser une table après un TRUNCATE, par exemple.
La connexion ORM courante doit pointer sur la base de données contenant la table cible. Les catalogues système PostgreSQL consultés à l'étape 2 sont scopés à la base courante : impossible d'identifier une séquence d'une autre base via la connexion en cours.
Le rôle courant doit avoir le droit ALTER sur la séquence cible. Typiquement, c'est le rôle propriétaire de la séquence (créateur de la table) ou un superutilisateur. Un compte applicatif standard (créé par ORM_CreateUser avec ses droits DML uniquement) ne peut pas appeler cette procédure.
MySQL / MariaDB — non implémenté
Le support MySQL/MariaDB n'est pas implémenté à ce jour. L'équivalent fonctionnel serait ALTER TABLE <table> AUTO_INCREMENT = <max+1>, mais cette branche n'est pas active dans la version actuelle du framework. Un appel sur ces providers ne donnera pas le résultat attendu.
🧭 Cas typique d'utilisation
Pour comprendre concrètement pourquoi ce recalage est nécessaire, voici le scénario le plus fréquent : un import de données depuis une source externe.
Sans recalage — le scénario qui échoue
| Étape | Action | État de la séquence |
|---|---|---|
| 1 | Table articles vide. Compteur de séquence à 1. | 1 |
| 2 | Import en masse : INSERT INTO articles (ID, ...) VALUES (1, ...), (2, ...), ..., (1000, ...) | 1 (inchangé — le compteur ne suit pas les IDs explicites) |
| 3 | L'application crée un nouvel article : INSERT INTO articles (DESIGNATION, ...) VALUES (...) — sans ID explicite, le moteur prend 1 dans la séquence. | ❌ Erreur : conflit de clé primaire (ID 1 déjà utilisé) |
Avec recalage — le scénario qui réussit
| Étape | Action | État de la séquence |
|---|---|---|
| 1 | Table articles vide. Compteur à 1. | 1 |
| 2 | Import en masse comme précédemment. | 1 |
| 3 | ORM_ResetSequence("articles", "ID") → recale la séquence sur 1001. | 1001 |
| 4 | L'application crée un nouvel article sans ID explicite. | ✅ Le moteur génère l'ID 1001 — pas de conflit. |
⚠️ Gestion des erreurs
Chaque étape du recalage peut échouer indépendamment et déclenche un code d'erreur spécifique pour faciliter le diagnostic.
| Constante | Étape concernée |
|---|---|
ERR_ORM_SEQ_SELECT_MAX_PK | Échec de l'étape 1 (lecture de MAX(clé)). Causes possibles : table inexistante, colonne inexistante, droits insuffisants en SELECT. |
ERR_ORM_SEQ_SELECT_PG_CLASS | Échec de l'étape 2 (identification de la séquence dans les catalogues système PostgreSQL). Cause typique : droits insuffisants pour interroger le catalogue système. |
ERR_ORM_SEQ_INTROUVABLE | L'étape 2 a réussi mais aucune séquence n'est associée à la combinaison (table, colonne) indiquée. La colonne n'est probablement pas en auto-incrément (ce n'est ni un SERIAL, ni un BIGSERIAL, ni un IDENTITY). |
ERR_ORM_SEQ_ALTER | Échec de l'étape 3 (ALTER SEQUENCE RESTART). Cause typique : droits ALTER insuffisants sur la séquence. |
-99999 | Exception non prévue. Consulter sErrorMessage pour le détail (typiquement remonté par le moteur SQL). |
ERR_ORM_SEQ_INTROUVABLECe code d'erreur signale que la colonne désignée n'a pas de séquence associée côté PostgreSQL. Avant d'incriminer la procédure, vérifier que :
• La colonne est bien définie comme SERIAL, BIGSERIAL ou IDENTITY dans le schéma physique
• Les paramètres sTableSQL et sCléPrimaire sont écrits avec la bonne casse (PostgreSQL est case-sensitive sur les identifiants encadrés par des guillemets)
• La table appartient bien au schéma de la connexion courante
💡 Exemples
Mode 1 — recalage après import nominal
Cas d'usage : après un import en masse depuis un fichier CSV ou une base externe, on remet la séquence en cohérence avec les IDs présents.
"articles", "ID_ARTICLE" ) SI bProcessing ALORS Info("Séquence recalée — l'application peut reprendre normalement") SINON Erreur("Échec du recalage : " + sErrorMessage) FIN
Mode 2 — recalage en boucle après une migration multi-tables
Cas d'usage : restauration ou migration qui touche plusieurs tables — on parcourt la liste pour recaler chaque séquence.
Mode 3 — diagnostic d'une erreur typique
Cas d'usage : on a appelé la procédure sur une colonne qui se trouve ne pas être en auto-incrément (oubli ou erreur de schéma).
Mode 4 — recalage après ORM_TruncateTable
Cas d'usage : nettoyage complet d'une table puis ré-import. Le TRUNCATE peut, selon les options, conserver ou non la séquence — un recalage explicite garantit le comportement attendu.