Connecteurs SQL
L'éditeur Connecteurs SQL est l'endroit où sont déclarées des requêtes SQL nommées. Un connecteur SQL est une définition réutilisable « qui parle à une base » — une connexion JDBC plus une liste de requêtes nommées — que le reste de NomaUBL référence par son nom. Il calque la structure des Connecteurs API : le même sélecteur pilote les Liaisons d'actions et les Règles de notification, avec un suffixe · SQL dans le menu déroulant pour que le type soit visible.
Cibles typiques :
- Une seconde base NomaUBL pour les recherches inter-environnements.
- Une base d'ERP source — JD Edwards, SAP, NetSuite ou un schéma personnalisé — quand une action doit lire un e-mail client, une date de paiement, un code de statut que l'API HTTP n'expose pas.
- Une base opérationnelle qu'une action doit mettre à jour — par exemple marquer une facture comme envoyée dans un système aval, archiver une ligne, enregistrer une trace d'audit.
La page fonctionne quel que soit le système source, le connecteur SQL pouvant pointer sur n'importe quelle base JDBC accessible.
Les connecteurs SQL sont nouveaux en 2026.05.7. Ils côtoient les connecteurs API dans Paramètres, et les deux types peuvent être câblés depuis les liaisons d'actions et les règles de notification — y compris la nouvelle liste d'appels avec Arrêt sur échec et chaînage des réponses via {call.N.fieldName}. Voir les notes de version 2026.05.7 pour la liste complète.
L'éditeur a trois onglets :
- Connection — type de base, URL JDBC, identifiants, schéma et limites de requêtes.
- Queries — cartes repliables par requête : nom, libellé, description, SQL, paramètres, drapeau
Writable. - Test — exécute une requête sur la base cible et affiche les colonnes + lignes ou le nombre de lignes affectées.
Accès à l'éditeur
- Paramètres → + Add SQL en haut à droite de la barre des ressources pour créer un nouveau connecteur SQL.
- Les connecteurs SQL existants se trouvent dans le groupe SQL de la barre des ressources avec un badge
sql— cliquer sur l'un d'eux ouvre l'éditeur.
Vue d'ensemble
Onglet 1 — Connexion
Connection
| Champ | Valeurs | Description |
|---|---|---|
| Database Type | Oracle / PostgreSQL | Type de moteur. Pilote le placeholder de l'URL JDBC et le parsing dépendant du dialecte côté runtime. |
| JDBC URL | texte | Chaîne de connexion JDBC complète. jdbc:oracle:thin:@host:1521/service_name pour Oracle, jdbc:postgresql://host:5432/database_name pour PostgreSQL. |
| Schema | texte (facultatif) | Schéma par défaut. Utilisé par le SQL — aucune préfixation automatique à l'exécution, la valeur est informative et permet d'écrire des noms de tables non qualifiés quand le compte JDBC dispose déjà du bon current_schema. |
Identifiants
| Champ | Description |
|---|---|
| DB User | Compte de base de données qui dispose des droits exigés par les requêtes déclarées sur ce connecteur. Un accès en lecture seule suffit pour des requêtes SELECT uniquement. |
| DB Password | Mot de passe du compte. Stocké encodé en Base64 dans le fichier de configuration, à l'identique de db-nomaubl et db-jde. |
Limites
| Champ | Défaut | Description |
|---|---|---|
| Query timeout (ms) | 30000 | Timeout JDBC par instruction. Les requêtes trop longues sont annulées au-delà. |
| Max rows | 1000 | Plafond de lignes renvoyées par appel SELECT. Une requête en dérive ne peut pas saturer le heap JVM. |
Onglet 2 — Requêtes
L'onglet Queries est une liste de cartes repliables. L'en-tête de carte affiche un badge LECT. / ÉCRIT., le nom de la requête et la description en deuxième ligne — un connecteur à plusieurs requêtes se lit ainsi comme une liste à cocher d'un coup d'œil. Cliquer sur un en-tête déplie l'éditeur ; + Add query ajoute une nouvelle requête.
Champs par requête
| Champ | Description |
|---|---|
| Name | Identifiant de la requête. Utilisé comme valeur d'endpoint quand la requête est câblée dans une liaison d'action ou une règle de notification (connecteur / nom). |
| Label | Titre court affiché à côté du nom dans les listes déroulantes (name — Label). |
| Description | Phrase libre affichée en deuxième ligne de la carte repliée. La lecture des règles à voix haute doit rester compréhensible. |
| Writable | Oui / Non. Doit être Oui quand le SQL est autre chose qu'un SELECT — sinon le runtime rejette l'appel avant même l'ouverture de la connexion. |
| SQL | Le SQL lui-même, avec des placeholders :name pour les paramètres. Le premier mot-clé hors commentaire et hors littéral détermine le type d'instruction (SELECT / INSERT / UPDATE / DELETE / MERGE). |
| Parameters | Spécification des jetons :placeholder utilisés dans le SQL. Format : `name |
Liste blanche des types d'instructions
Seuls SELECT, INSERT, UPDATE, DELETE et MERGE sont acceptés. Tout le reste — DROP, TRUNCATE, ALTER, GRANT, CREATE, etc. — est rejeté avant même l'ouverture de la connexion. Une requête qui commence par l'un de ces mots-clés ne peut pas non plus être enregistrée avec Writable=Non : le runtime parse à nouveau le premier mot-clé à chaque appel, le verrou ne se contourne pas en éditant la ressource à la main.
Binding des paramètres (:name → ?)
Le binding des paramètres passe par PreparedStatement. Le runtime parse le SQL, réécrit chaque jeton :name en un ? positionnel et lie les valeurs positionnellement — les valeurs ne sont jamais substituées par concaténation dans le SQL. Le parseur respecte :
- les littéraux entre apostrophes (
'O''Brien'), - les identifiants entre guillemets (
"customer.name"), - les commentaires de ligne (
-- …) et de bloc (/* … */), - l'opérateur de cast PostgreSQL
::type('foo'::text).
Les jetons à l'intérieur de l'un de ces constructs passent inchangés.
La spec des paramètres pilote l'onglet Test et l'éditeur des appels : chaque :name déclaré devient un champ étiqueté pré-rempli avec la valeur default. Les lignes de spec sont séparées par des points-virgules ; chaque ligne contient jusqu'à trois champs séparés par des barres verticales. Les champs vides sont acceptés (un paramètre sans défaut donne simplement un champ vide).
Drapeau Writable
Writable=Non est la valeur sûre par défaut. Le passer à Oui est obligatoire pour toute instruction non-SELECT et c'est ce que le runtime vérifie à l'appel :
- Une requête
SELECTavecWritable=Ouis'exécute sans problème — le drapeau élargit la liste blanche, il ne la rétrécit pas. - Une requête
UPDATEavecWritable=Nonest rejetée avec un message d'erreur dans le panneau de test, et tracéeSTOPdans le journal d'audit à l'exécution. - Une faute de frappe dans une règle de notification qui pointe sur une requête non-
Writablemais essaie d'exécuterDELETE FROM …ne peut pas réussir — le verrou s'applique avant l'ouverture de la connexion.
Onglet 3 — Test
Un runner intégré qui exécute la requête sélectionnée sur la base cible et affiche le résultat.
| Élément | Description |
|---|---|
| Query | Liste déroulante de toutes les requêtes déclarées dans l'onglet Queries, au format name — Label. La sélection d'une requête pré-remplit les lignes de paramètres à partir de la spec. |
| Parameters | Une ligne par :placeholder déclaré, plus un bouton Add param pour des paramètres ad hoc absents de la spec. Chaque ligne a un champ nom et un champ valeur. |
| Run | Envoie l'appel à /api/sql-connectors/{connecteur}/{requête} avec les valeurs de paramètres. Le résultat est affiché à côté du bouton. |
Panneau de résultat
| Type d'instruction | Affichage |
|---|---|
| SELECT | Type d'instruction + nombre de lignes + durée sur la ligne verte de succès ; en dessous, un tableau compact colonnes × lignes. Le runtime plafonne le nombre de lignes à Max rows de l'onglet Connection. |
| INSERT / UPDATE / DELETE / MERGE | Type d'instruction + nombre de lignes affectées + durée sur la ligne verte de succès. Pas de tableau — le runtime ne renvoie que le compteur d'updates pour les appels non-SELECT. |
| Erreur | Cadre d'erreur rouge avec le message JDBC / parseur (SQLException, violation de la liste blanche, :placeholder manquant, etc.). |
L'onglet Test appelle la base réelle — Enregistrer le connecteur d'abord après une édition ; sinon le test tourne contre la version précédemment enregistrée de la requête.
Utilisation des connecteurs SQL
Les connecteurs SQL se branchent aux mêmes points d'appel que les connecteurs API :
- Liaisons d'actions — les boutons réglementaires du modal de détail facture peuvent appeler n'importe quelle requête SQL, seule ou en chaîne, via la liste d'appels multiples livrée en 2026.05.7.
- Règles de notification — la même liste d'appels, déclenchée automatiquement quand la règle correspond à un changement de statut.
Dans les deux cas, la liste déroulante des connecteurs liste les connecteurs API et les connecteurs SQL fusionnés avec les suffixes · API / · SQL ; la liste déroulante des cibles charge les endpoints ou les requêtes selon le type du connecteur choisi.
Sorties et chaînage des réponses
Quand un appel SQL retourne, ses sorties sont versées dans le contexte de dispatch sous des clés call.N.*, où N est l'index 1-basé de l'appel dans la règle ou la liaison. Les appels suivants y accèdent via des placeholders {call.N.fieldName} dans leurs valeurs de paramètres.
| Champ | Source |
|---|---|
call.N.success | true quand l'appel s'est exécuté sans erreur. |
call.N.statementType | SELECT / INSERT / UPDATE / DELETE / MERGE. |
call.N.rowCount | Pour SELECT — nombre de lignes renvoyées. |
call.N.updateCount | Pour les non-SELECT — nombre de lignes affectées. |
call.N.error | Message d'erreur quand success vaut false. |
call.N.<colonne> | Pour SELECT — chaque colonne de la première ligne, par son nom. |
Exemple : une règle qui commence par chercher l'e-mail du client via une requête SQL, puis envoie un webhook HTTP de suivi, peut placer dans le paramètre to du webhook la valeur {call.1.EMAIL} (la colonne EMAIL de la première ligne de l'appel #1).
Conseils & bonnes pratiques
- Un connecteur par base, pas par requête. Un connecteur crm à cinq requêtes nommées se lit mieux que cinq connecteurs portant chacun une requête. Le menu déroulant regroupe les requêtes sous le connecteur parent.
- Nommer les requêtes par intention, pas par forme SQL.
findCustomerEmailse lit mieux queselectKcoFromF0101. Le corps du SQL est à un clic dans l'éditeur — le nom est ce que la liste de règles affiche. - Démarrer chaque connecteur en
Writable=Non. Passer le drapeau àOuiuniquement sur les requêtes qui doivent vraiment écrire. Un connecteur enSELECTseul ne peut pas être détourné pour exécuter unDELETE, même si une faute de frappe pointe la règle sur la mauvaise requête. - Utiliser des placeholders
:namepour toute valeur fournie par l'utilisateur. Concaténer une valeur dans la chaîne SQL contourne le filet de sécurité du binding paramétré. Le parseur ignore volontairement les jetons à l'intérieur des littéraux et des commentaires : un:dans une chaîne reste sans effet. - Réduire Max rows par défaut sur les requêtes orientées tableau de bord. Un widget qui lit les 10 dernières factures rejetées n'a pas besoin de 1000 lignes en retour ; le plafonner à 50 garde l'interface réactive et le fetch JDBC peu coûteux.
- Tester avant d'enregistrer en cas de modification. L'onglet Test prend en compte l'édition en cours quand il existe des changements non enregistrés, mais le bouton Run appelle la base réelle — il n'y a pas de rollback. Une requête
Writable=Ouitestée s'engage si le SQL le décide. - Coupler connecteurs SQL et API via le chaînage des réponses. Une règle de notification peut lire une valeur via une requête SQL et la transmettre comme paramètre à un webhook HTTP, sans code de chaque côté. Voir Règles de notification — onglet Actions pour les détails.
- Garder les identifiants dans un compte BD dédié. Même sur un connecteur en lecture seule, donner au compte JDBC les seuls droits dont les requêtes ont besoin —
SELECTsur un petit ensemble de tables, sans accès large au schéma.