📖 Guide · SELECT · ORM_CSHX2

CTE & ClauseWith

Utilisation des Common Table Expressions (clauses WITH … AS) depuis une classe métier d'ORM_CSHX2. Couvre les trois membres impliqués (m_sClauseWith, m_sClauseJoin, m_sClauseSelect), le point architectural critique (une CTE n'est pas une table HFSQL), et un exemple complet de calcul d'agrégat.

Architecture MySQL · MariaDB · PostgreSQL Guide conceptuel
01

🗃️ Les trois membres impliqués

L'utilisation d'une CTE dans ORM_CSHX2 mobilise trois membres publics de la classe que le développeur alimente avant de déclencher le chargement :

MembreRôle
m_sClauseWith Définition complète de la CTE — WITH nom AS (SELECT …). Préfixé automatiquement à la requête SELECT au moment de l'exécution.
m_sClauseJoin Jointure SQL brute sur la CTE — seul mécanisme valide pour joindre une CTE à la table principale.
m_sClauseSelect Liste explicite des colonnes à projeter — obligatoire pour récupérer les colonnes de la CTE (le SELECT * implicite ne les inclut pas).
02

⚠️ Point architectural critique

Une CTE n'est pas une table HFSQL — elle n'existe pas dans l'analyse WinDev. Elle n'a donc aucune entrée dans HListeFichier() ni de rubriques accessibles via HListeRubrique(). Deux conséquences directes pour le développeur :

⚠️ Le mécanisme standard de jointures est inutilisable

Le mécanisme standard de déclaration des jointures (cf. guide Jointures multi-niveaux) tente de résoudre les rubriques de chaque jointure depuis le dictionnaire de données du projet. Une CTE n'y figure pas → l'opération échoue.

Utiliser exclusivement m_sClauseJoin pour joindre une CTE à la table principale.

ℹ️ Colonnes CTE — mapping manuel obligatoire

Les colonnes produites par une CTE ne sont jamais mappées automatiquement aux membres de la classe. Deux actions obligatoires dans la classe métier héritante :

1. Déclarer un membre récepteur pour chaque colonne CTE (ex. m_nTotalVentes est un Monétaire) avec son annotation <MAPPING=NOM_COLONNE_CTE>.

2. Demander explicitement la colonne via m_sClauseSelect — sans cela, la requête ne retournera jamais les colonnes de la CTE.

03

💡 Exemple complet

Calcul du total des ventes par client en utilisant une CTE, jointure sur la table principale et projection du résultat dans un membre de la classe métier héritante.

Déclaration dans la classe métier

// Membre récepteur — déclaré dans la classe héritante de xFrameWork_CSHX2 // L'annotation <MAPPING=TOTAL_VENTES> permet au composant d'alimenter ce membre // avec la colonne TOTAL_VENTES retournée par la CTE m_nTotalVentes est un Monétaire <MAPPING=TOTAL_VENTES>

Alimentation des membres et chargement

// 1. Définition de la CTE :m_sClauseWith = [ WITH cte_ventes AS ( SELECT ID_CLIENT, SUM(MONTANT_HT) AS TOTAL_VENTES FROM commandes WHERE STATUT = 'V' GROUP BY ID_CLIENT ) ] // 2. Jointure brute sur la CTE (le mécanisme standard est inutilisable ici) :m_sClauseJoin = "LEFT JOIN cte_ventes ON cte_ventes.ID_CLIENT = clients.ID_CLIENT" // 3. Projection explicite (obligatoire pour récupérer les colonnes CTE) :m_sClauseSelect = "clients.*, cte_ventes.TOTAL_VENTES" // 4. Chargement standard (bProcessing, nErrorCode, sErrorMessage) = :mth_ChargerSelonClauseWhere("clients.SQL_STATUS = 0")