fr en

Faire un SELECT INTO dynamique en SQL Embedded sans générer de code retour SQLCODE -312

Objectif :

Il faut parfois écrire nos requêtes SQL EMBEDDED (encapsulées de le code RPGLE) de façon dynamique.
C’est à dire que certaines variables de la requête seront valorisées durant l’exécution du programme et non au moment de son écriture.

C’est très pratique et fonctionne très bien.

Le problème c’est qu’une requête de type SELECT INTO ne fonctionne pas en SQL EMBEDDED dynamique. Elle lève l’erreur SQLCODE -312 dont le texte est le suivant : variable-name IS NOT DEFINED OR NOT USABLE.

Heureusement il existe une solution pour palier à cela : il faut utiliser VALUES ( ) INTO ?.

Exemples :

Requête non dynamique

SELECT OBJECT_COUNT FROM TABLE(QSYS2.LIBRARY_INFO(‘nom_bibliotheque‘));  

Retourne bien le nombre d’object contenu dans la bibliothèque nommée ‘nom_bibliotheque‘.
Mais ‘nom_bibliothèque‘ est définie « en dur » et ne variera pas lors de l’exécution.

Pour que la requête porte sur la valeur d’une variable qui sera alimentée lors de l’exécution du programme, il faut utiliser une requête SQL dynamique.

 

Requête dynamique SELECT INTO : Erreur SQL SQLCODE -312

dcl-s ma_requete    char(500)   inz;
Dcl-s mon_resultat zoned(5:0) inz;

ma_requete = SELECT OBJECT_COUNT INTO :mon_resultat 
                     + FROM TABLE(QSYS2.LIBRARY_INFO( »’
                     + ma_variable_bibliotheque +  »’))’;  

EXEC SQL
   PREPARE SQLSTM FROM :ma_requete;

if SQLCODE = 0;
   EXEC SQL
      EXECUTE SQLSTM USING :ma_requete;
endif;

 

Requête dynamique VALUES () INTO ? 

dcl-s ma_requete    char(500)   inz;
Dcl-s mon_resultat zoned(5:0) inz;

ma_requete = VALUES(
                     +
SELECT OBJECT_COUNT
                     + FROM TABLE(QSYS2.LIBRARY_INFO( »’
                     + ma_variable_bibliotheque +  »’))) INTO ?‘;  

EXEC SQL
   PREPARE SQLSTM FROM :ma_requete;

if SQLCODE = 0;
   EXEC SQL
      EXECUTE SQLSTM USING :mon_resultat;
endif;

Cette fois cela fonctionne, la requête retourne bien de nombre d’objets contenus dans la bibliothèque dont le nom est présent dans la variable ma_variable_bibliotheque.

Remarque :
Le PREPARE porte sur la requête : FROM :ma_requete;
Le EXECUTE utilise le champ résultat : USING :mon_resultat;

 

Requête dynamique VALUES () INTO ? portant sur plusieurs champs 

dcl-s ma_requete       char(500)   inz;
Dcl-s mon_resultat_1 zoned(5:0) inz;
Dcl-s mon_resultat_2 char(20)     inz;

ma_requete = VALUES(
                     +
SELECT OBJECT_COUNT, LIBRARY_TYPE
                     + FROM TABLE(QSYS2.LIBRARY_INFO( »’
                     + ma_variable_bibliotheque +  »’))) INTO ?‘;  

EXEC SQL
   PREPARE SQLSTM FROM :ma_requete;

if SQLCODE = 0;
   EXEC SQL
      EXECUTE SQLSTM USING :mon_resultat_1, :mon_resultat_2;
endif;