Procédure publique · ORM_CSHX2 · Utilitaires SQL

ORM_QuoteIdentifiers

Encapsule les identifiants SQL (noms de tables et de colonnes) d'une requête selon les conventions du provider courant — guillemets doubles pour PostgreSQL, backticks pour MySQL. Indispensable quand le schéma utilise des mots réservés SQL ou repose sur la sensibilité à la casse des identifiants.

PUBLIQUE ENCAPSULATION IDENTIFIANTS MySQL · MariaDB · PostgreSQL
01

📋 Description

ORM_QuoteIdentifiers prend une requête SQL en paramètre et retourne la même requête dans laquelle les identifiants connus du framework (noms de tables et de colonnes) ont été encapsulés selon les règles du provider de la connexion ORM courante :

  • PostgreSQL : guillemets doubles → "table"."colonne"
  • MySQL : backticks → `table`.`colonne`
⚠️ Encapsulation d'identifiants — pas de quoting de valeurs

Cette procédure ne traite pas les valeurs SQL (chaînes, dates, nombres). Pour cela, utiliser ORM_Quote. La présente procédure agit uniquement sur les noms d'objets de schéma (tables, colonnes) — l'équivalent SQL des « delimited identifiers » du standard.

🎯 Quand utiliser cette procédure

1. Identifiants en conflit avec des mots réservés SQL. Si une table ou une colonne porte un nom comme USER, ORDER, DATE, TYPE, etc., la requête échoue côté moteur sans encapsulation. Faire transiter la requête par ORM_QuoteIdentifiers résout le problème de manière transparente.

2. Schéma à identifiants sensibles à la casse. PostgreSQL convertit les identifiants non encapsulés en minuscules au moment de la résolution. Si le schéma a été créé avec des noms en casse mixte (par exemple Clients.NomPrenom), seules les requêtes encapsulant les identifiants pourront les résoudre correctement.

3. Portabilité multi-provider. Le code applicatif compose la requête une seule fois, sans connaître les conventions d'encapsulation propres à chaque moteur — la procédure choisit le caractère approprié.

ℹ️ Activation conditionnelle

L'encapsulation n'est appliquée que si le mode sensible à la casse est activé pour la session ORM. Sinon la requête est retournée telle quelle, sans modification. Cette option est configurable via ORM_Setup.

02

🔑 Signature

Déclaration
PROCÉDURE ORM_QuoteIdentifiers(
  LOCAL sRequête est une chaîne
) : chaîne
ÉlémentValeur
VisibilitéPUBLIQUE

Paramètre

ParamètreTypeRôle
sRequêtechaîneRequête SQL brute dont les identifiants connus seront encapsulés. La requête peut contenir n'importe quelle instruction SQL (SELECT, UPDATE, INSERT, DELETE…) ainsi que des fragments de clauses (WHERE, ORDER BY…).

Valeur de retour

Une chaîne contenant la requête transformée si l'encapsulation a été appliquée, ou la requête d'origine inchangée si les conditions d'activation ne sont pas remplies — voir §03.

03

🧭 Conditions d'activation et règles d'encapsulation

Conditions d'activation

L'encapsulation n'est appliquée que si toutes les conditions suivantes sont réunies :

ConditionDétail
Mode sensible à la casse activéConfigurable via ORM_Setup. Désactivé par défaut.
Provider supportéPostgreSQL ou MySQL. Les autres providers ne supportent pas l'encapsulation par cette procédure.
Dictionnaire de données peupléLe framework doit avoir connaissance des identifiants du schéma (typiquement après initialisation de la connexion).

Si l'une au moins de ces conditions n'est pas remplie, la requête est retournée telle quelle, sans transformation, sans erreur.

Caractères d'encapsulation par provider

ProviderCaractèreForme produite
PostgreSQL" (guillemet double)"table"."colonne"
MySQL` (backtick)`table`.`colonne`
MariaDB` (backtick)`table`.`colonne` (comportement aligné sur MySQL)

Identifiants concernés

Seuls les identifiants connus du dictionnaire de données du framework sont encapsulés. Les autres mots de la requête sont préservés à l'identique : mots-clés SQL, opérateurs, valeurs, alias de requête, fonctions SQL. Le mécanisme respecte les mots complets — un identifiant qui apparaîtrait par hasard comme sous-chaîne d'un autre mot ne sera pas modifié.

ℹ️ Forme attendue dans la requête source

Le framework reconnaît les identifiants sous leur forme qualifiée table.colonne ou sous leur forme simple, selon ce qui est répertorié dans le dictionnaire de données. La requête en entrée peut contenir l'identifiant tel quel — l'encapsulation est ajoutée par la procédure.

04

💡 Exemples

Mode 1 — encapsulation d'une clause SELECT en PostgreSQL

Cas d'usage : requête manuelle sur une base PostgreSQL en mode sensible à la casse.

// ── Requête source ────────────────────────────────────────────── sRequête est une chaîne = "SELECT clients.NOM, clients.PRENOM FROM clients WHERE clients.ACTIF = TRUE" // ── Encapsulation des identifiants ────────────────────────────── sRequêteEnc est une chaîne = ORM_QuoteIdentifiers(sRequête) // → "SELECT "clients"."NOM", "clients"."PRENOM" // FROM "clients" // WHERE "clients"."ACTIF" = TRUE" // ── Exécution sur la connexion courante ───────────────────────── SQLExec(sRequêteEnc, "REQ_Clients")

Mode 2 — gestion d'un identifiant en conflit avec un mot réservé

Cas d'usage : table nommée USER (mot réservé en SQL standard) — sans encapsulation, la requête échoue.

// ── Requête qui échouerait sans encapsulation ─────────────────── sRequête est une chaîne = "SELECT USER.LOGIN FROM USER WHERE USER.ACTIF = 1" // ── Avec encapsulation, la requête devient valide ─────────────── sRequêteEnc est une chaîne = ORM_QuoteIdentifiers(sRequête) // → MySQL : "SELECT `USER`.`LOGIN` FROM `USER` WHERE `USER`.`ACTIF` = 1" // → PostgreSQL : 'SELECT "USER"."LOGIN" FROM "USER" WHERE "USER"."ACTIF" = 1' SQLExec(sRequêteEnc, "REQ_Users")

Mode 3 — comportement quand l'encapsulation n'est pas active

Cas d'usage : projet en mode insensible à la casse (configuration par défaut). La procédure retourne la requête telle quelle.

// ── Si l'encapsulation n'est pas activée dans ORM_Setup… ──────── sRequête est une chaîne = "SELECT clients.NOM FROM clients" sRequêteEnc est une chaîne = ORM_QuoteIdentifiers(sRequête) // → sRequêteEnc = "SELECT clients.NOM FROM clients" (inchangée) // L'appel est sûr et idempotent — l'inclure systématiquement // dans le code applicatif est une bonne pratique de portabilité, // même si l'encapsulation n'est pas active dans la configuration courante.

Mode 4 — bonne pratique : encapsulation systématique avant exécution

Pattern recommandé pour le code applicatif qui exécute des requêtes SQL composées à la main, en dehors des méthodes ORM standard.

// ── Composition de la requête (avec ORM_Quote pour les valeurs) ─ sNom est une chaîne = SAI_NomRecherché sRequête est une chaîne = ChaîneConstruit(
  "SELECT * FROM clients WHERE clients.NOM = %1",   ORM_Quote(sNom) ) // ── Encapsulation des identifiants juste avant exécution ──────── sRequête = ORM_QuoteIdentifiers(sRequête) // ── Exécution ─────────────────────────────────────────────────── SI SQLExec(sRequête, "REQ_Recherche") ALORS // Traitement du résultat... FIN SQLFerme("REQ_Recherche")