Choix multiples en SQL sur IBM i : maîtriser IN, CASE et sous-requêtes
lun 4 février 2019Comment réaliser un choix multiple en SQL DB2 sur IBM i
Dans le monde IBM i, beaucoup de développeurs viennent du RPG et raisonnent naturellement en IF, SELECT/WHEN ou en boucles.
Pourtant, SQL fournit des mécanismes simples et puissants pour exprimer un choix multiple, souvent de manière plus lisible et plus performante.
Petit rappel (utile pour tout le monde 😉) sur les principales approches en DB2 for IBM i.
1. Le choix multiple le plus simple : l’opérateur IN
Lorsqu’on souhaite tester si une valeur appartient à un ensemble donné, IN est la solution la plus lisible.
SELECT *
FROM fichiera
WHERE A1 IN (1, 3, 5, 7);Cette écriture remplace avantageusement une succession de conditions :
WHERE A1 = 1
OR A1 = 3
OR A1 = 5
OR A1 = 7Pourquoi privilégier IN ?
- meilleure lisibilité
- maintenance facilitée
- optimisation généralement plus efficace côté DB2
Dès que plusieurs OR apparaissent, IN devient un réflexe à adopter.
Source :
IBM Documentation – IN predicate
Pourquoi privilégier IN ?
- meilleure lisibilité
- maintenance facilitée
- optimisation généralement plus efficace côté DB2
Dès que plusieurs OR apparaissent, IN devient un réflexe à adopter.
Source :
IBM Documentation – IN predicate
Pourquoi privilégier IN ?
- meilleure lisibilité
- maintenance facilitée
- optimisation généralement plus efficace côté DB2
Dès que plusieurs OR apparaissent, IN devient un réflexe à adopter.
Source :
IBM Documentation – IN predicate
https://www.ibm.com/docs/en/i/7.6.0?topic=predicates-in-predicate
2. Un choix multiple dynamique avec une sous-requête
Très souvent, la liste des valeurs ne doit pas être codée en dur, mais provenir d’une table.
SELECT *
FROM fichiera
WHERE A1 IN (
SELECT B1
FROM fichierb
);Dans ce cas :
A1est comparé à toutes les valeurs retournées par la sous-requête- la règle métier est centralisée en base
- on évite des traitements intermédiaires côté RPG
Cas d’usage courant
- tables de paramétrage
- listes fonctionnelles maintenues par les utilisateurs
- règles métier évolutives sans recompilation applicative
3. Introduire de la logique métier avec CASE
SQL permet d’intégrer une logique conditionnelle directement dans la requête grâce à l’expression CASE.
C’est l’équivalent conceptuel d’un SELECT/WHEN en RPG.
SELECT *
FROM fichiera
WHERE A1 IN (
SELECT
CASE
WHEN SUBSTR(B2, 19, 7) <> ''
THEN INT(SUBSTR(B2, 19, 7))
ELSE 0
END
FROM fichierb
);Ici :
- une valeur est extraite d’une zone alphanumérique
- une règle de transformation est appliquée
- la comparaison se fait sur une valeur calculée
👉 Idée clé :
Le CASE permet de normaliser ou interpréter une donnée brute avant comparaison, sans repasser par le code applicatif.
Source :
IBM Documentation – CASE expression
https://www.ibm.com/docs/en/i/7.6.0?topic=expressions-case-expression
4. Améliorer la lisibilité avec une CTE (WITH)
Pour un SQL plus clair et plus maintenable, il est recommandé d’isoler la logique métier dans une CTE (Common Table Expression).
WITH valeurs_b AS (
SELECT DISTINCT
CASE
WHEN SUBSTR(B2, 19, 7) <> ''
THEN INT(SUBSTR(B2, 19, 7))
ELSE 0
END AS B3
FROM fichierb
)
SELECT a.*
FROM fichiera a
WHERE a.A1 IN (SELECT B3 FROM valeurs_b);Avantages
- séparation claire entre calcul métier et filtrage
- SQL plus lisible et auto-documenté
- plus simple à faire évoluer
- approche moderne, bien adaptée à IBM i
Source :
IBM Documentation – WITH clause (CTE)
https://www.ibm.com/docs/en/i/7.6.0?topic=statement-common-table-expression
5. IN ou EXISTS : quelle différence ?
Dans certains cas, on peut préférer EXISTS :
SELECT a.*
FROM fichiera a
WHERE EXISTS (
SELECT 1
FROM fichierb b
WHERE a.A1 =
CASE
WHEN SUBSTR(b.B2, 19, 7) <> ''
THEN INT(SUBSTR(b.B2, 19, 7))
ELSE 0
END
);À retenir
INexprime une logique de liste de valeursEXISTSexprime une logique de relation entre lignes- sur DB2 for IBM i, l’optimiseur choisit souvent un plan similaire, mais
EXISTSévite certains effets de bord (NULL, gros volumes)
Source :
IBM Documentation – EXISTS predicate
https://www.ibm.com/docs/en/i/7.6.0?topic=predicates-exists-predicate
Conclusion
Le choix multiple en SQL DB2 sur IBM i repose sur des constructions simples :
IN- sous-requêtes
CASE- CTE (
WITH)
Bien utilisées, elles permettent :
- de simplifier le code RPG
- de rapprocher la logique métier des données
- d’écrire un SQL plus lisible, plus moderne et plus maintenable
Un excellent levier pour aller vers un IBM i plus SQL-centric, sans renier les fondamentaux du RPG.
