Méthode publique · ORM_CSHX2 · Chargement

mth_ChargerSelonID

Charge un enregistrement en mémoire en le recherchant par sa clé primaire. Verrouillage pessimiste optionnel. Hydrate l'objet courant et le tableau interne m_tabResults.

PUBLIQUE SELECT MySQL · MariaDB · PostgreSQL
01

📋 Description

mth_ChargerSelonID est la méthode dédiée au chargement d'un enregistrement par sa clé primaire. C'est le pattern le plus fréquent dans les applications métier : afficher la fiche d'un client, recharger un objet après modification, vérifier l'existence d'un tuple…

La méthode prend l'identifiant à rechercher en premier paramètre, applique le verrou si demandé, et hydrate l'objet courant ainsi que m_tabResults avec le tuple trouvé (s'il existe). Si p_sClauseSelect a été pré-positionné pour limiter les colonnes projetées, la clé primaire est ajoutée automatiquement à la liste si elle n'y figure pas déjà — voir l'avertissement ci-dessous.

🎯 Quand utiliser cette méthode plutôt que mth_ChargerSelonClauseWhere ?

Dès que la condition de recherche est uniquement l'égalité sur la clé primaire. mth_ChargerSelonID(42) est plus court, plus lisible, et plus expressif que :p_sClauseWhere = "table.PK = 42" suivi de mth_ChargerSelonClauseWhere().

Pour toute autre condition (filtre métier, plusieurs critères, jointures, tri, LIMIT…), utiliser mth_ChargerSelonClauseWhere.

⚠️ Auto-ajout de la clé primaire dans p_sClauseSelect

Si l'appelant a pré-positionné p_sClauseSelect pour ne charger qu'un sous-ensemble de colonnes, la méthode ajoute automatiquement la colonne PK à la liste si elle n'y figure pas déjà, sous la forme tableSQL.colonnePK.

Raison : sans la PK dans le SELECT, l'enregistrement chargé n'aurait pas son identifiant côté objet — un appel ultérieur à mth_Enregistrer() ne pourrait pas cibler la bonne ligne en base. L'auto-ajout est donc un garde-fou, pas un effet de bord à craindre.

Effet observable : après l'appel, p_sClauseSelect peut contenir une colonne supplémentaire par rapport à ce qui avait été écrit avant l'appel.

02

🔑 Signature

Déclaration
PROCÉDURE mth_ChargerSelonID(
  LOCAL nIDRecherché est un entier,
  LOCAL nTypeLock est un entier = NoLock
) : (booléen, entier, chaîne)
ÉlémentValeur
VisibilitéPUBLIQUE

Paramètres

ParamètreTypeDéfautRôle
nIDRecherchéentierValeur de la clé primaire à rechercher. Obligatoire.
nTypeLockentierNoLockVerrouillage pessimiste : NoLock · LockInShareMode · LockForUpdate. Une transaction doit être ouverte par l'appelant pour tout verrou ≠ NoLock.

Membre pré-positionnable — facultatif, à renseigner avant l'appel si projection partielle souhaitée.

MembreTypeDéfautRôle
p_sClauseSelectchaîne""Liste explicite des colonnes à projeter au format TABLE.COLONNE séparées par ,. Vide → toutes les colonnes mappées. La colonne PK est ajoutée automatiquement si absente (voir §01).
⚠️ Impact de p_sClauseSelect sur les UPDATE

Si p_sClauseSelect est utilisé pour ne charger qu'un sous-ensemble de colonnes, un appel ultérieur à mth_Enregistrer() sur cet objet ne mettra à jour que les colonnes effectivement chargées — les autres restent inchangées en base.

C'est le comportement attendu : il évite d'écraser silencieusement avec des valeurs vides les colonnes qui n'ont pas été lues. Pour modifier d'autres colonnes, recharger d'abord l'objet sans p_sClauseSelect (ou avec une liste élargie).

03

📦 Résultats hydratés

Comme toutes les méthodes de chargement, mth_ChargerSelonID hydrate directement des objets WLangage. La structure d'une classe métier (mapping, colonnes framework, m_tabResults, constructeur, jointures) est détaillée dans la section dédiée de mth_ChargerSelonClauseWhere.

La recherche par clé primaire ramène 0 ou 1 enregistrement (la PK étant unique). Deux cas à distinguer :

p_nOccurrencesTrouvéesSignification
0Aucun enregistrement avec cet ID. L'objet courant n'est pas hydraté ; m_tabResults est vide.
1Cas nominal. L'objet courant est hydraté avec le tuple trouvé. m_tabResults[1] contient également cet objet.
ℹ️ Vérifier p_nOccurrencesTrouvées avant d'utiliser les valeurs

bProcessing = Vrai indique uniquement que la requête s'est exécutée sans erreur SQL — pas qu'un enregistrement a été trouvé. Une recherche par ID sur une PK inexistante reste un succès (bProcessing = Vrai, p_nOccurrencesTrouvées = 0).

Tester systématiquement p_nOccurrencesTrouvées avant de lire les membres de l'objet.

04

📤 Valeur de retour

Triplet standard ORM (bProcessing, nErrorCode, sErrorMessage) :

RetourCondition
(Vrai, 0, "")La requête SQL s'est exécutée sans erreur. Ne garantit pas qu'un enregistrement a été trouvé — consulter p_nOccurrencesTrouvées.
(Faux, <code>, sMsg)Échec de validation ou erreur SQL — voir la section ⚠️ Gestion des erreurs.
05

⚠️ Gestion des erreurs

Les codes d'erreur retournés sont les mêmes que pour mth_ChargerSelonClauseWhere, puisque la recherche par ID s'appuie sur le mécanisme général de chargement par clause WHERE :

CodeConstanteCondition
-21099ERR_ORM_SELECT_LOCK_INVALIDEnTypeLock ne vaut ni NoLock, ni LockInShareMode, ni LockForUpdate.
-21098ERR_ORM_SELECT_LOCK_SANS_TRANSACTIONVerrou demandé (nTypeLock ≠ NoLock) mais aucune transaction active. La transaction doit être ouverte par l'appelant via ORM_TransactionBegin().
-21095ERR_ORM_SELECT_ENREG_VERROUILLEL'enregistrement chargé en mode LockForUpdate est déjà verrouillé par un autre poste / utilisateur.
-21094ERR_ORM_SELECT_EXCEPTIONException non gérée pendant la construction ou l'exécution de la requête.
-999ERR_SQL_INVALID_REQUESTErreur SQL générique propagée par le moteur. Le détail est dans sErrorMessage.
⚠️ Verrou et transaction — obligation de l'appelant

Si un verrou est demandé (LockForUpdate ou LockInShareMode), une transaction doit être préalablement ouverte via ORM_TransactionBegin(). Si aucune transaction n'est active au moment de l'appel, la méthode retourne immédiatement (Faux, -21098, "...") sans exécuter le SELECT.

06

💡 Exemples

Mode 1 — chargement nominal par ID

// ── Charger le client n°42 ────────────────────────────────────── clClient est un Client (bProcessing, nErrorCode, sErrorMessage) = clClient:mth_ChargerSelonID(42) SI bProcessing ALORS SI clClient:p_nOccurrencesTrouvées = 1 ALORS // L'objet est hydraté, on peut lire ses membres Info("Client trouvé : " + clClient:m_DENOMINATION) SINON Info("Aucun client avec cet ID") FIN SINON Erreur(sErrorMessage) FIN

Mode 2 — verrou pessimiste avec transaction

// ── Charger pour modification atomique ────────────────────────── (bProcessing, nErrorCode, sErrorMessage) = ORM_TransactionBegin() SI bProcessing ALORS (bProcessing, nErrorCode, sErrorMessage) = clClient:mth_ChargerSelonID(42, LockForUpdate) SI bProcessing ET clClient:p_nOccurrencesTrouvées = 1 ALORS // ... modifications sur clClient ... clClient:m_DENOMINATION = "Nouveau nom" (bProcessing, nErrorCode, sErrorMessage,) = clClient:mth_Enregistrer() FIN SI bProcessing ALORS // ✅ Tout est OK — on valide en base (bProcessing, nErrorCode, sErrorMessage) = ORM_TransactionCommit() SI bProcessing = Faux ALORS Erreur(sErrorMessage) FIN SINON // ❌ Échec — annulation complète, aucune modification en base ORM_TransactionRollBack() FIN FIN

Mode 3 — projection partielle avec auto-ajout de la PK

// ── Ne charger qu'une colonne — la PK sera ajoutée automatiquement ─ clClient:p_sClauseSelect = "clients.NOM" (bProcessing, nErrorCode, sErrorMessage) = clClient:mth_ChargerSelonID(42) // Avant l'appel : p_sClauseSelect = "clients.NOM" // Après l'appel : p_sClauseSelect = "clients.NOM,clients.ID_CLIENT" // (la PK clients.ID_CLIENT a été ajoutée automatiquement par la méthode) // ⚠️ Si on appelle clClient:mth_Enregistrer() ensuite, // seules NOM et ID_CLIENT seront mises à jour en base.

Mode 4 — bonne pratique : préférer mth_ChargerSelonID quand on cherche par PK

// ❌ Verbeux — recherche par PK via mth_ChargerSelonClauseWhere clClient:p_sClauseWhere = "clients.ID_CLIENT = 42" (bProcessing, nErrorCode, sErrorMessage) = clClient:mth_ChargerSelonClauseWhere() // ✅ Plus court, plus lisible, expressif sur l'intention (bProcessing, nErrorCode, sErrorMessage) = clClient:mth_ChargerSelonID(42)