mth_Enregistrer
Persiste l'objet courant en base. La méthode détermine automatiquement l'opération SQL à effectuer (INSERT, UPDATE ou DELETE) en fonction de l'état de la clé primaire de l'objet — un seul appel pour toutes les opérations d'écriture.
📋 Description
mth_Enregistrer est la méthode universelle de persistance d'ORM_CSHX2. Elle persiste un objet en base sans que l'appelant ait à choisir explicitement entre INSERT, UPDATE ou DELETE : la valeur de la clé primaire de l'objet détermine l'opération à effectuer.
Le tableau suivant résume cette logique de bascule :
| État de la PK | Opération | Effet |
|---|---|---|
= 0 | INSERT | Création d'un nouvel enregistrement. La valeur de la PK est attribuée automatiquement par le moteur SQL (auto-incrément). |
> 0 | UPDATE | Mise à jour de l'enregistrement existant ayant cet identifiant. |
< 0 | DELETE | Suppression de l'enregistrement dont l'identifiant vaut Abs(PK). Comportement métier équivalent à mth_EffacerSelonID : cascade applicative, traductions, archivage trashcan, gestion automatique de transaction. Voir §03 pour la nuance sur l'état de l'instance après DELETE. |
Cette convention permet d'unifier les opérations CRUD en un seul point d'entrée. Particulièrement précieux dans les flux où la liste des modifications à appliquer est construite progressivement (formulaire de saisie, batch d'import, synchronisation…) : le code appelant n'a pas à dispatcher entre trois méthodes différentes, il suffit de positionner correctement la PK.
C'est aussi ce qui rend mth_EnregistrerTableau capable de traiter, dans un même tableau, un mélange d'INSERT, d'UPDATE et de DELETE en une seule passe.
🔑 Signature
| Élément | Valeur |
|---|---|
| Visibilité | PUBLIQUE |
| Paramètres | aucun |
La méthode opère sur l'objet courant : ses membres mappés en base contiennent les valeurs à persister, et la PK détermine l'opération. Aucun paramètre à passer.
🔁 Comportement selon l'état de la PK
PK = 0 → INSERT
Cas du nouvel enregistrement. L'objet vient d'être instancié, ou a été remis à zéro via mth_RAZ. La PK n'a pas encore de valeur en base.
La méthode insère un nouveau tuple. Le moteur SQL attribue alors un nouvel identifiant via le mécanisme d'auto-incrément, et cet identifiant est automatiquement répercuté sur l'objet et retourné dans le 4ᵉ élément du résultat (nID).
PK > 0 → UPDATE
Cas de la modification. L'objet a été chargé précédemment (via mth_ChargerSelonID ou mth_ChargerSelonClauseWhere) ou sa PK a été positionnée explicitement.
La méthode met à jour le tuple correspondant en base. Toutes les colonnes mappées sont mises à jour avec les valeurs courantes des membres de l'objet.
Si l'objet a été chargé avec un p_sClauseSelect limitant la projection (ex : "clients.NOM"), seules les colonnes effectivement chargées seront mises à jour lors de l'UPDATE. Les autres colonnes restent inchangées en base, ce qui évite d'écraser des valeurs avec des chaînes vides ou des zéros par défaut.
Pour modifier d'autres colonnes que celles initialement chargées, recharger d'abord l'objet sans p_sClauseSelect (ou avec une liste élargie).
PK < 0 → DELETE
Cas de la suppression. La PK a été positionnée à une valeur négative pour signaler l'opération. L'identifiant réel à supprimer est Abs(PK).
Le comportement métier est équivalent à un appel direct à mth_EffacerSelonID(Abs(PK)) : cascade applicative selon l'analyse, suppression des traductions, archivage dans cshx2_trashcan, gestion automatique de transaction. La suppression est irréversible.
Pour une suppression isolée et explicite, mth_EffacerSelonID reste plus expressif et plus lisible.
La convention PK<0 prend tout son sens dans les flux unifiés où l'appelant traite une liste hétérogène d'opérations sans connaître à l'avance leur nature : formulaire de saisie multi-action, traitement d'un import, dans mth_EnregistrerTableau qui peut traiter INSERT, UPDATE et DELETE en un seul lot.
Si le résultat côté base de données est identique à mth_EffacerSelonID(Abs(PK)), l'état de l'instance en mémoire diverge légèrement après la suppression :
• mth_EffacerSelonID réinitialise les membres mappés de l'instance (équivalent à un appel à mth_RAZ) puis pose p_bRecordDeleted = Vrai.
• mth_Enregistrer avec PK<0 ne réinitialise pas les membres mappés — l'instance conserve les anciennes valeurs en mémoire — mais pose également p_bRecordDeleted = Vrai (alias français : p_bEnregistrementSupprimé).
Dans les deux cas, le drapeau p_bRecordDeleted permet aux méthodes d'agrégat (mth_SommeValeurs, mth_ValeurMoyenne, etc.) d'exclure les éléments supprimés du calcul. C'est cette différence de RAZ qui justifie de privilégier mth_EffacerSelonID pour les suppressions isolées et la convention PK<0 pour les flux unifiés (notamment mth_EnregistrerTableau).
📤 Valeur de retour
Quadruplet ORM élargi (bProcessing, nErrorCode, sErrorMessage, nID) :
| Élément | Type | Description |
|---|---|---|
bProcessing | booléen | Vrai si l'enregistrement SQL s'est bien déroulé, Faux sinon. |
nErrorCode | entier | 0 en cas de succès, code d'erreur négatif sinon. |
sErrorMessage | chaîne | Message d'erreur lisible en cas d'échec, vide sinon. |
nID | entier | Identifiant de l'enregistrement traité — voir détails ci-dessous. |
Convention sur nID
| Cas | Valeur de nID |
|---|---|
| Succès — INSERT | Nouvel identifiant attribué par la base (auto-incrément). Toujours positif. |
| Succès — UPDATE | L'identifiant de l'enregistrement modifié (PK inchangée). |
| Succès — DELETE | Abs(PK) — l'identifiant qui a été supprimé. |
| Échec SQL | -1 |
Le 4ᵉ élément du retour est particulièrement utile après un INSERT pour récupérer l'identifiant nouvellement attribué :
(bProcessing, nErrorCode, sErrorMessage, nID) = clClient:mth_Enregistrer()
SI bProcessing ALORS
// Utiliser nID pour les enregistrements liés ou la navigation
clCommande:m_ID_CLIENT = nID
FIN
L'ID est aussi automatiquement répercuté sur la PK de l'objet courant — les deux valeurs sont équivalentes après l'appel.
-1 pour signaler l'échecEn cas d'échec SQL, nID = -1 indique sans ambiguïté l'absence d'enregistrement valide en base. Tester bProcessing reste la façon canonique de détecter l'échec ; nID = -1 est une commodité pour les contextes où seul l'ID est manipulé.
⚠️ Gestion des erreurs
Les codes d'erreur retournés dépendent de l'opération effectuée :
En cas d'INSERT ou UPDATE
| Code | Constante | Condition |
|---|---|---|
-999 | ERR_SQL_INVALID_REQUEST | Erreur SQL générique (contrainte d'intégrité, type incompatible, valeur trop longue, etc.). Le détail est dans sErrorMessage. |
En cas de DELETE (PK<0)
Mêmes codes que mth_EffacerSelonID, puisque le mécanisme est identique :
| Code | Constante | Condition |
|---|---|---|
-23099 | ERR_ORM_DELETE_VERROUILLE | L'enregistrement à supprimer est verrouillé par un autre poste / utilisateur. |
-23098 | ERR_ORM_DELETE_PROVIDER | Provider SQL non géré pour la suppression de l'enregistrement principal. |
-23097 | ERR_ORM_DELETE_TRAD_VERROUILLE | Une traduction associée est verrouillée par un autre poste. |
-23096 | ERR_ORM_DELETE_TRAD_PROVIDER | Provider SQL non géré pour la suppression des traductions. |
-999 | ERR_SQL_INVALID_REQUEST | Erreur SQL générique propagée par le moteur. |
💡 Exemples
Mode 1 — création d'un nouvel enregistrement
Mode 2 — modification d'un enregistrement existant
Mode 3 — suppression via convention de signe
Mode 4 — INSERT atomique avec enregistrements liés
Un cas courant : créer un client puis ses commandes liées. Si l'une des opérations échoue, on annule tout.
Mode 5 — diagnostic via mode verbose
Pour visualiser les requêtes SQL réellement exécutées (utile pour comprendre la différence INSERT/UPDATE, voir les colonnes mises à jour, etc.) :
Trace produite (cas INSERT) :
Trace produite (cas UPDATE) :
Détails complets : ORM_VerboseMode.